我有以下代码:
import threading
from functools import wraps
class Synchronized(object):
def __init__(self):
self.lock = threading.Lock()
def synchronized(f):
@wraps(f)
def wrapper(self, *args, **kwargs):
with self.lock:
print "here"
return f(self, *args, **kwargs)
return wrapper
@synchronized
def go(self):
print 1
class B(Synchronized):
@synchronized
def foo(self):
return 1
此代码在导入抱怨时失败:
File "a.py", line XXX, in B
@synchronized
NameError: name 'synchronized' is not defined
但是,如果我注释掉B并且只使用Syncrhonized().go()
,那么效果很好。
问题: python如何知道基类中的@synchronized
是什么,但未能在其派生词中解析它?
答案 0 :(得分:4)
synchronized
被定义为Synchronized
的类主体中的一个函数。
类主体像函数一样执行以定义类;生成的本地名称空间用于形成类属性。这就是synchronized
在Synchronized
上用作装饰器时go
内的本地名称的原因。您可以将其与定义函数内部的装饰器进行比较,然后尝试将其应用于该函数的外部;它不起作用,因为装饰器是局部变量。
您可以在类@Syncronized.synchronized.im_func
中使用B
(.im_func
从方法包装器中解包该函数):
class B(Synchronized):
@Synchronized.synchronized.im_func
def foo(self):
return 1
更好的是,不要在所有的类中定义装饰器,而是在Synchronized
之外定义它。毕竟,这不是一种方法:
def synchronized(f):
@wraps(f)
def wrapper(self, *args, **kwargs):
with self.lock:
print "here"
return f(self, *args, **kwargs)
return wrapper
class Synchronized(object):
def __init__(self):
self.lock = threading.Lock()
@synchronized
def go(self):
print 1
class B(Synchronized):
@synchronized
def foo(self):
return 1