#python #python-3.x #amazon-web-services #decorator #python-decorators
#питон #python-3.x #amazon-веб-сервисы #оформитель #питон-декораторы
Вопрос:
Я вижу много примеров обертывания декораторов своими собственными, но все они касаются пользовательских декораторов. У меня есть сторонний декоратор, который можно использовать, например:
@someSDK myFunction()
что я хочу сделать, так это обернуть это в свой собственный декоратор, который вызывает @someSDK
только в том случае, если env имеет значение true
ПРАВКА: в частности, декоратор третьей стороны @xray_recorder.capture()
. Мне нужен мой собственный декоратор, который будет реализовывать это только в том случае, если у меня есть переменная, установленная в качестве определенного флага.
Это то, что у меня пока есть приблизительное представление:
if CUSTOM_XRAY_WRAPPER is True: @xray_recorder.capture() def wrapper(*args, **kwargs): val = func(*args, **kwargs) return val return wrapper else: def wrapper(*args, **kwargs): val = func(*args, **kwargs) return val return wrapper
Ответ №1:
В качестве небольшого примера, поскольку вы не привели минимального воспроизводимого примера:
CUSTOM_XRAY_WRAPPER = True def xray_capture(func): def wrapper(*args, **kwargs): print('recodring') return func(*args, **kwargs) return wrapper def yourdecorator(func): if CUSTOM_XRAY_WRAPPER: return xray_capture(func) return func @yourdecorator def yourfunction(text): print(text)
Здесь использование xray_capture
декоратора для функции выводит «запись» перед выполнением этой функции. Вместо этого функцию yourdecorator
можно использовать в качестве декоратора, который возвращает либо обычную функцию как есть, если значение CUSTOM_XRAY_WRAPPER равно False. Если это правда, он возвращает функцию, украшенную xray_capture
.
Кстати, вам не нужно писать CUSTOM_XRAY_WRAPPER == True
, так как это уже либо Правда, либо Ложь, что означает, что вы проверяете, является ли True == True
или False == True
.
В вашем примере это будет выглядеть так:
def yourdecorator(func): if CUSTOM_XRAY_WRAPPER: xray_recorder.capture()(func) return func
Комментарии:
1. Неверно ли то, как я это сделал, добавив аннотацию перед оберткой?
2. Что ж, ваша версия определенно неверна. Насколько я вижу, вы никогда на самом деле не определяете настоящего декоратора. Вы определяете функцию-оболочку ony.
Ответ №2:
Что вам нужно помнить, так это то, что
@decorator def foobar(): ...
эквивалентно
def foobar(): ... foobar = decorator(foobar)
Итак, чего ты хочешь, так это
def my_decorator(f): if CUSTOM_XRAY_WRAPPER: return xray_recorder.capture()(f) else: return f
Ответ №3:
Вы можете переименовать декоратора и использовать сквозной:
from functools import wraps MY_ENV_VAR = True # create a pass-through wrapper def sample_decorator(f): @wraps(f) def wrapper(*args, **kwargs): return f(*args, **kwargs) return wrapper # now you can just use the same decorator everywhere if MY_ENV_VAR: # use your recorder.capture x_ray_capture = xray_recorder.capture() else: # pass-through x_ray_capture = sample_decorator @x_ray_capture def foo(): # do something
Комментарии:
1. разве это не должно быть xray_recorder.capture() в первом случае, если?
2. @qaispak это должно быть исправлено