4.3. Decorator Types¶
By type:
Function decorators
Class decorators
By decorated object:
Decorating function
Decorating class
Decorating method
By wrapper type:
Wrapper function
Wrapper class
Wrapper method
By number of arguments:
Without arguments
With arguments
4.3.1. Decorator Types¶
Function decorators
Class decorators
In this example:
obj
is a decorated objectdoesn't matter, whether is a function, class or method
>>> def mydecorator(obj):
... ...
>>> class MyDecorator:
... def __init__(self, obj):
... ...
4.3.2. Wrapper Type¶
Wrapper function
Wrapper class
Wrapper method
In this example:
obj
is a decorated objectdoesn't matter, whether is a function, class or method
If
obj
andWrapper
are classes,Wrapper
can inherit fromobj
(to extend it)
>>> def mydecorator(obj):
... def wrapper(*args, **kwargs):
... ...
... return wrapper
>>> def mydecorator(obj):
... class Wrapper:
... def __init__(self, *args, **kwargs):
... ...
... return Wrapper
>>> class MyDecorator:
... def __init__(self, obj):
... ...
...
... def __call__(self, *args, **kwargs):
... ...
4.3.3. Decorated Object¶
Decorating function (by convention
func
orfn
)Decorating class (by convention
cls
)Decorating method (by convention
mth
,meth
ormethod
)
>>> def mydecorator(func):
... ...
>>> def mydecorator(cls):
... ...
>>> def mydecorator(mth):
... ...
>>> class MyDecorator:
... def __init__(self, func):
... ...
>>> class MyDecorator:
... def __init__(self, cls):
... ...
>>> class MyDecorator:
... def __init__(self, mth):
... ...
4.3.4. Usage¶
>>> @mydecorator
... def myfunction(*args, **kwargs):
... ...
>>> class MyClass:
... @mydecorator
... def mymethod(self, *args, **kwargs):
... ...
>>> @mydecorator
... class MyClass:
... ...
>>> @MyDecorator
... def myfunction(*args, **kwargs):
... ...
>>> class MyClass:
... @MyDecorator
... def mymethod(self, *args, **kwargs):
... ...
>>> @MyDecorator
... class MyClass:
... ...
4.3.5. Arguments¶
Without arguments
With arguments
>>> @mydecorator
... def myfunction(*args, **kwargs):
... ...
>>> @MyDecorator
... def myfunction(*args, **kwargs):
... ...
>>> @mydecorator('arg1', 'arg2')
... def myfunction(*args, **kwargs):
... ...
>>> @MyClass('arg1', 'arg2')
... def myfunction(*args, **kwargs):
... ...
4.3.6. Assignments¶
"""
* Assignment: Decorator Syntax About
* Complexity: easy
* Lines of code: 5 lines
* Time: 5 min
English:
1. Create decorator `mydecorator`
2. Decorator should have `wrapper` with `*args` and `**kwargs` parameters
3. Wrapper should call original function with it's original parameters,
and return its value
4. Decorator should return `wrapper` function
5. Run doctests - all must succeed
Polish:
1. Stwórz dekorator `mydecorator`
2. Dekorator powinien mieć `wrapper` z parametrami `*args` i `**kwargs`
3. Wrapper powinien wywoływać oryginalną funkcję z jej oryginalnymi
parametrami i zwracać jej wartość
4. Decorator powinien zwracać funckję `wrapper`
5. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isfunction
>>> assert isfunction(mydecorator), \
'Create mydecorator() function'
>>> assert isfunction(mydecorator(lambda: ...)), \
'mydecorator() should take function as an argument'
>>> @mydecorator
... def echo(text):
... return text
>>> echo('hello')
'hello'
"""
# type: Callable[[Callable], Callable]
def mydecorator():
pass
"""
* Assignment: Decorator Syntax Disable
* Complexity: easy
* Lines of code: 1 lines
* Time: 5 min
English:
1. Modify decorator `disable`
2. Decorator raises `PermissionError` and does not execute function
3. Run doctests - all must succeed
Polish:
1. Zmodyfikuj dekorator `disable`
2. Dekorator podnosi `PermissionError` i nie wywołuje funkcji
3. Uruchom doctesty - wszystkie muszą się powieść
Tests:
>>> import sys; sys.tracebacklimit = 0
>>> from inspect import isfunction
>>> assert isfunction(disable), \
'Create disable() function'
>>> assert isfunction(disable(lambda: ...)), \
'disable() should take function as an argument'
>>> @disable
... def echo(text):
... print(text)
>>> echo('hello')
Traceback (most recent call last):
PermissionError: Function is disabled
"""
# type: Callable[[Callable], Callable]
def disable(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper