如何从Python装饰器内部访问装饰方法的局部变量(locals())?

3 投票
2 回答
998 浏览
提问于 2025-04-16 23:57

我需要做的是:

假设我有一个装饰器:

def deco(func):
    def decoret(*args, **kwargs):
        print(func.__locals__) # I know __locals__ is not valid, but I need something like this
    return decoret

@deco
def func():
    test1 = 123
    test2 = 456

func()

我想获取一个包含所有局部变量的列表(就像在函数内部调用locals()一样),这样我就能在装饰器的decor函数里访问到一个包含test1和test2值的字典

我知道可以通过使用Python的inspect模块来实现这个,但我找不到正确的框架来获取这个函数。

另外,我使用的是Python 3.2的CPython版本。

2 个回答

1

其实,我找到了一种方法,可以绕过这个问题并通过系统的跟踪来实现。

看看这个代码片段:

def Property(function):
    keys = 'fget', 'fset', 'fdel'
    func_locals = {'doc':function.__doc__}
    def probeFunc(frame, event, arg):
        if event == 'return':
            locals = frame.f_locals
            func_locals.update(dict((k,locals.get(k)) for k in keys))
            sys.settrace(None)
        return probeFunc
    sys.settrace(probeFunc)
    function()
    return property(**func_locals)

这个代码是从一个位于 http://code.activestate.com/recipes/410698/ 的代码片段中拿来的。

另外,看看这个StackOverflow的话题: Python: 静态变量装饰器

3

在一个函数执行之前,它里面是没有任何局部变量的。你在给函数加装饰的时候,能用的东西只有在定义这个函数时就已经存在的那些。

d = 'd'
def a(d=d):
    b = 'b'
    c = 'c'

print a.__dict__
# {}
print a.b
# AttributeError: 'function' object has no attribute 'b'
print dir(a)
# Doesn't print anything

撰写回答