获取 co_names 个函数,而不是 co_names 个装饰器
Get co_names of function, not co_names of decorators
我有一个装饰函数。当我调用 __call__.co_names
时,我想获取函数中列出的名称,但它却给了我装饰器中列出的名称。让我告诉你:
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
baz()
return func(*args, **kwargs)
return wrapper
@decorator
def foo():
bar()
def bar():
print('bar is the name I want')
def baz():
print('baz is the name I get')
def foo2(): # undecorated
bar()
foo.__code__.co_names
# ['baz']
foo2.__code__.co_names
# ['bar']
在调用 .__code__.co_names
以获取函数内部的名称而不是装饰器函数之前,我可以对 foo
做些什么吗?
基本上,我如何先剥离所有装饰器函数?
来自 functools
文档:
To allow access to the original function for introspection and other purposes (e.g. bypassing a caching decorator such as lru_cache()
), this function automatically adds a __wrapped__
attribute to the wrapper that refers to the function being wrapped.
所以你可以这样做:
def get_original_function(f):
return getattr(f, '__wrapped__', f) # default is f, if no __wrapped__ attribute
这也适用于具有多个装饰器的函数; __wrapped__
指的是原来的装饰函数,只要每个装饰器都使用@wraps
,所以不需要遵循多个.__wrapped__
引用。
我有一个装饰函数。当我调用 __call__.co_names
时,我想获取函数中列出的名称,但它却给了我装饰器中列出的名称。让我告诉你:
from functools import wraps
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
baz()
return func(*args, **kwargs)
return wrapper
@decorator
def foo():
bar()
def bar():
print('bar is the name I want')
def baz():
print('baz is the name I get')
def foo2(): # undecorated
bar()
foo.__code__.co_names
# ['baz']
foo2.__code__.co_names
# ['bar']
在调用 .__code__.co_names
以获取函数内部的名称而不是装饰器函数之前,我可以对 foo
做些什么吗?
基本上,我如何先剥离所有装饰器函数?
来自 functools
文档:
To allow access to the original function for introspection and other purposes (e.g. bypassing a caching decorator such as
lru_cache()
), this function automatically adds a__wrapped__
attribute to the wrapper that refers to the function being wrapped.
所以你可以这样做:
def get_original_function(f):
return getattr(f, '__wrapped__', f) # default is f, if no __wrapped__ attribute
这也适用于具有多个装饰器的函数; __wrapped__
指的是原来的装饰函数,只要每个装饰器都使用@wraps
,所以不需要遵循多个.__wrapped__
引用。