Вызов функции без вызова функции-обертки функции
Допустим, у меня есть функция:
@some_authorization
def to_call():
pass
Теперь я хочу вызвать эту функцию to_call(), но не хочу, чтобы выполнялась функция-обертка @some_authorization. Как реализовать этот сценарий?
Когда вы украшаете функцию, вы переназначаете ее имя на то, что возвращается декоратором. Если вы не хотите этого, не украшайте метод.
Вместо этого вы можете вызвать декоратор как стандартную функцию, передав ему функцию, а результат присвоить другому имени.
def some_authorization(f):
def func(*args, **kwargs):
print("authorizing")
return f(*args, **kwargs)
return func
def to_call():
pass
authorized_to_call = some_authorization(to_call)
print('to call')
to_call()
print('authorized to call')
authorized_to_call()
(some_authorization
- это точно такой же декоратор, который вы бы использовали для украшения to_call
в противном случае)
Добавлю к ответу @matszwecja, декоратор не обязательно должен возвращать функцию (на самом деле, он вообще не должен возвращать ничего вызываемого, но это была бы плохая идея). Поэтому можно вернуть объект, который является вызываемым, но также позволяет получить исходную функцию:
def keeping_original_fun(decorator):
class WrappedFun:
def __init__(self, fun):
self.fun = fun
self.decorated_fun = decorator(fun)
def __call__(self, *args, **kwargs):
return self.decorated_fun(*args, **kwargs)
return WrappedFun
Так что вместо украшения some_authorization, вы могли бы сделать
@keeping_original_fun(some_authorization)
def to_call():
pass
Таким образом, вы все еще можете получить доступ к оригинальному описанию to_call
через to_call.fun
.