SlideShare a Scribd company logo
Python Decorators
Alex Su


             Classification 4/3/2012   Copyright 2009 Trend Micro Inc.   1
Before
• Java Jersey
@GET
@PATH(―/hello‖)
public void hello() {
    return ―Hello World‖
}



• Python Bottle
@get('/hello')
def hello():
    return "Hello World!‖




                            Copyright 2009 Trend Micro Inc.
What’s a Decorator?
Decoration is a way to specify management code for functions and classes.
Decorators themselves take the form of callable objects (e.g., functions) that
process other callable objects.


• Function decorators install wrapper objects to intercept later function calls
  and process them as needed.
• Class decorators install wrapper objects to intercept later instance creation
  calls and process them as required.




                                        Copyright 2009 Trend Micro Inc.
Why Decorators?
• Decorators have a very explicit syntax, which makes them easier to spot than
  helper function calls that may be arbitrarily far-removed from the subject
  functions or classes.
• Decorators are applied once, when the subject function or class is defined;
  it’s not necessary to add extra code (which may have to be changed in the
  future) at every call to the class or function.
• Because of both of the prior points, decorators make it less likely that a user
  of an API will forget to augment a function or class according to API
  requirements.




                                        Copyright 2009 Trend Micro Inc.
Why Decorators?
def query():                                                        @get('/query')
  # parse http request                                              @logging
  # logging                                                         @authentication
  # authenticate user                                               @authorization(―admin‖)
  # authorize user permission                                       @cache
  # if cache exists, return it.                                     def query():
  # get data from DB                                                  # get data from DB




                                  Copyright 2009 Trend Micro Inc.
Function Decorators




     Classification 4/3/2012   Copyright 2009 Trend Micro Inc.   6
Usage
In terms of code, function decorators automatically map the following syntax:
@decorator
def F(arg):
...
F(99) # Call function


into this equivalent form, where decorator is a one-argument callable object
that re- turns a callable object with the same number of arguments as F:


def F(arg):
...
F = decorator(F) # Rebind function name to decorator result
F(99) # Essentially calls decorator(F)(99)
                                        Copyright 2009 Trend Micro Inc.
Implementation
A decorator itself is a callable that returns a callable.


def decorator(F):
     print ‖init decorator"
     return F


@decorator
def func():
     print "Hello‖


This decorator is invoked at decoration time, and the callable it returns is
invoked when the original function name is later called.

                                          Copyright 2009 Trend Micro Inc.
Implementation
the decorator returns a wrapper that retains the original function in an enclosing scope


def decorator(F):
              def wrapper(*args):
                        print ‖run function"
                        F()
              return wrapper


@decorator
def func():
     print "Hello"
When the name func is later called, it really invokes the wrapper function
returned by decorator; the wrapper function can then run the original func
because it is still available in an enclosing scope.

                                               Copyright 2009 Trend Micro Inc.
Implementation
To do the same with classes, we can overload the call operation and use instance at-
tributes instead of enclosing scopes:


class decorator:
              def __init__(self, func):    # On @ decoration
                              self.func = func
                              print "init decorator‖
              def __call__(self, *args):     # On wrapped function call
                              print "run function"
                              self.func(*args)


@decorator
def func():   # func = decorator(func), then func is passed to __init__
              print "Hello‖


func()   #call __call__'s *args




                                                               Copyright 2009 Trend Micro Inc.
Class Decorators




   Classification 4/3/2012   Copyright 2009 Trend Micro Inc. 11
Usage
@decorator # Decorate
class C:
...
x = C(99) # Make an instance


is equivalent to the following—the class is automatically passed to the
decorator func- tion, and the decorator’s result is assigned back to the class
name:


class C:
...
C = decorator(C) # Rebind class name to decorator result
x = C(99) # Essentially calls decorator(C)(99)

                                        Copyright 2009 Trend Micro Inc.
Implementation
A decorator itself is a callable that returns a callable.


def decorator(C):
     print ‖init decorator"
     return C


@decorator
class C:
           def __init__(self, x, y):
                     self.attr = 'spam’




                                          Copyright 2009 Trend Micro Inc.
Implementation
the decorator returns a wrapper that retains the original function in an enclosing scope


def decorator(cls):
              class Wrapper:
                             def __init__(self, *args):
                                           self.wrapped = cls(*args)
                             def __getattr__(self, name):
                                           return getattr(self.wrapped, name)
              return Wrapper


@decorator
class C:
              def __init__(self, x, y):
                             self.attr = 'spam’



It does support multiple instances, because each instance creation call makes a new
independent wrapper object.

                                                            Copyright 2009 Trend Micro Inc.
Implementation - invalid
class Decorator:
             def __init__(self, C): # On @ decoration
                           self.C = C
             def __call__(self, *args): # On instance creation
                           self.wrapped = self.C(*args)
                           return self
             def __getattr__(self, attrname): # On atrribute fetch
                           return getattr(self.wrapped, attrname)
@decorator
class C:
  ….


x = C()
y = C() # Overwrites x!



this version fails to handle multiple instances of a given class—each instance
creation call overwrites the prior saved instance.

                                                           Copyright 2009 Trend Micro Inc.
Decorator Nesting




   Classification 4/3/2012   Copyright 2009 Trend Micro Inc. 16
Usage
Sometimes one decorator isn’t enough. To support multiple steps of augmentation,
decorator syntax allows you to add multiple layers of wrapper logic to a decorated
function or method. When this feature is used, each decorator must appear on a line of
its own. Decorator syntax of this form:


@A
@B
@C
def f(...):
   ...
runs the same as the following:


def f(...):
   ...
f = A(B(C(f)))


                                           Copyright 2009 Trend Micro Inc.
Implementation
def sidedish1(meal):
  return lambda: meal() + 30


def sidedish2(meal):
  return lambda: meal() + 40


@sidedish1
@sidedish2
def friedchicken():
  return 49.0


is equivalent to


friedchicken = sidedish1(sidedish2(friedchicken))


print(friedchicken()) # 119.0
                                                    Copyright 2009 Trend Micro Inc.
