SlideShare ist ein Scribd-Unternehmen logo
1 von 36
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

Weitere ähnliche Inhalte

Was ist angesagt?

Decorators in Python
Decorators in PythonDecorators in Python
Decorators in PythonBen James
 
Object oriented programming with python
Object oriented programming with pythonObject oriented programming with python
Object oriented programming with pythonArslan Arshad
 
Namespace in C++ Programming Language
Namespace in C++ Programming LanguageNamespace in C++ Programming Language
Namespace in C++ Programming LanguageHimanshu Choudhary
 
Inline Functions and Default arguments
Inline Functions and Default argumentsInline Functions and Default arguments
Inline Functions and Default argumentsNikhil Pandit
 
Regular expressions in Python
Regular expressions in PythonRegular expressions in Python
Regular expressions in PythonSujith Kumar
 
Inheritance in c++ ppt (Powerpoint) | inheritance in c++ ppt presentation | i...
Inheritance in c++ ppt (Powerpoint) | inheritance in c++ ppt presentation | i...Inheritance in c++ ppt (Powerpoint) | inheritance in c++ ppt presentation | i...
Inheritance in c++ ppt (Powerpoint) | inheritance in c++ ppt presentation | i...cprogrammings
 
9. Input Output in java
9. Input Output in java9. Input Output in java
9. Input Output in javaNilesh Dalvi
 
Modules and packages in python
Modules and packages in pythonModules and packages in python
Modules and packages in pythonTMARAGATHAM
 
Python – Object Oriented Programming
Python – Object Oriented Programming Python – Object Oriented Programming
Python – Object Oriented Programming Raghunath A
 
Inheritance in c++
Inheritance in c++Inheritance in c++
Inheritance in c++Vishal Patil
 
Templates in C++
Templates in C++Templates in C++
Templates in C++Tech_MX
 
Java class,object,method introduction
Java class,object,method introductionJava class,object,method introduction
Java class,object,method introductionSohanur63
 

Was ist angesagt? (20)

Chapter 05 classes and objects
Chapter 05 classes and objectsChapter 05 classes and objects
Chapter 05 classes and objects
 
Decorators in Python
Decorators in PythonDecorators in Python
Decorators in Python
 
Object oriented programming with python
Object oriented programming with pythonObject oriented programming with python
Object oriented programming with python
 
OOP C++
OOP C++OOP C++
OOP C++
 
Namespace in C++ Programming Language
Namespace in C++ Programming LanguageNamespace in C++ Programming Language
Namespace in C++ Programming Language
 
Inline Functions and Default arguments
Inline Functions and Default argumentsInline Functions and Default arguments
Inline Functions and Default arguments
 
Python OOPs
Python OOPsPython OOPs
Python OOPs
 
Python-Encapsulation.pptx
Python-Encapsulation.pptxPython-Encapsulation.pptx
Python-Encapsulation.pptx
 
Python programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphismPython programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphism
 
Regular expressions in Python
Regular expressions in PythonRegular expressions in Python
Regular expressions in Python
 
Inheritance in c++ ppt (Powerpoint) | inheritance in c++ ppt presentation | i...
Inheritance in c++ ppt (Powerpoint) | inheritance in c++ ppt presentation | i...Inheritance in c++ ppt (Powerpoint) | inheritance in c++ ppt presentation | i...
Inheritance in c++ ppt (Powerpoint) | inheritance in c++ ppt presentation | i...
 
9. Input Output in java
9. Input Output in java9. Input Output in java
9. Input Output in java
 
Modules and packages in python
Modules and packages in pythonModules and packages in python
Modules and packages in python
 
Python - object oriented
Python - object orientedPython - object oriented
Python - object oriented
 
Python – Object Oriented Programming
Python – Object Oriented Programming Python – Object Oriented Programming
Python – Object Oriented Programming
 
Inheritance in c++
Inheritance in c++Inheritance in c++
Inheritance in c++
 
Templates in C++
Templates in C++Templates in C++
Templates in C++
 
Oop concepts in python
Oop concepts in pythonOop concepts in python
Oop concepts in python
 
Java class,object,method introduction
Java class,object,method introductionJava class,object,method introduction
Java class,object,method introduction
 
Python Modules
Python ModulesPython Modules
Python Modules
 

Andere mochten auch

Object oriented programming Fundamental Concepts
Object oriented programming Fundamental ConceptsObject oriented programming Fundamental Concepts
Object oriented programming Fundamental ConceptsBharat Kalia
 
Advanced Python Techniques: Decorators
Advanced Python Techniques: DecoratorsAdvanced Python Techniques: Decorators
Advanced Python Techniques: DecoratorsTomo Popovic
 
The (unknown) collections module
The (unknown) collections moduleThe (unknown) collections module
The (unknown) collections modulePablo Enfedaque
 
EuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystifiedEuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystifiedPablo 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_objectsWilliam 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 PythonSarah Mount
 
Multiprocessing with python
Multiprocessing with pythonMultiprocessing with python
Multiprocessing with pythonPatrick Vergain
 
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 ObjectsP3 InfoTech Solutions Pvt. Ltd.
 
類別的繼承
類別的繼承類別的繼承
類別的繼承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 evolutionRamkumar Ravichandran
 
Advance OOP concepts in Python
Advance OOP concepts in PythonAdvance OOP concepts in Python
Advance OOP concepts in PythonSujith Kumar
 
資料視覺化之理論、賞析與實作
資料視覺化之理論、賞析與實作資料視覺化之理論、賞析與實作
資料視覺化之理論、賞析與實作台灣資料科學年會
 
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
 

Andere mochten auch (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...
 

Ähnlich wie Python decorators

Advanced Python, Part 1
Advanced Python, Part 1Advanced Python, Part 1
Advanced Python, Part 1Zaar 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
 
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.pdfKoteswari Kasireddy
 
Cocoa for Web Developers
Cocoa for Web DevelopersCocoa for Web Developers
Cocoa for Web Developersgeorgebrock
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)Jacek Laskowski
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved againrik0
 
Functions_21_22.pdf
Functions_21_22.pdfFunctions_21_22.pdf
Functions_21_22.pdfpaijitk
 
Python_Object_Oriented_Programming.pptx
Python_Object_Oriented_Programming.pptxPython_Object_Oriented_Programming.pptx
Python_Object_Oriented_Programming.pptxKoteswari Kasireddy
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java DevelopersYakov Fain
 
Ruby: Beyond the Basics
Ruby: Beyond the BasicsRuby: Beyond the Basics
Ruby: Beyond the BasicsMichael Koby
 
Learning C++ - Class 4
Learning C++ - Class 4Learning C++ - Class 4
Learning C++ - Class 4Ali Aminian
 

Ähnlich wie 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
 
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
 
Module Magic
Module MagicModule Magic
Module Magic
 

Mehr von 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 introductionAlex Su
 

Mehr von 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
 

Kürzlich hochgeladen

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dashnarutouzumaki53779
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch TuesdayIvanti
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 

Kürzlich hochgeladen (20)

A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Visualising and forecasting stocks using Dash
Visualising and forecasting stocks using DashVisualising and forecasting stocks using Dash
Visualising and forecasting stocks using Dash
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
2024 April Patch Tuesday
2024 April Patch Tuesday2024 April Patch Tuesday
2024 April Patch Tuesday
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 

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

Hinweis der Redaktion

  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.