作为装饰参数的变量

2024-07-04 09:16:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我发现decorator参数是在decorator定义中传递的,而不是像函数那样的调用。你知道吗

现在我想知道是否有可能让decorator在运行时获得这样一个变量的值,decorator应该打印state的当前值,而不是它在定义处的值:

def deco(msg):
    def decorater(func):
        def wrapper(*args, **kwargs):
            print msg
            func(*args, **kwargs)
        return wrapper
    return decorater


def func():
    local = {
        "state": None
    }

    @deco(local["state"])
    def test():
        pass

    def setState(newState):
        local["state"] = newState

    setState("start")
    test()
    setState("test")
    test()

func()

Tags: testreturn定义localdefargsmsgdecorator
2条回答

约翰你应该读this。在python中,变量不是对象。你的问题是“是否有可能让decorator在运行时获得一个变量的值”,因为python的作用域规则是没有意义的。decorator函数通常无权访问定义state的范围。不过,有几种方法可以让你得到想要的行为。你知道吗

在不知道你想做什么的具体情况下,这里有两个可能有用的方法。第一个使用闭包:

state = None
def with_closure(f):
     def helper(*args, **kwargs):
        # state is in scope for this function
        print "Current state is: {}.".format(state)
        return f(*args, **kwargs)
     return helper

@with_closure
def foo():
    return "something"

或者可以制作一个对象来跟踪状态:

class StateHolder:
    def set_state(self, state):
        self.state = state

def with_state_object(state_object):
    def decorator(f):
        def helper(*args, **kwargs):
            print "Current state is: {}.".format(state_object.state)
            return f(*args, **kwargs)
        return helper
    return decorator

global_state = StateHolder()
global_state.set_state("some state")

@with_state_object(global_state)
def foo():
    return "something"

在您的示例中,deco()是一个decorator工厂;您正在创建decorator,然后它将立即被调用。更一般地说,在定义要修饰的函数时调用修饰器。你知道吗

您只需不传入state,并从wrapper()中作为全局访问它,就可以用最少的更改来完成您想要做的事情,在这种情况下,您不需要deco();您可以直接使用@decorator。也就是说,我认为有更好的方法来做你想做的事情。你知道吗

相关问题 更多 >

    热门问题