gpt4 book ai didi

python - 是否可以检查一个函数是否在另一个函数中被修饰?

转载 作者:太空宇宙 更新时间:2023-11-04 02:10:49 25 4
gpt4 key购买 nike

在我的示例中,如果调用函数(此处为decoratednot_decorated)具有特定的装饰器,是否有任何方法可以检查内部函数 f1 (在代码 @out 中)?这些信息是否传递给函数?

def out(fun):
def inner(*args, **kwargs):
fun(*args, **kwargs)
return inner

@out
def decorated():
f1()

def not_decorated():
f1()

def f1():
if is_decorated_by_out: # here I want to check it
print('I am')
else:
print('I am not')

decorated()
not_decorated()

预期输出:

I am
I am not

最佳答案

需要说明的是,这是骇人听闻的骇客行为,所以我不推荐这样做,但由于您已经排除了其他参数,而且无论是否包装,f1 都是一样的,您我们把黑客作为你唯一的选择。解决方案是在包装函数中添加一个局部变量,其唯一目的是通过堆栈检查找到:

import inspect

def out(fun):
def inner(*args, **kwargs):
__wrapped_by__ = out
fun(*args, **kwargs)
return inner

def is_wrapped_by(func):
try:
return inspect.currentframe().f_back.f_back.f_back.f_locals.get('__wrapped_by__') is func
except AttributeError:
return False

@out
def decorated():
f1()

def not_decorated():
f1()

def f1():
if is_wrapped_by(out):
print('I am')
else:
print('I am not')

decorated()
not_decorated()

Try it online!

这假设了特定程度的嵌套(通过 f_back 的手动回溯来解释 is_wrapped_by 本身,f1 decorated 最后到 inner(从 out)。如果你想确定 out 是否涉及 anywhere 在调用堆栈中,使 is_wrapped_by 循环直到堆栈耗尽:

def is_wrapped_by(func):
frame = None
try:
# Skip is_wrapped_by and caller
frame = inspect.currentframe().f_back.f_back
while True:
if frame.f_locals.get('__wrapped_by__') is func:
return True
frame = frame.f_back
except AttributeError:
pass
finally:
# Leaving frame on the call stack can cause cycle involving locals
# which delays cleanup until cycle collector runs;
# explicitly break cycle to save yourself the headache
del frame
return False

关于python - 是否可以检查一个函数是否在另一个函数中被修饰?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53769051/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com