如何保存函数参数名称后,它是包装?



我有一个包装函数。我希望这个函数包含它的原始名称和参数名称。我正在使用Python 2.7.

这不是我的原始代码,但代表了我的问题:

from functools import wraps
def deco(func):
@wraps(func) #here i tried @wraps(func, assigned=("__name__", "__code__")) but it seems the __code__ attribute is read only
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
@deco
def f(a):
pass
print f.__code__.co_varnames

返回:

('args', 'kwargs')

:

('a',)

我找到了函数属性__closure__,它有助于获得原始函数,从而获得原始参数。但是,如果我需要装饰器中的参数名称,并且函数有多个包装器,则必须编写一个新函数,该函数返回包装函数的原始参数名称。

这并不难,但是如果functools方法wraps可以分配属性__name__,也许还有其他方法可以分配参数?

似乎没有一个内置方法来将包装函数的参数设置为包装函数。因此,我创建了一个新的装饰器,它为原始函数创建了一个__wrapped__属性。这个属性包含一个self函数,因此您不需要在第一个装饰器中检查它是否存在。然后用原始函数中的__dict____name__更新包装器。


from inspect import getargspec

def wrap_wrapper(wrapped):
def update_wrapper_attributes(wrapper):
if '__wrapped__' not in wrapped.__dict__:  # it will only work in the first decorator and not let overwrite
# __wrapped__ with next wrapper function
wrapped.__wrapped__ = wrapped  # I don't need to check if there is an attribute __wrapped__
wrapper.__dict__.update(wrapped.__dict__)  # now wrapper have an attribute __wrapped__
wrapper.__name__ = wrapped.__name__  # save the original function name through decorators
return wrapper
return update_wrapper_attributes

def another_deco(func):
@wrap_wrapper(func)
def wrap(*args, **kvargs):
print "FROM THE SECOND DECORATOR ORIGINAL FUNCTION ARG NAMES:", getargspec(func.__wrapped__)[0]
return func(*args, **kvargs)
return wrap

def deco_who_takes_parameters(a, b):
def deco(func):
@wrap_wrapper(func)
def wrap(*args, **kvargs):
print "FROM THE FIRST DECORATOR ORIGINAL FUNCTION ARG NAMES:", getargspec(func.__wrapped__)[0]
a(b)  # do something with a and b
return func(*args, **kvargs)
return wrap
return deco

@another_deco
@deco_who_takes_parameters(str, 1)
def f(a):
return a

f(1)
print "FINALLY:", getargspec(f.__wrapped__)[0]
print "WRAPPED FUNCTION NAME IS THE SAME AS ORIGINAL FUNCTION NAME:", f.__name__

结果:


FROM THE SECOND DECORATOR ORIGINAL FUNCTION ARG NAMES: ['a']
FROM THE FIRST DECORATOR ORIGINAL FUNCTION ARG NAMES: ['a']
FINALLY: ['a']
WRAPPED FUNCTION NAME IS THE SAME AS ORIGINAL FUNCTION NAME: f

最新更新