Написание хорошего декоратора ничем не отличается от написания хорошей функции. Что в идеале означает использование строк документации и обеспечение того, чтобы декоратор был включен в вашу среду тестирования.
Вам обязательно следует использовать либо библиотеку decorator
, либо, что лучше, декоратор functools.wraps()
в стандартной библиотеке (начиная с 2.5).
Кроме того, лучше всего держать ваши декораторы узко сфокусированными и хорошо продуманными. Не используйте *args
или **kw
, если ваш декоратор ожидает определенных аргументов. И do укажите, какие аргументы вы ожидаете, вместо:
def keep_none(func):
def _exec(*args, **kw):
return None if args[0] is None else func(*args, **kw)
return _exec
... использовать ...
def keep_none(func):
"""Wraps a function which expects a value as the first argument, and
ensures the function won't get called with *None*. If it is, this
will return *None*.
>>> def f(x):
... return x + 5
>>> f(1)
6
>>> f(None) is None
Traceback (most recent call last):
...
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
>>> f = keep_none(f)
>>> f(1)
6
>>> f(None) is None
True"""
@wraps(func)
def _exec(value, *args, **kw):
return None if value is None else func(value, *args, **kw)
return _exec