Decorator Arguments




    Classification 4/3/2012   Copyright 2009 Trend Micro Inc. 19
Usage
Both function and class decorators can also seem to take arguments, although really
these arguments are passed to a callable that in effect returns the decorator, which in
turn returns a callable. The following, for instance:


@decorator(A, B)
def F(arg):
              ...
F(99)
is automatically mapped into this equivalent form, where decorator is a callable that
returns the actual decorator. The returned decorator in turn returns the callable run later
for calls to the original function name:


def F(arg):
              ...
F = decorator(A, B)(F) # Rebind F to result of decorator's return value
F(99) # Essentially calls decorator(A, B)(F)(99)

                                                   Copyright 2009 Trend Micro Inc.
Implementation
def sidedish(number):
  return {
     1 : lambda meal: (lambda: meal() + 30),
     2 : lambda meal: (lambda: meal() + 40),
     3 : lambda meal: (lambda: meal() + 50),
     4 : lambda meal: (lambda: meal() + 60)
  }.get(number, lambda meal: (lambda: meal()))


@sidedish(2)
@sidedish(3)
def friedchicken():
  return 49.0


print(friedchicken()) # 139.0




                                                 Copyright 2009 Trend Micro Inc.
def sidedish(number):
Implementation                     def dish1(meal):
                                        return lambda: meal() + 30


@sidedish(2)                       def dish2(meal):
@sidedish(3)                            return lambda: meal() + 40
def friedchicken():
  return 49.0
                                   def dish3(meal):

print(friedchicken()) # 139.0
                                        return lambda: meal() + 50


                                   def dish4(meal):
                                        return lambda: meal() + 60


                                   def nodish(meal):
                                        return lambda: meal()


                                   return {
                                        1 : dish1,
                                        2 : dish2,
                                        3 : dish3,
                                        4 : dish4
                                   }.get(number, nodish)
                                 Copyright 2009 Trend Micro Inc.
Decorators Manage Functions and Classes
def decorate(O):
  # Save or augment function or class O
  return O


@decorator
def F(): ... # F = decorator(F)


@decorator
class C: ... # C = decorator(C)




                                          Copyright 2009 Trend Micro Inc.
Logging example
                                                                               >>> spam(1, 2, 3)
class tracer:
                                                                               call 1 to spam
  def __init__(self, func):
                                                                               6
     self.calls = 0
                                                                               >>> spam ('a', 'b', 'c')
     self.func = func
                                                                               call 2 to spam
  def __call__(self, *args):
                                                                               abc
     self.calls += 1
                                                                               >>> spam.calls
     print('call %s to %s' % (self.calls, self.func.__name__))
                                                                               2
     self.func(*args)


@tracer
def spam(a, b, c):
  print(a + b + c)



                                             Copyright 2009 Trend Micro Inc.
State Information




  Classification 4/3/2012   Copyright 2009 Trend Micro Inc. 25
Class instance attributes
                                                                                >>>spam(1, 2, 3)
class tracer:
  def __init__(self, func):
                                                                                call 1 to spam
     self.calls = 0                                                             6
     self.func = func                                                           >>>spam(a=4, b=5, c=6)
  def __call__(self, *args, **kwargs):                                          call 2 to spam
     self.calls += 1                                                            15
     print('call %s to %s' % (self.calls, self.func.__name__))
                                                                                >>>eggs(2, 16)
     return self.func(*args, **kwargs)
                                                                                call 1 to eggs

@tracer
                                                                                65536
def spam(a, b, c):                                                              >>>eggs(4, y=4)
  print(a + b + c)                                                              call 2 to eggs
                                                                                256
@tracer
def eggs(x, y):
  print(x ** y)
                                                    Copyright 2009 Trend Micro Inc.
Enclosing scopes and nonlocals
                                                                              >>>spam(1, 2, 3)
def tracer(func):
                                                                              call 1 to spam
  calls = 0
                                                                              6
  def wrapper(*args, **kwargs):
                                                                              >>>spam(a=4, b=5, c=6)
     nonlocal calls
                                                                              call 2 to spam
     calls += 1
                                                                              15
     print('call %s to %s' % (calls, func.__name__))
                                                                              >>>eggs(2, 16)
     return func(*args, **kwargs)
                                                                              call 1 to eggs
  return wrapper
                                                                              65536
                                                                              >>>eggs(4, y=4)
                                                                              call 2 to eggs
                                                                              256




                                            Copyright 2009 Trend Micro Inc.
Enclosing scopes and globals
calls = 0                                                                >>>spam(1, 2, 3)
def tracer(func):                                                        call 1 to spam
  def wrapper(*args, **kwargs):                                          6
     global calls                                                        >>>spam(a=4, b=5, c=6)
     calls += 1                                                          call 2 to spam
     print('call %s to %s' % (calls, func.__name__))                     15
     return func(*args, **kwargs)                                        >>>eggs(2, 16)
  return wrapper                                                         call 3 to eggs
                                                                         65536
                                                                         >>>eggs(4, y=4)
                                                                         call 4 to eggs
                                                                         256




                                            Copyright 2009 Trend Micro Inc.
Decorating Class Methods




      Classification 4/3/2012   Copyright 2009 Trend Micro Inc. 29
Class Blunders I - Decorating Class Methods
class tracer:
          def __init__(self, func):
                     self.calls = 0
                     self.func = func
          def __call__(self, *args, **kwargs):
                     self.calls += 1
                     print('call %s to %s' % (self.calls, self.func.__name__))
                     return self.func(*args, **kwargs)




                                             Copyright 2009 Trend Micro Inc.
Class Blunders I - Decorating Class Methods
class Person:
                def __init__(self, name, pay):
                              self.name = name
                              self.pay = pay
                @tracer
                def giveRaise(self, percent):
                              self.pay *= (1.0 + percent)
                @tracer
                def lastName(self):
                              return self.name.split()[-1]


bob = Person('Bob Smith', 50000)
bob.giveRaise(.25) ## Runs tracer.__call__(???, .25)




The root of the problem here is in the self argument of the tracer class’s __call__ method,
is it a tracer instance or a Person instance?

                                                             Copyright 2009 Trend Micro Inc.
Using nested functions to decorate methods
def tracer(func):
          calls = 0
          def onCall(*args, **kwargs):
                      nonlocal calls
                      calls += 1
                      print('call %s to %s' % (calls, func.__name__))
                      return func(*args, **kwargs)
          return onCall




                                              Copyright 2009 Trend Micro Inc.
Singleton Classes
instances = {}
def getInstance(aClass, *args):
             if aClass not in instances:
                          instances[aClass] = aClass(*args)
             return instances[aClass]


def singleton(aClass):
             def onCall(*args):
                          return getInstance(aClass, *args)
             return onCall


@singleton
class Spam:
             def __init__(self, val):
                          self.attr = val


                                                    Copyright 2009 Trend Micro Inc.
Why Decorators? (Revisited)
drawbacks:
• Type changes
   – As we’ve seen, when wrappers are inserted, a decorated function or class
     does not retain its original type—its name is rebound to a wrapper object.


• Extra calls
   – A wrapping layer added by decoration incurs the additional performance
     cost of an extra call each time the decorated object is invoked




                                      Copyright 2009 Trend Micro Inc.
Why Decorators? (Revisited)
benefits:
• Explicit syntax
   – Decorators make augmentation explicit and obvious.
• Code maintenance
   – Decorators avoid repeated augmentation code at each function or class
     call.
• Consistency
   – Decorators make it less likely that a programmer will forget to use
     required wrapping logic.




                                       Copyright 2009 Trend Micro Inc.
Q&A




      Classification 4/3/2012   Copyright 2009 Trend Micro Inc. 36

More Related Content

What's hot

Modules and packages in python
Modules and packages in pythonModules and packages in python
Modules and packages in python
TMARAGATHAM
 
Python Modules
Python ModulesPython Modules
Python Modules
Nitin Reddy Katkam
 
Iterarators and generators in python
Iterarators and generators in pythonIterarators and generators in python
Iterarators and generators in python
Sarfaraz Ghanta
 
Python programming : Classes objects
Python programming : Classes objectsPython programming : Classes objects
Python programming : Classes objects
Emertxe Information Technologies Pvt Ltd
 
Python functions
Python functionsPython functions
Python functions
Prof. Dr. K. Adisesha
 
Python OOPs
Python OOPsPython OOPs
Python OOPs
Binay Kumar Ray
 
Python programming : Abstract classes interfaces
Python programming : Abstract classes interfacesPython programming : Abstract classes interfaces
Python programming : Abstract classes interfaces
Emertxe Information Technologies Pvt Ltd
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
Maulik Borsaniya
 
Python – Object Oriented Programming
Python – Object Oriented Programming Python – Object Oriented Programming
Python – Object Oriented Programming
Raghunath A
 
What is Multithreading In Python | Python Multithreading Tutorial | Edureka
What is Multithreading In Python | Python Multithreading Tutorial | EdurekaWhat is Multithreading In Python | Python Multithreading Tutorial | Edureka
What is Multithreading In Python | Python Multithreading Tutorial | Edureka
Edureka!
 
Python lambda functions with filter, map & reduce function
Python lambda functions with filter, map & reduce functionPython lambda functions with filter, map & reduce function
Python lambda functions with filter, map & reduce function
ARVIND PANDE
 
What is Python Lambda Function? Python Tutorial | Edureka
What is Python Lambda Function? Python Tutorial | EdurekaWhat is Python Lambda Function? Python Tutorial | Edureka
What is Python Lambda Function? Python Tutorial | Edureka
Edureka!
 
Basics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonBasics of Object Oriented Programming in Python
Basics of Object Oriented Programming in Python
Sujith Kumar
 
How to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | EdurekaHow to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | Edureka
Edureka!
 
Functions in Python
Functions in PythonFunctions in Python
Functions in Python
Kamal Acharya
 
Tkinter Python Tutorial | Python GUI Programming Using Tkinter Tutorial | Pyt...
Tkinter Python Tutorial | Python GUI Programming Using Tkinter Tutorial | Pyt...Tkinter Python Tutorial | Python GUI Programming Using Tkinter Tutorial | Pyt...
Tkinter Python Tutorial | Python GUI Programming Using Tkinter Tutorial | Pyt...
Edureka!
 
Python-DataAbstarction.pptx
Python-DataAbstarction.pptxPython-DataAbstarction.pptx
Python-DataAbstarction.pptx
Karudaiyar Ganapathy
 
Python - object oriented
Python - object orientedPython - object oriented
Python - object oriented
Learnbay Datascience
 
Python Class | Python Programming | Python Tutorial | Edureka
Python Class | Python Programming | Python Tutorial | EdurekaPython Class | Python Programming | Python Tutorial | Edureka
Python Class | Python Programming | Python Tutorial | Edureka
Edureka!
 
Polymorphism in Python
Polymorphism in Python Polymorphism in Python
Polymorphism in Python
Home
 

What's hot (20)

Modules and packages in python
Modules and packages in pythonModules and packages in python
Modules and packages in python
 
Python Modules
Python ModulesPython Modules
Python Modules
 
Iterarators and generators in python
Iterarators and generators in pythonIterarators and generators in python
Iterarators and generators in python
 
Python programming : Classes objects
Python programming : Classes objectsPython programming : Classes objects
Python programming : Classes objects
 
Python functions
Python functionsPython functions
Python functions
 
Python OOPs
Python OOPsPython OOPs
Python OOPs
 
Python programming : Abstract classes interfaces
Python programming : Abstract classes interfacesPython programming : Abstract classes interfaces
Python programming : Abstract classes interfaces
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
 
Python – Object Oriented Programming
Python – Object Oriented Programming Python – Object Oriented Programming
Python – Object Oriented Programming
 
