SlideShare ist ein Scribd-Unternehmen logo
1 von 44
Decorators Explained 
A Powerful Tool That Should Be in Your Python Toolbelt
Samuel Fortier-Galarneau 
Software Developer @ Digium, Inc 
@samuelg 
http://github.com/samuelg
Agenda 
• Primer 
• What is a decorator? 
• How do they work? 
• Examples
Primer 
Functions 
• Functions in Python are first class members 
• They can be passed to other functions and return 
new functions 
def add(first, second): 
return first + second 
def partial(func, first): 
def wrapper(second): 
return func(first, second) 
return wrapper
Primer 
Functions 
>>> func = partial(add, 1) 
>>> func(2) 
3
Primer 
Variable function arguments 
• Functions can have variable positional and 
keyword arguments via *args and **kwargs 
• *args and **kwargs can be packed again and 
passed along to another function 
def func(*args, **kwargs): 
print args 
print kwargs
Primer 
Variable function arguments 
>>> func(1, 2, my_arg=‘value') 
(1, 2) 
{'my_arg': 'value'}
Primer 
Variable function arguments 
def func(*args, **kwargs): 
other_func(*args, **kwargs) 
def other_func(arg1, arg2, arg3): 
print arg1 
print arg2 
print arg3
Primer 
Variable function arguments 
>>> func(1, 2, arg3=3) 
1 
2 
3
What is a decorator? 
• Injects code before/after a function call or object 
creation 
• A callable wrapper around a callable resource 
(object that implements __call__ is callable) 
• Similar to macros in C/C++ but uses built in 
Python syntax and language semantics
What is a decorator? 
• Can be implemented as a function or a class 
• Can be applied to a function or a class 
• Functions have an implicit __call__ method which 
makes them callable 
• Classes must implement a __call__ method to 
qualify as a decorator
How do they work? 
Decorator function 
def decorator(func): 
def wrapper(): 
print 'in wrapper()' 
return func() 
return wrapper 
@decorator 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function 
>>> my_function() 
in wrapper() 
in my_function()
How do they work? 
Decorator function 
def decorator(func): 
def wrapper(): 
print 'in wrapper()' 
return func() 
return wrapper 
@decorator 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function 
def decorator(func): 
def wrapper(): 
print 'in wrapper()' 
return func() 
return wrapper 
@decorator 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function 
def decorator(func): 
def wrapper(): 
print 'in wrapper()' 
return func() 
return wrapper 
@decorator 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function 
def decorator(func): 
def wrapper(): 
print 'in wrapper()' 
return func() 
return wrapper 
@decorator 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function 
wrapper is a closure over func 
def decorator(func): 
def wrapper(): 
print 'in wrapper()' 
return func() 
return wrapper 
@decorator 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function 
def decorator(func): 
def wrapper(): 
print 'in wrapper()' 
return func() 
return wrapper 
@decorator 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator class 
class Decorator(object): 
def __init__(self, func): 
self.func = func 
def __call__(self): 
print 'in __call__()' 
return self.func() 
@Decorator 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator class 
>>> my_function() 
in __call__() 
in my_function()
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function with arguments 
>>> my_function() 
in wrapper() 
(1,) 
{'config': 'value'} 
in my_function()
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator function with arguments 
def decorator(*args, **kwargs): 
def receiver(func): 
def wrapper(): 
print 'in wrapper()' 
print args 
print kwargs 
return func() 
return wrapper 
return receiver 
@decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator class with arguments 
class Decorator(object): 
def __init__(self, *args, **kwargs): 
self.args = args 
self.kwargs = kwargs 
def __call__(self, func): 
def wrapper(): 
print 'in __call__()' 
print self.args 
print self.kwargs 
return func() 
return wrapper 
@Decorator(1, config='value') 
def my_function(): 
print 'in my_function()'
How do they work? 
Decorator class with arguments 
>>> my_function() 
in __call__() 
(1,) 
{'config': 'value'} 
in my_function()
Example: counting function 
calls 
class Counter(object): 
def __init__(self, func): 
self.count = 0 
self.func = func 
def __call__(self): 
self.count += 1 
return self.func() 
def getCount(self): 
return self.count 
@Counter 
def function(): 
pass
Example: counting function 
calls 
>>> function() 
>>> function() 
>>> function() 
>>> function.getCount() 
3
Example: memoize 
class Memoize(object): 
def __init__(self, func): 
self.cache = {} 
self.func = func 
def __call__(self, *args, **kwargs): 
cache_key = '%s%s' % (args, kwargs) 
if cache_key in self.cache: 
return self.cache[cache_key] 
else: 
result = self.func(*args, **kwargs) 
self.cache[cache_key] = result 
return result 
@Memoize 
def function(bound): 
sum = 0 
for x in range(bound): 
sum += x 
return sum
Example: memoize 
>>> function(100000000) 
~ 11 seconds 
>>> function(100000000) 
~ 10 milliseconds
Example: type checker 
def type_check(*types): 
def receiver(func): 
def wrapper(*args, **kwargs): 
for index, type_arg in enumerate(types): 
if type(args[index]) != type_arg: 
raise TypeError('Expected %s at index %s' % 
(type_arg, index)) 
return func(*args, **kwargs) 
return wrapper 
return receiver 
@type_check(int, int, str) 
def function(first, second, third): 
print 'success'
Example: type checker 
>>> function(1, 2, ‘works') 
success 
>>> function('will', 'not', ‘work') 
Traceback (most recent call last): 
File "type.py", line 17, in <module> 
function('will', 'not', 'work') 
File "type.py", line 7, in wrapper 
raise TypeError('Expected %s at index %s' % 
(type_arg, index)) 
TypeError: Expected <type 'int'> at index 0
Example: singleton 
instances = {} 
def singleton(cls): 
def create(*args): 
if cls not in instances: 
instances[cls] = cls(*args) 
return instances[cls] 
return create 
@singleton 
class Toolbelt(object): 
def __init__(self): 
pass
Example: singleton 
>>> toolbelt = Toolbelt() 
>>> another = Toolbelt() 
>>> another == toolbelt 
True
Other uses 
• Retries 
• Pre/Post conditions 
• Function input/output transforms 
• Performance logging 
• Authorization
Thanks! 
Samuel Fortier-Galarneau 
@samuelg 
http://github.com/samuelg 
http://www.slideshare.net/sgalarne/decorators-2

Weitere ähnliche Inhalte

Was ist angesagt?

08 c++ Operator Overloading.ppt
08 c++ Operator Overloading.ppt08 c++ Operator Overloading.ppt
08 c++ Operator Overloading.ppt
Tareq Hasan
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
John De Goes
 
Inline function
Inline functionInline function
Inline function
Tech_MX
 

Was ist angesagt? (20)

c# keywords, identifiers and Naming Conventions
c# keywords, identifiers and Naming Conventionsc# keywords, identifiers and Naming Conventions
c# keywords, identifiers and Naming Conventions
 
Datatype in c++ unit 3 -topic 2
Datatype in c++ unit 3 -topic 2Datatype in c++ unit 3 -topic 2
Datatype in c++ unit 3 -topic 2
 
08 c++ Operator Overloading.ppt
08 c++ Operator Overloading.ppt08 c++ Operator Overloading.ppt
08 c++ Operator Overloading.ppt
 
Class and object in C++ By Pawan Thakur
Class and object in C++ By Pawan ThakurClass and object in C++ By Pawan Thakur
Class and object in C++ By Pawan Thakur
 
Function overloading ppt
Function overloading pptFunction overloading ppt
Function overloading ppt
 
Sequence and Traverse - Part 1
Sequence and Traverse - Part 1Sequence and Traverse - Part 1
Sequence and Traverse - Part 1
 
Encapsulation
EncapsulationEncapsulation
Encapsulation
 
DATA STRUCTURE AND ALGORITHMS
DATA STRUCTURE AND ALGORITHMS DATA STRUCTURE AND ALGORITHMS
DATA STRUCTURE AND ALGORITHMS
 
Refactoring Functional Type Classes
Refactoring Functional Type ClassesRefactoring Functional Type Classes
Refactoring Functional Type Classes
 
Haskell study 8
Haskell study 8Haskell study 8
Haskell study 8
 
Inline function
Inline functionInline function
Inline function
 
Unary operator overloading
Unary operator overloadingUnary operator overloading
Unary operator overloading
 
INLINE FUNCTION IN C++
INLINE FUNCTION IN C++INLINE FUNCTION IN C++
INLINE FUNCTION IN C++
 
Delegates and events in C#
Delegates and events in C#Delegates and events in C#
Delegates and events in C#
 
C++ classes tutorials
C++ classes tutorialsC++ classes tutorials
C++ classes tutorials
 
Boost your productivity with Scala tooling!
Boost your productivity  with Scala tooling!Boost your productivity  with Scala tooling!
Boost your productivity with Scala tooling!
 
Arrays in python
Arrays in pythonArrays in python
Arrays in python
 
Encapsulation
EncapsulationEncapsulation
Encapsulation
 
Object Oriented Programming Concepts for beginners
Object Oriented Programming Concepts for beginners Object Oriented Programming Concepts for beginners
Object Oriented Programming Concepts for beginners
 
operator overloading & type conversion in cpp over view || c++
operator overloading & type conversion in cpp over view || c++operator overloading & type conversion in cpp over view || c++
operator overloading & type conversion in cpp over view || c++
 

Andere mochten auch

Meta-Classes in Python
Meta-Classes in PythonMeta-Classes in Python
Meta-Classes in Python
Guy Wiener
 

Andere mochten auch (20)

EuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystifiedEuroPython 2015 - Decorators demystified
EuroPython 2015 - Decorators demystified
 
The (unknown) collections module
The (unknown) collections moduleThe (unknown) collections module
The (unknown) collections module
 
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)
 
Oop concepts classes_objects
Oop concepts classes_objectsOop concepts classes_objects
Oop concepts classes_objects
 
Message-passing concurrency in Python
Message-passing concurrency in PythonMessage-passing concurrency in Python
Message-passing concurrency in Python
 
Meta-Classes in Python
Meta-Classes in PythonMeta-Classes in Python
Meta-Classes 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
 
NETCONF Call Home
NETCONF Call Home NETCONF Call Home
NETCONF Call Home
 
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
 
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
 
DockerCon EU 2015: Persistent, stateful services with docker cluster, namespa...
DockerCon EU 2015: Persistent, stateful services with docker cluster, namespa...DockerCon EU 2015: Persistent, stateful services with docker cluster, namespa...
DockerCon EU 2015: Persistent, stateful services with docker cluster, namespa...
 
Django Best Practices
Django Best PracticesDjango Best Practices
Django Best Practices
 
An Introduction to Python Concurrency
An Introduction to Python ConcurrencyAn Introduction to Python Concurrency
An Introduction to Python Concurrency
 
QCon Rio - Machine Learning for Everyone
QCon Rio - Machine Learning for EveryoneQCon Rio - Machine Learning for Everyone
QCon Rio - Machine Learning for Everyone
 
Python for Image Understanding: Deep Learning with Convolutional Neural Nets
Python for Image Understanding: Deep Learning with Convolutional Neural NetsPython for Image Understanding: Deep Learning with Convolutional Neural Nets
Python for Image Understanding: Deep Learning with Convolutional Neural Nets
 
Tutorial on Deep learning and Applications
Tutorial on Deep learning and ApplicationsTutorial on Deep learning and Applications
Tutorial on Deep learning and Applications
 
Python Generator Hacking
Python Generator HackingPython Generator Hacking
Python Generator Hacking
 

Ähnlich wie Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.

DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
Graham Dumpleton
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New Relic
New Relic
 
Functions in python
Functions in pythonFunctions in python
Functions in python
Ilian Iliev
 
Php Reusing Code And Writing Functions
Php Reusing Code And Writing FunctionsPhp Reusing Code And Writing Functions
Php Reusing Code And Writing Functions
mussawir20
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
Jano Suchal
 

Ähnlich wie Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt. (20)

PyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating DecoratorsPyCon NZ 2013 - Advanced Methods For Creating Decorators
PyCon NZ 2013 - Advanced Methods For Creating Decorators
 
Python_Functions_Unit1.pptx
Python_Functions_Unit1.pptxPython_Functions_Unit1.pptx
Python_Functions_Unit1.pptx
 
The Ring programming language version 1.7 book - Part 35 of 196
The Ring programming language version 1.7 book - Part 35 of 196The Ring programming language version 1.7 book - Part 35 of 196
The Ring programming language version 1.7 book - Part 35 of 196
 
Decorators.pptx
Decorators.pptxDecorators.pptx
Decorators.pptx
 
Python : Functions
Python : FunctionsPython : Functions
Python : Functions
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)
 
DjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New RelicDjangoCon US 2011 - Monkeying around at New Relic
DjangoCon US 2011 - Monkeying around at New Relic
 
Djangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New RelicDjangocon11: Monkeying around at New Relic
Djangocon11: Monkeying around at New Relic
 
25-functions.ppt
25-functions.ppt25-functions.ppt
25-functions.ppt
 
Functions in python
Functions in pythonFunctions in python
Functions in python
 
Php Reusing Code And Writing Functions
Php Reusing Code And Writing FunctionsPhp Reusing Code And Writing Functions
Php Reusing Code And Writing Functions
 
Python decorators (中文)
Python decorators (中文)Python decorators (中文)
Python decorators (中文)
 
2 Functions2.pptx
2 Functions2.pptx2 Functions2.pptx
2 Functions2.pptx
 
Funkcija, objekt, python
Funkcija, objekt, pythonFunkcija, objekt, python
Funkcija, objekt, python
 
(map Clojure everyday-tasks)
(map Clojure everyday-tasks)(map Clojure everyday-tasks)
(map Clojure everyday-tasks)
 
UNIT- 2 PPDS R20.pptx
UNIT- 2 PPDS R20.pptxUNIT- 2 PPDS R20.pptx
UNIT- 2 PPDS R20.pptx
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Python Function.pdf
Python Function.pdfPython Function.pdf
Python Function.pdf
 
3. functions modules_programs (1)
3. functions modules_programs (1)3. functions modules_programs (1)
3. functions modules_programs (1)
 
Functions2.pdf
Functions2.pdfFunctions2.pdf
Functions2.pdf
 

Kürzlich hochgeladen

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Kürzlich hochgeladen (20)

Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Advantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your BusinessAdvantages of Hiring UIUX Design Service Providers for Your Business
Advantages of Hiring UIUX Design Service Providers for Your Business
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 

Decorators Explained: A Powerful Tool That Should Be in Your Python Toolbelt.

  • 1. Decorators Explained A Powerful Tool That Should Be in Your Python Toolbelt
  • 2. Samuel Fortier-Galarneau Software Developer @ Digium, Inc @samuelg http://github.com/samuelg
  • 3.
  • 4. Agenda • Primer • What is a decorator? • How do they work? • Examples
  • 5. Primer Functions • Functions in Python are first class members • They can be passed to other functions and return new functions def add(first, second): return first + second def partial(func, first): def wrapper(second): return func(first, second) return wrapper
  • 6. Primer Functions >>> func = partial(add, 1) >>> func(2) 3
  • 7. Primer Variable function arguments • Functions can have variable positional and keyword arguments via *args and **kwargs • *args and **kwargs can be packed again and passed along to another function def func(*args, **kwargs): print args print kwargs
  • 8. Primer Variable function arguments >>> func(1, 2, my_arg=‘value') (1, 2) {'my_arg': 'value'}
  • 9. Primer Variable function arguments def func(*args, **kwargs): other_func(*args, **kwargs) def other_func(arg1, arg2, arg3): print arg1 print arg2 print arg3
  • 10. Primer Variable function arguments >>> func(1, 2, arg3=3) 1 2 3
  • 11. What is a decorator? • Injects code before/after a function call or object creation • A callable wrapper around a callable resource (object that implements __call__ is callable) • Similar to macros in C/C++ but uses built in Python syntax and language semantics
  • 12. What is a decorator? • Can be implemented as a function or a class • Can be applied to a function or a class • Functions have an implicit __call__ method which makes them callable • Classes must implement a __call__ method to qualify as a decorator
  • 13. How do they work? Decorator function def decorator(func): def wrapper(): print 'in wrapper()' return func() return wrapper @decorator def my_function(): print 'in my_function()'
  • 14. How do they work? Decorator function >>> my_function() in wrapper() in my_function()
  • 15. How do they work? Decorator function def decorator(func): def wrapper(): print 'in wrapper()' return func() return wrapper @decorator def my_function(): print 'in my_function()'
  • 16. How do they work? Decorator function def decorator(func): def wrapper(): print 'in wrapper()' return func() return wrapper @decorator def my_function(): print 'in my_function()'
  • 17. How do they work? Decorator function def decorator(func): def wrapper(): print 'in wrapper()' return func() return wrapper @decorator def my_function(): print 'in my_function()'
  • 18. How do they work? Decorator function def decorator(func): def wrapper(): print 'in wrapper()' return func() return wrapper @decorator def my_function(): print 'in my_function()'
  • 19. How do they work? Decorator function wrapper is a closure over func def decorator(func): def wrapper(): print 'in wrapper()' return func() return wrapper @decorator def my_function(): print 'in my_function()'
  • 20. How do they work? Decorator function def decorator(func): def wrapper(): print 'in wrapper()' return func() return wrapper @decorator def my_function(): print 'in my_function()'
  • 21. How do they work? Decorator class class Decorator(object): def __init__(self, func): self.func = func def __call__(self): print 'in __call__()' return self.func() @Decorator def my_function(): print 'in my_function()'
  • 22. How do they work? Decorator class >>> my_function() in __call__() in my_function()
  • 23. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 24. How do they work? Decorator function with arguments >>> my_function() in wrapper() (1,) {'config': 'value'} in my_function()
  • 25. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 26. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 27. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 28. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 29. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 30. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 31. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 32. How do they work? Decorator function with arguments def decorator(*args, **kwargs): def receiver(func): def wrapper(): print 'in wrapper()' print args print kwargs return func() return wrapper return receiver @decorator(1, config='value') def my_function(): print 'in my_function()'
  • 33. How do they work? Decorator class with arguments class Decorator(object): def __init__(self, *args, **kwargs): self.args = args self.kwargs = kwargs def __call__(self, func): def wrapper(): print 'in __call__()' print self.args print self.kwargs return func() return wrapper @Decorator(1, config='value') def my_function(): print 'in my_function()'
  • 34. How do they work? Decorator class with arguments >>> my_function() in __call__() (1,) {'config': 'value'} in my_function()
  • 35. Example: counting function calls class Counter(object): def __init__(self, func): self.count = 0 self.func = func def __call__(self): self.count += 1 return self.func() def getCount(self): return self.count @Counter def function(): pass
  • 36. Example: counting function calls >>> function() >>> function() >>> function() >>> function.getCount() 3
  • 37. Example: memoize class Memoize(object): def __init__(self, func): self.cache = {} self.func = func def __call__(self, *args, **kwargs): cache_key = '%s%s' % (args, kwargs) if cache_key in self.cache: return self.cache[cache_key] else: result = self.func(*args, **kwargs) self.cache[cache_key] = result return result @Memoize def function(bound): sum = 0 for x in range(bound): sum += x return sum
  • 38. Example: memoize >>> function(100000000) ~ 11 seconds >>> function(100000000) ~ 10 milliseconds
  • 39. Example: type checker def type_check(*types): def receiver(func): def wrapper(*args, **kwargs): for index, type_arg in enumerate(types): if type(args[index]) != type_arg: raise TypeError('Expected %s at index %s' % (type_arg, index)) return func(*args, **kwargs) return wrapper return receiver @type_check(int, int, str) def function(first, second, third): print 'success'
  • 40. Example: type checker >>> function(1, 2, ‘works') success >>> function('will', 'not', ‘work') Traceback (most recent call last): File "type.py", line 17, in <module> function('will', 'not', 'work') File "type.py", line 7, in wrapper raise TypeError('Expected %s at index %s' % (type_arg, index)) TypeError: Expected <type 'int'> at index 0
  • 41. Example: singleton instances = {} def singleton(cls): def create(*args): if cls not in instances: instances[cls] = cls(*args) return instances[cls] return create @singleton class Toolbelt(object): def __init__(self): pass
  • 42. Example: singleton >>> toolbelt = Toolbelt() >>> another = Toolbelt() >>> another == toolbelt True
  • 43. Other uses • Retries • Pre/Post conditions • Function input/output transforms • Performance logging • Authorization
  • 44. Thanks! Samuel Fortier-Galarneau @samuelg http://github.com/samuelg http://www.slideshare.net/sgalarne/decorators-2