Python装饰函数作用域
我似乎不知道下面的代码是否没有将demovar公开给修饰函数:Python装饰函数作用域,python,multithreading,decorator,scoping,Python,Multithreading,Decorator,Scoping,我似乎不知道下面的代码是否没有将demovar公开给修饰函数: def exposebasevar(function): def decorator(*args, **kwargs): demovar = 'Where am I?' # => or MyThreadSafeObjectHandle() return function(*args, **kwargs) return decorator @exposebasevar def u
def exposebasevar(function):
def decorator(*args, **kwargs):
demovar = 'Where am I?' # => or MyThreadSafeObjectHandle()
return function(*args, **kwargs)
return decorator
@exposebasevar
def usesexposedvariable():
print demovar # this line will give an error
usesexposedvariable()
背景:我有一个模块,每个函数都使用一个全局变量。
现在我想让这个线程安全,所以我想让这个变量通过一个装饰程序来实现。然后在decorator中,我可以找出对象的哪个实例属于线程,并将其传入。这样我就不需要更改每个函数的签名或内容
有人知道怎么设置吗?谢谢。您的代码不工作的原因与以下原因完全相同:
def f():
print v # NameError: global name 'v' is not defined
def g():
v = 42
f()
g()
最干净的方法可能是将demovar
作为参数传递给函数
:
def exposebasevar(function):
def decorator(*args, **kwargs):
demovar = 'Where am I?' # => or MyThreadSafeObjectHandle()
return function(*args, demovar=demovar, **kwargs)
return decorator
@exposebasevar
def usesexposedvariable(demovar):
print demovar # this line will give an error
usesexposedvariable()
您的代码不工作的原因与以下原因完全相同:
def f():
print v # NameError: global name 'v' is not defined
def g():
v = 42
f()
g()
最干净的方法可能是将demovar
作为参数传递给函数
:
def exposebasevar(function):
def decorator(*args, **kwargs):
demovar = 'Where am I?' # => or MyThreadSafeObjectHandle()
return function(*args, demovar=demovar, **kwargs)
return decorator
@exposebasevar
def usesexposedvariable(demovar):
print demovar # this line will give an error
usesexposedvariable()
这将是动态范围界定。人们普遍认为这是一个非常糟糕的想法,因此在包括Python在内的多种语言中根本不受支持。只是不可能,除非你想拉非常肮脏和脆弱的黑客。实际上,我将此作为标准免责声明,并不是因为我心中有任何这样的解决方案。我能提供的最接近“工作”的方法是重新编写字节码,呃 相反,将其作为修饰函数的参数。或者摆脱全球批发,从长远来看,这可能会更简单、更好
def exposebasevar(function):
def decorator(*args, **kwargs):
demovar = 'Where am I?'
return function(*args, demovar=demovar, **kwargs) # <<
return decorator
@exposebasevar
def usesexposedvariable(demovar): # <<
print demovar
def exposebasevar(函数):
def装饰器(*args,**kwargs):
德莫瓦尔=‘我在哪里?’
返回函数(*args,demovar=demovar,**kwargs)#这将是动态作用域。人们普遍认为这是一个非常糟糕的想法,因此在包括Python在内的多种语言中根本不受支持。只是不可能,除非你想拉非常肮脏和脆弱的黑客。实际上,我将此作为标准免责声明,并不是因为我心中有任何这样的解决方案。我能提供的最接近“工作”的方法是重新编写字节码,呃
相反,将其作为修饰函数的参数。或者摆脱全球批发,从长远来看,这可能会更简单、更好
def exposebasevar(function):
def decorator(*args, **kwargs):
demovar = 'Where am I?'
return function(*args, demovar=demovar, **kwargs) # <<
return decorator
@exposebasevar
def usesexposedvariable(demovar): # <<
print demovar
def exposebasevar(函数):
def装饰器(*args,**kwargs):
德莫瓦尔=‘我在哪里?’
返回函数(*args,demovar=demovar,**kwargs)#
我有一个模块,每个函数都使用一个全局变量。现在我想让那个线程安全
你所描述的基本上是目的;不幸的是,您可能需要稍微更改代码以使其工作,问题是线程本地对象本身不是线程本地对象;只有它的属性是。只要始终使用线程本地对象的属性,它几乎是透明的:
我有一个模块,每个函数都使用一个全局变量。现在我想让那个线程安全
你所描述的基本上是目的;不幸的是,您可能需要稍微更改代码以使其工作,问题是线程本地对象本身不是线程本地对象;只有它的属性是。只要您始终使用线程本地对象的属性,它几乎是透明的:欢迎使用StackOverflow!为什么您希望这段代码使demovar对函数可用?为什么不将demovar作为参数传递给函数呢?值得注意的是,无论您在哪里进行这种包装,都可以使用它。欢迎使用StackOverflow!为什么您希望这段代码使demovar对函数可用?为什么不直接将demovar作为参数传递给函数呢?值得注意的是,无论你在哪里进行这种包装,使用它都是一个好主意。谢谢,我知道它有点粗糙。。。然后,当每个文件中的每个函数都需要第一个参数来传递作用域时,有些东西告诉我应该自动执行。@user1951656是的,您可以自动执行tjat。使用sed
或重构工具;-)它还有一个额外的好处,那就是它不会产生运行时成本,也不是需要破译才能理解代码的魔法。。。然后,当每个文件中的每个函数都需要第一个参数来传递作用域时,有些东西告诉我应该自动执行。@user1951656是的,您可以自动执行tjat。使用sed
或重构工具;-)它还有一个额外的好处,那就是它不产生运行时成本,也不是为了理解代码而必须破译的魔法。谢谢。我将使用Flask框架的方法,使全局变量成为真实对象的代理对象,将其作为真实对象,然后在每次访问时使用基于线程id的dict快速偷偷地查找代理对象。不知何故,这也给了我一种非常棘手的解决方法。。。基本上,唯一的“非黑客”方法就是将te参数(例如“请求”)传递给每个请求处理程序,这是非常可行的。只是有点。。。不优雅。。。我希望我能自动实现这一点,或者以某种方式将其传递给函数访问的函数“globals”。其他想法仍然欢迎:)谢谢。我将使用Flask框架的方法,使全局变量成为真实对象的代理对象,将其作为真实对象,然后在每次访问时使用基于线程id的dict快速偷偷地查找代理对象。不知何故,这也给了我一种非常棘手的解决方法。。。基本上,唯一的“非黑客”方法就是将te参数(例如“请求”)传递给每个请求处理程序,这是非常可行的。只是有点。。。不优雅。。。我希望我能自动实现这一点,或者以某种方式将其传递给函数访问的函数“globals”。其他想法仍然受欢迎:)