Python 作为装饰参数的变量

Python 作为装饰参数的变量,python,decorator,Python,Decorator,我发现decorator参数是在decorator定义中传递的,而不是像函数那样的调用 现在我想知道是否有可能让decorator在运行时像这样获得变量的值,decorator应该打印state的当前值,而不是它在定义中的头: def deco(msg): def decorater(func): def wrapper(*args, **kwargs): print msg func(*args, **kwargs)

我发现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()

在您的示例中,
deco()
是一个装饰工厂;您正在创建装饰器,该装饰器将立即被调用。更一般地说,在定义要装饰的函数时调用装饰器


您只需不传入
状态
,并从
包装器()
中以全局形式访问它,就可以用最小的更改完成您想要做的事情,在这种情况下,您不需要
deco()
;您可以直接使用
@decorator
。也就是说,我认为有更好的方法来做你想做的事情。

在你的例子中,
deco()
是一家装饰工厂;您正在创建装饰器,该装饰器将立即被调用。更一般地说,在定义要装饰的函数时调用装饰器

您只需不传入
状态
,并从
包装器()
中以全局形式访问它,就可以用最小的更改完成您想要做的事情,在这种情况下,您不需要
deco()
;您可以直接使用
@decorator
。也就是说,我认为有更好的方法来做你想做的事。

约翰,你应该读一读。在python中,变量不是对象。您的问题是,“是否有可能让装饰程序在运行时获得变量的值”,这是没有意义的,因为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"
约翰:你应该读书。在python中,变量不是对象。您的问题是,“是否有可能让装饰程序在运行时获得变量的值”,这是没有意义的,因为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"

我要做的是将参数传递给装饰器。我希望此参数包含调用函数时的数据,而不是定义时的数据。@JohnSmith,用实际代码编辑您的问题,实际代码正试图做您想要的事情,我将能够更好地回答。我不能在这里发布20k行代码。我提供的例子确实说明了这个问题。我不知道为什么在理解调用和定义之间的区别时会遇到这样的问题。。。如果您调用测试函数,装饰器将打印它在定义中的参数。我想让它打印它在调用时的参数值。为什么你认为我在理解差异方面有“这样的问题”?在我的回答中,我用这两个词来解释不同的事情。我也告诉过你如何去做你想做的事情,我只是说有更好的方法去做,并要求提供更多的背景,以便我能更好地帮助你。因为你问我想做什么,而我已经两次解释了。那你为什么不告诉我更好的方法呢?我想做的是把论点传给装饰师。我希望此参数包含调用函数时的数据,而不是定义时的数据。@JohnSmith,用实际代码编辑您的问题,实际代码正试图做您想要的事情,我将能够更好地回答。我不能在这里发布20k行代码。我提供的例子确实说明了这个问题。我不知道为什么在理解调用和定义之间的区别时会遇到这样的问题。。。如果您调用测试函数,装饰器将打印它在定义中的参数。我想让它打印它在调用时的参数值。为什么你认为我在理解差异方面有“这样的问题”?在我的回答中,我用这两个词来解释不同的事情。我也告诉过你如何去做你想做的事情,我只是说有更好的方法去做,并要求提供更多的背景,以便我能更好地帮助你。因为你问我想做什么,而我已经两次解释了。那你为什么不告诉我更好的方法呢