What is Multithreading In Python | Python Multithreading Tutorial | Edureka
What is Multithreading In Python | Python Multithreading Tutorial | EdurekaWhat is Multithreading In Python | Python Multithreading Tutorial | Edureka
What is Multithreading In Python | Python Multithreading Tutorial | Edureka
 
Python lambda functions with filter, map & reduce function
Python lambda functions with filter, map & reduce functionPython lambda functions with filter, map & reduce function
Python lambda functions with filter, map & reduce function
 
What is Python Lambda Function? Python Tutorial | Edureka
What is Python Lambda Function? Python Tutorial | EdurekaWhat is Python Lambda Function? Python Tutorial | Edureka
What is Python Lambda Function? Python Tutorial | Edureka
 
Basics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonBasics of Object Oriented Programming in Python
Basics of Object Oriented Programming in Python
 
How to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | EdurekaHow to use Map() Filter() and Reduce() functions in Python | Edureka
How to use Map() Filter() and Reduce() functions in Python | Edureka
 
Functions in Python
Functions in PythonFunctions in Python
Functions in Python
 
Tkinter Python Tutorial | Python GUI Programming Using Tkinter Tutorial | Pyt...
Tkinter Python Tutorial | Python GUI Programming Using Tkinter Tutorial | Pyt...Tkinter Python Tutorial | Python GUI Programming Using Tkinter Tutorial | Pyt...
Tkinter Python Tutorial | Python GUI Programming Using Tkinter Tutorial | Pyt...
 
Python-DataAbstarction.pptx
Python-DataAbstarction.pptxPython-DataAbstarction.pptx
Python-DataAbstarction.pptx
 
Python - object oriented
Python - object orientedPython - object oriented
Python - object oriented
 
Python Class | Python Programming | Python Tutorial | Edureka
Python Class | Python Programming | Python Tutorial | EdurekaPython Class | Python Programming | Python Tutorial | Edureka
Python Class | Python Programming | Python Tutorial | Edureka
 
Polymorphism in Python
Polymorphism in Python Polymorphism in Python
Polymorphism in Python
 

Viewers also liked

Object oriented programming Fundamental Concepts
Object oriented programming Fundamental ConceptsObject oriented programming Fundamental Concepts
Object oriented programming Fundamental Concepts
Bharat Kalia
 
Advanced Python Techniques: Decorators
Advanced Python Techniques: DecoratorsAdvanced Python Techniques: Decorators
Advanced Python Techniques: Decorators
Tomo Popovic
 
The (unknown) collections module
The (unknown) collections moduleThe (unknown) collections module
The (unknown) collections module
Pablo Enfedaque
 
EuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystifiedEuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystified
Pablo Enfedaque
 
An Introduction to Object-Oriented Programming (DrupalCamp North 2015)
An Introduction to Object-Oriented Programming (DrupalCamp North 2015)An Introduction to Object-Oriented Programming (DrupalCamp North 2015)
An Introduction to Object-Oriented Programming (DrupalCamp North 2015)
Bart Feenstra
 
Creative Language and Creative Process Across Disciplines: Music, Programming...
Creative Language and Creative Process Across Disciplines: Music, Programming...Creative Language and Creative Process Across Disciplines: Music, Programming...
Creative Language and Creative Process Across Disciplines: Music, Programming...
jwettersten
 
Oop concepts classes_objects
Oop concepts classes_objectsOop concepts classes_objects
Oop concepts classes_objects
William Olivier
 
Meta-Classes in Python
Meta-Classes in PythonMeta-Classes in Python
Meta-Classes in PythonGuy Wiener
 
Message-passing concurrency in Python
Message-passing concurrency in PythonMessage-passing concurrency in Python
Message-passing concurrency in Python
Sarah Mount
 
Multiprocessing with python
Multiprocessing with pythonMultiprocessing with python
Multiprocessing with python
Patrick Vergain
 
Interfacing C/C++ and Python with SWIG
Interfacing C/C++ and Python with SWIGInterfacing C/C++ and Python with SWIG
Interfacing C/C++ and Python with SWIG
David Beazley (Dabeaz LLC)
 
Python Programming Essentials - M20 - Classes and Objects
Python Programming Essentials - M20 - Classes and ObjectsPython Programming Essentials - M20 - Classes and Objects
Python Programming Essentials - M20 - Classes and Objects
P3 InfoTech Solutions Pvt. Ltd.
 
Python in Action (Part 1)
Python in Action (Part 1)Python in Action (Part 1)
Python in Action (Part 1)
David Beazley (Dabeaz LLC)
 
類別的繼承
類別的繼承類別的繼承
類別的繼承
Justin Lin
 
Prepping the Analytics organization for Artificial Intelligence evolution
Prepping the Analytics organization for Artificial Intelligence evolutionPrepping the Analytics organization for Artificial Intelligence evolution
Prepping the Analytics organization for Artificial Intelligence evolution
Ramkumar Ravichandran
 
Advance OOP concepts in Python
Advance OOP concepts in PythonAdvance OOP concepts in Python
Advance OOP concepts in Python
Sujith Kumar
 
Mastering Python 3 I/O (Version 2)
Mastering Python 3 I/O (Version 2)Mastering Python 3 I/O (Version 2)
Mastering Python 3 I/O (Version 2)
David Beazley (Dabeaz LLC)
 
Generators: The Final Frontier
Generators: The Final FrontierGenerators: The Final Frontier
Generators: The Final Frontier
David Beazley (Dabeaz LLC)
 
資料視覺化之理論、賞析與實作
資料視覺化之理論、賞析與實作資料視覺化之理論、賞析與實作
資料視覺化之理論、賞析與實作
台灣資料科學年會
 
