Python 作为装饰参数的变量
我发现decorator参数是在decorator定义中传递的,而不是像函数那样的调用 现在我想知道是否有可能让decorator在运行时像这样获得变量的值,decorator应该打印state的当前值,而不是它在定义中的头: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)
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行代码。我提供的例子确实说明了这个问题。我不知道为什么在理解调用和定义之间的区别时会遇到这样的问题。。。如果您调用测试函数,装饰器将打印它在定义中的参数。我想让它打印它在调用时的参数值。为什么你认为我在理解差异方面有“这样的问题”?在我的回答中,我用这两个词来解释不同的事情。我也告诉过你如何去做你想做的事情,我只是说有更好的方法去做,并要求提供更多的背景,以便我能更好地帮助你。因为你问我想做什么,而我已经两次解释了。那你为什么不告诉我更好的方法呢