Open source u Crnoj Gori - izazovi i mogućnosti (Infofest 2016, Budva, Monten...
Open source u Crnoj Gori - izazovi i mogućnosti (Infofest 2016, Budva, Monten...Open source u Crnoj Gori - izazovi i mogućnosti (Infofest 2016, Budva, Monten...
Open source u Crnoj Gori - izazovi i mogućnosti (Infofest 2016, Budva, Monten...
Tomo Popovic
 

Viewers also liked (20)

Object oriented programming Fundamental Concepts
Object oriented programming Fundamental ConceptsObject oriented programming Fundamental Concepts
Object oriented programming Fundamental Concepts
 
Advanced Python Techniques: Decorators
Advanced Python Techniques: DecoratorsAdvanced Python Techniques: Decorators
Advanced Python Techniques: Decorators
 
The (unknown) collections module
The (unknown) collections moduleThe (unknown) collections module
The (unknown) collections module
 
EuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystifiedEuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystified
 
An Introduction to Object-Oriented Programming (DrupalCamp North 2015)
An Introduction to Object-Oriented Programming (DrupalCamp North 2015)An Introduction to Object-Oriented Programming (DrupalCamp North 2015)
An Introduction to Object-Oriented Programming (DrupalCamp North 2015)
 
Creative Language and Creative Process Across Disciplines: Music, Programming...
Creative Language and Creative Process Across Disciplines: Music, Programming...Creative Language and Creative Process Across Disciplines: Music, Programming...
Creative Language and Creative Process Across Disciplines: Music, Programming...
 
Oop concepts classes_objects
Oop concepts classes_objectsOop concepts classes_objects
Oop concepts classes_objects
 
Meta-Classes in Python
Meta-Classes in PythonMeta-Classes in Python
Meta-Classes in Python
 
Message-passing concurrency in Python
Message-passing concurrency in PythonMessage-passing concurrency in Python
Message-passing concurrency in Python
 
Multiprocessing with python
Multiprocessing with pythonMultiprocessing with python
Multiprocessing with python
 
Interfacing C/C++ and Python with SWIG
Interfacing C/C++ and Python with SWIGInterfacing C/C++ and Python with SWIG
Interfacing C/C++ and Python with SWIG
 
Python Programming Essentials - M20 - Classes and Objects
Python Programming Essentials - M20 - Classes and ObjectsPython Programming Essentials - M20 - Classes and Objects
Python Programming Essentials - M20 - Classes and Objects
 
Python in Action (Part 1)
Python in Action (Part 1)Python in Action (Part 1)
Python in Action (Part 1)
 
類別的繼承
類別的繼承類別的繼承
類別的繼承
 
Prepping the Analytics organization for Artificial Intelligence evolution
Prepping the Analytics organization for Artificial Intelligence evolutionPrepping the Analytics organization for Artificial Intelligence evolution
Prepping the Analytics organization for Artificial Intelligence evolution
 
Advance OOP concepts in Python
Advance OOP concepts in PythonAdvance OOP concepts in Python
Advance OOP concepts in Python
 
Mastering Python 3 I/O (Version 2)
Mastering Python 3 I/O (Version 2)Mastering Python 3 I/O (Version 2)
Mastering Python 3 I/O (Version 2)
 
Generators: The Final Frontier
Generators: The Final FrontierGenerators: The Final Frontier
Generators: The Final Frontier
 
資料視覺化之理論、賞析與實作
資料視覺化之理論、賞析與實作資料視覺化之理論、賞析與實作
資料視覺化之理論、賞析與實作
 
Open source u Crnoj Gori - izazovi i mogućnosti (Infofest 2016, Budva, Monten...
Open source u Crnoj Gori - izazovi i mogućnosti (Infofest 2016, Budva, Monten...Open source u Crnoj Gori - izazovi i mogućnosti (Infofest 2016, Budva, Monten...
Open source u Crnoj Gori - izazovi i mogućnosti (Infofest 2016, Budva, Monten...
 

Similar to Python decorators

Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1
Zaar Hai
 
The Power of Decorators in Python [Meetup]
The Power of Decorators in Python [Meetup]The Power of Decorators in Python [Meetup]
The Power of Decorators in Python [Meetup]
Haim Michael
 
Python_Unit_2 OOPS.pptx
Python_Unit_2  OOPS.pptxPython_Unit_2  OOPS.pptx
Python_Unit_2 OOPS.pptx
ChhaviCoachingCenter
 
Object Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonObject Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonTendayi Mawushe
 
Python decorators (中文)
Python decorators (中文)Python decorators (中文)
Python decorators (中文)
Yiwei Chen
 
Object_Oriented_Programming_Unit3.pdf
Object_Oriented_Programming_Unit3.pdfObject_Oriented_Programming_Unit3.pdf
Object_Oriented_Programming_Unit3.pdf
Koteswari Kasireddy
 
Decorators.pptx
Decorators.pptxDecorators.pptx
Decorators.pptx
KeerthanaM738437
 
Python_Functions_Unit1.pptx
Python_Functions_Unit1.pptxPython_Functions_Unit1.pptx
Python_Functions_Unit1.pptx
Koteswari Kasireddy
 
Python programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphismPython programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphism
Emertxe Information Technologies Pvt Ltd
 
Cocoa for Web Developers
Cocoa for Web DevelopersCocoa for Web Developers
Cocoa for Web Developers
georgebrock
 
Chapter 02 functions -class xii
Chapter 02   functions -class xiiChapter 02   functions -class xii
Chapter 02 functions -class xii
Praveen M Jigajinni
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
Jacek Laskowski
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved again
rik0
 
Functions_21_22.pdf
Functions_21_22.pdfFunctions_21_22.pdf
Functions_21_22.pdf
paijitk
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
Solution4Future
 
Python_Object_Oriented_Programming.pptx
Python_Object_Oriented_Programming.pptxPython_Object_Oriented_Programming.pptx
Python_Object_Oriented_Programming.pptx
Koteswari Kasireddy
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
Yakov Fain
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
Michael Koby
 
2 Functions2.pptx
2 Functions2.pptx2 Functions2.pptx
2 Functions2.pptx
RohitYadav830391
 
Learning C++ - Class 4
Learning C++ - Class 4Learning C++ - Class 4
Learning C++ - Class 4
Ali Aminian
 

Similar to Python decorators (20)

Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1
 
The Power of Decorators in Python [Meetup]
The Power of Decorators in Python [Meetup]The Power of Decorators in Python [Meetup]
The Power of Decorators in Python [Meetup]
 
Python_Unit_2 OOPS.pptx
Python_Unit_2  OOPS.pptxPython_Unit_2  OOPS.pptx
Python_Unit_2 OOPS.pptx
 
Object Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in PythonObject Orientation vs Functional Programming in Python
Object Orientation vs Functional Programming in Python
 
Python decorators (中文)
Python decorators (中文)Python decorators (中文)
Python decorators (中文)
 
Object_Oriented_Programming_Unit3.pdf
Object_Oriented_Programming_Unit3.pdfObject_Oriented_Programming_Unit3.pdf
Object_Oriented_Programming_Unit3.pdf
 
Decorators.pptx
Decorators.pptxDecorators.pptx
Decorators.pptx
 
Python_Functions_Unit1.pptx
Python_Functions_Unit1.pptxPython_Functions_Unit1.pptx
Python_Functions_Unit1.pptx
 
Python programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphismPython programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphism
 
Cocoa for Web Developers
Cocoa for Web DevelopersCocoa for Web Developers
Cocoa for Web Developers
 
Chapter 02 functions -class xii
Chapter 02   functions -class xiiChapter 02   functions -class xii
Chapter 02 functions -class xii
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved again
 
Functions_21_22.pdf
Functions_21_22.pdfFunctions_21_22.pdf
Functions_21_22.pdf
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
Python_Object_Oriented_Programming.pptx
Python_Object_Oriented_Programming.pptxPython_Object_Oriented_Programming.pptx
Python_Object_Oriented_Programming.pptx
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the Basics
 
2 Functions2.pptx
2 Functions2.pptx2 Functions2.pptx
2 Functions2.pptx
 
Learning C++ - Class 4
Learning C++ - Class 4Learning C++ - Class 4
Learning C++ - Class 4
 

More from Alex Su

Node js introduction
Node js introductionNode js introduction
Node js introductionAlex Su
 
One click deployment
One click deploymentOne click deployment
One click deploymentAlex Su
 
Scrum Introduction
Scrum IntroductionScrum Introduction
Scrum IntroductionAlex Su
 
Redis Introduction
Redis IntroductionRedis Introduction
Redis IntroductionAlex Su
 
Using puppet
Using puppetUsing puppet
Using puppetAlex Su
 
JMS Introduction
JMS IntroductionJMS Introduction
JMS IntroductionAlex Su
 
Spring Framework Introduction
Spring Framework IntroductionSpring Framework Introduction
Spring Framework IntroductionAlex Su
 
Java Unit Test and Coverage Introduction
Java Unit Test and Coverage IntroductionJava Unit Test and Coverage Introduction
Java Unit Test and Coverage IntroductionAlex Su
 
Cascading introduction
Cascading introductionCascading introduction
Cascading introduction
Alex Su
 

More from Alex Su (9)

Node js introduction
Node js introductionNode js introduction
Node js introduction
 
One click deployment
One click deploymentOne click deployment
One click deployment
 
Scrum Introduction
Scrum IntroductionScrum Introduction
Scrum Introduction
 
Redis Introduction
Redis IntroductionRedis Introduction
Redis Introduction
 
Using puppet
Using puppetUsing puppet
Using puppet
 
JMS Introduction
JMS IntroductionJMS Introduction
JMS Introduction
 
Spring Framework Introduction
Spring Framework IntroductionSpring Framework Introduction
Spring Framework Introduction
 
Java Unit Test and Coverage Introduction
Java Unit Test and Coverage IntroductionJava Unit Test and Coverage Introduction
Java Unit Test and Coverage Introduction
 
Cascading introduction
Cascading introductionCascading introduction
Cascading introduction
 

Recently uploaded

State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Product School
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 

Recently uploaded (20)

State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 

Python decorators

  • 1. Python Decorators Alex Su Classification 4/3/2012 Copyright 2009 Trend Micro Inc. 1
  • 2. Before • Java Jersey @GET @PATH(―/hello‖) public void hello() { return ―Hello World‖ } • Python Bottle @get('/hello') def hello(): return "Hello World!‖ Copyright 2009 Trend Micro Inc.
  • 3. What’s a Decorator? Decoration is a way to specify management code for functions and classes. Decorators themselves take the form of callable objects (e.g., functions) that process other callable objects. • Function decorators install wrapper objects to intercept later function calls and process them as needed. • Class decorators install wrapper objects to intercept later instance creation calls and process them as required. Copyright 2009 Trend Micro Inc.
  • 4. Why Decorators? • Decorators have a very explicit syntax, which makes them easier to spot than helper function calls that may be arbitrarily far-removed from the subject functions or classes. • Decorators are applied once, when the subject function or class is defined; it’s not necessary to add extra code (which may have to be changed in the future) at every call to the class or function. • Because of both of the prior points, decorators make it less likely that a user of an API will forget to augment a function or class according to API requirements. Copyright 2009 Trend Micro Inc.
  • 5. Why Decorators? def query(): @get('/query') # parse http request @logging # logging @authentication # authenticate user @authorization(―admin‖) # authorize user permission @cache # if cache exists, return it. def query(): # get data from DB # get data from DB Copyright 2009 Trend Micro Inc.
  • 6. Function Decorators Classification 4/3/2012 Copyright 2009 Trend Micro Inc. 6
  • 7. Usage In terms of code, function decorators automatically map the following syntax: @decorator def F(arg): ... F(99) # Call function into this equivalent form, where decorator is a one-argument callable object that re- turns a callable object with the same number of arguments as F: def F(arg): ... F = decorator(F) # Rebind function name to decorator result F(99) # Essentially calls decorator(F)(99) Copyright 2009 Trend Micro Inc.
  • 8. Implementation A decorator itself is a callable that returns a callable. def decorator(F): print ‖init decorator" return F @decorator def func(): print "Hello‖ This decorator is invoked at decoration time, and the callable it returns is invoked when the original function name is later called. Copyright 2009 Trend Micro Inc.
  • 9. Implementation the decorator returns a wrapper that retains the original function in an enclosing scope def decorator(F): def wrapper(*args): print ‖run function" F() return wrapper @decorator def func(): print "Hello" When the name func is later called, it really invokes the wrapper function returned by decorator; the wrapper function can then run the original func because it is still available in an enclosing scope. Copyright 2009 Trend Micro Inc.
  • 10. Implementation To do the same with classes, we can overload the call operation and use instance at- tributes instead of enclosing scopes: class decorator: def __init__(self, func): # On @ decoration self.func = func print "init decorator‖ def __call__(self, *args): # On wrapped function call print "run function" self.func(*args) @decorator def func(): # func = decorator(func), then func is passed to __init__ print "Hello‖ func() #call __call__'s *args Copyright 2009 Trend Micro Inc.
  • 11. Class Decorators Classification 4/3/2012 Copyright 2009 Trend Micro Inc. 11
  • 12. Usage @decorator # Decorate class C: ... x = C(99) # Make an instance is equivalent to the following—the class is automatically passed to the decorator func- tion, and the decorator’s result is assigned back to the class name: class C: ... C = decorator(C) # Rebind class name to decorator result x = C(99) # Essentially calls decorator(C)(99) Copyright 2009 Trend Micro Inc.
  • 13. Implementation A decorator itself is a callable that returns a callable. def decorator(C): print ‖init decorator" return C @decorator class C: def __init__(self, x, y): self.attr = 'spam’ Copyright 2009 Trend Micro Inc.
  • 14. Implementation the decorator returns a wrapper that retains the original function in an enclosing scope def decorator(cls): class Wrapper: def __init__(self, *args): self.wrapped = cls(*args) def __getattr__(self, name): return getattr(self.wrapped, name) return Wrapper @decorator class C: def __init__(self, x, y): self.attr = 'spam’ It does support multiple instances, because each instance creation call makes a new independent wrapper object. Copyright 2009 Trend Micro Inc.
  • 15. Implementation - invalid class Decorator: def __init__(self, C): # On @ decoration self.C = C def __call__(self, *args): # On instance creation self.wrapped = self.C(*args) return self def __getattr__(self, attrname): # On atrribute fetch return getattr(self.wrapped, attrname) @decorator class C: …. x = C() y = C() # Overwrites x! this version fails to handle multiple instances of a given class—each instance creation call overwrites the prior saved instance. Copyright 2009 Trend Micro Inc.
  • 16. Decorator Nesting Classification 4/3/2012 Copyright 2009 Trend Micro Inc. 16
  • 17. Usage Sometimes one decorator isn’t enough. To support multiple steps of augmentation, decorator syntax allows you to add multiple layers of wrapper logic to a decorated function or method. When this feature is used, each decorator must appear on a line of its own. Decorator syntax of this form: @A @B @C def f(...): ... runs the same as the following: def f(...): ... f = A(B(C(f))) Copyright 2009 Trend Micro Inc.
  • 18. Implementation def sidedish1(meal): return lambda: meal() + 30 def sidedish2(meal): return lambda: meal() + 40 @sidedish1 @sidedish2 def friedchicken(): return 49.0 is equivalent to friedchicken = sidedish1(sidedish2(friedchicken)) print(friedchicken()) # 119.0 Copyright 2009 Trend Micro Inc.
  • 19. Decorator Arguments Classification 4/3/2012 Copyright 2009 Trend Micro Inc. 19
  • 20. Usage Both function and class decorators can also seem to take arguments, although really these arguments are passed to a callable that in effect returns the decorator, which in turn returns a callable. The following, for instance: @decorator(A, B) def F(arg): ... F(99) is automatically mapped into this equivalent form, where decorator is a callable that returns the actual decorator. The returned decorator in turn returns the callable run later for calls to the original function name: def F(arg): ... F = decorator(A, B)(F) # Rebind F to result of decorator's return value F(99) # Essentially calls decorator(A, B)(F)(99) Copyright 2009 Trend Micro Inc.
  • 21. Implementation def sidedish(number): return { 1 : lambda meal: (lambda: meal() + 30), 2 : lambda meal: (lambda: meal() + 40), 3 : lambda meal: (lambda: meal() + 50), 4 : lambda meal: (lambda: meal() + 60) }.get(number, lambda meal: (lambda: meal())) @sidedish(2) @sidedish(3) def friedchicken(): return 49.0 print(friedchicken()) # 139.0 Copyright 2009 Trend Micro Inc.
  • 22. def sidedish(number): Implementation def dish1(meal): return lambda: meal() + 30 @sidedish(2) def dish2(meal): @sidedish(3) return lambda: meal() + 40 def friedchicken(): return 49.0 def dish3(meal): print(friedchicken()) # 139.0 return lambda: meal() + 50 def dish4(meal): return lambda: meal() + 60 def nodish(meal): return lambda: meal() return { 1 : dish1, 2 : dish2, 3 : dish3, 4 : dish4 }.get(number, nodish) Copyright 2009 Trend Micro Inc.
  • 23. Decorators Manage Functions and Classes def decorate(O): # Save or augment function or class O return O @decorator def F(): ... # F = decorator(F) @decorator class C: ... # C = decorator(C) Copyright 2009 Trend Micro Inc.
  • 24. Logging example >>> spam(1, 2, 3) class tracer: call 1 to spam def __init__(self, func): 6 self.calls = 0 >>> spam ('a', 'b', 'c') self.func = func call 2 to spam def __call__(self, *args): abc self.calls += 1 >>> spam.calls print('call %s to %s' % (self.calls, self.func.__name__)) 2 self.func(*args) @tracer def spam(a, b, c): print(a + b + c) Copyright 2009 Trend Micro Inc.
  • 25. State Information Classification 4/3/2012 Copyright 2009 Trend Micro Inc. 25
  • 26. Class instance attributes >>>spam(1, 2, 3) class tracer: def __init__(self, func): call 1 to spam self.calls = 0 6 self.func = func >>>spam(a=4, b=5, c=6) def __call__(self, *args, **kwargs): call 2 to spam self.calls += 1 15 print('call %s to %s' % (self.calls, self.func.__name__)) >>>eggs(2, 16) return self.func(*args, **kwargs) call 1 to eggs @tracer 65536 def spam(a, b, c): >>>eggs(4, y=4) print(a + b + c) call 2 to eggs 256 @tracer def eggs(x, y): print(x ** y) Copyright 2009 Trend Micro Inc.
  • 27. Enclosing scopes and nonlocals >>>spam(1, 2, 3) def tracer(func): call 1 to spam calls = 0 6 def wrapper(*args, **kwargs): >>>spam(a=4, b=5, c=6) nonlocal calls call 2 to spam calls += 1 15 print('call %s to %s' % (calls, func.__name__)) >>>eggs(2, 16) return func(*args, **kwargs) call 1 to eggs return wrapper 65536 >>>eggs(4, y=4) call 2 to eggs 256 Copyright 2009 Trend Micro Inc.
  • 28. Enclosing scopes and globals calls = 0 >>>spam(1, 2, 3) def tracer(func): call 1 to spam def wrapper(*args, **kwargs): 6 global calls >>>spam(a=4, b=5, c=6) calls += 1 call 2 to spam print('call %s to %s' % (calls, func.__name__)) 15 return func(*args, **kwargs) >>>eggs(2, 16) return wrapper call 3 to eggs 65536 >>>eggs(4, y=4) call 4 to eggs 256 Copyright 2009 Trend Micro Inc.
  • 29. Decorating Class Methods Classification 4/3/2012 Copyright 2009 Trend Micro Inc. 29
  • 30. Class Blunders I - Decorating Class Methods class tracer: def __init__(self, func): self.calls = 0 self.func = func def __call__(self, *args, **kwargs): self.calls += 1 print('call %s to %s' % (self.calls, self.func.__name__)) return self.func(*args, **kwargs) Copyright 2009 Trend Micro Inc.
  • 31. Class Blunders I - Decorating Class Methods class Person: def __init__(self, name, pay): self.name = name self.pay = pay @tracer def giveRaise(self, percent): self.pay *= (1.0 + percent) @tracer def lastName(self): return self.name.split()[-1] bob = Person('Bob Smith', 50000) bob.giveRaise(.25) ## Runs tracer.__call__(???, .25) The root of the problem here is in the self argument of the tracer class’s __call__ method, is it a tracer instance or a Person instance? Copyright 2009 Trend Micro Inc.
  • 32. Using nested functions to decorate methods def tracer(func): calls = 0 def onCall(*args, **kwargs): nonlocal calls calls += 1 print('call %s to %s' % (calls, func.__name__)) return func(*args, **kwargs) return onCall Copyright 2009 Trend Micro Inc.
  • 33. Singleton Classes instances = {} def getInstance(aClass, *args): if aClass not in instances: instances[aClass] = aClass(*args) return instances[aClass] def singleton(aClass): def onCall(*args): return getInstance(aClass, *args) return onCall @singleton class Spam: def __init__(self, val): self.attr = val Copyright 2009 Trend Micro Inc.
  • 34. Why Decorators? (Revisited) drawbacks: • Type changes – As we’ve seen, when wrappers are inserted, a decorated function or class does not retain its original type—its name is rebound to a wrapper object. • Extra calls – A wrapping layer added by decoration incurs the additional performance cost of an extra call each time the decorated object is invoked Copyright 2009 Trend Micro Inc.
  • 35. Why Decorators? (Revisited) benefits: • Explicit syntax – Decorators make augmentation explicit and obvious. • Code maintenance – Decorators avoid repeated augmentation code at each function or class call. • Consistency – Decorators make it less likely that a programmer will forget to use required wrapping logic. Copyright 2009 Trend Micro Inc.
  • 36. Q&A Classification 4/3/2012 Copyright 2009 Trend Micro Inc. 36

Editor's Notes

  1. Like onion
  2. Like onion
  3. For example, @Transactional annotation in java
  4. AOPUse decorator to validate argumentsLoggingCaching
  5. Python 3.0
  6. The root of the problem here is in the self argument of the tracer class’s __call__ method—is it a tracer instance or a Person instance? We really need both as it’s coded: the tracer for decorator state, and the Person for routing on to the original method. Really, self must be the tracer object, to provide access to tracer’s state information; this is true whether decorating a simple function or a method. Unfortunately, when our decorated method name is rebound to a class instance object with a __call__, Python passes only the tracer instance to self; it doesn’t pass along the Person subject in the arguments list at all. Moreover, because the tracer knows nothing about the Person instance we are trying to process with method calls, there’s no way to create a bound method with an instance, and thus no way to correctly dis- patch the call.
  7. If you want your function decorators to work on both simple functions and class methods, the most straightforward solution lies in using one of the other state retention solutions described earlier—code your function decorator as nested defs, so that you don’t depend on a single self instance argument to be both the wrapper class instance and the subject class instance. It can store both state by nonlocal attribute and pass arguments
  8. Explicit syntax Decorators make augmentation explicit and obvious. Their @ syntax is easier to recognize than special code in calls that may appear anywhere in a source file—in our singleton and tracer examples, for instance, the decorator lines seem more likely to be noticed than extra code at calls would be. Moreover, decorators allow function and instance creation calls to use normal syntax familiar to all Python programmers. Code maintenance Decorators avoid repeated augmentation code at each function or class call. Be- cause they appear just once, at the definition of the class or function itself, they obviate redundancy and simplify future code maintenance. For our singleton and tracer cases, we need to use special code at each call to use a manager function approach—extra work is required both initially and for any modifications that must be made in the future. Consistency Decorators make it less likely that a programmer will forget to use required wrap- ping logic. This derives mostly from the two prior advantages—because decoration is explicit and appears only once, at the decorated objects themselves, decorators promote more consistent and uniform API usage than special code that must be included at each call. In the singleton example, for instance, it would be easy to forget to route all class creation calls through special code, which would subvert the singleton management altogether.