我对属性进行了子类化,尝试为其添加锁,以便对它的访问是原子的(一次只有一个线程可以读取和写入它)。但我在初始化程序时遇到了错误,并且无法找出原因。
需要明确的是:我不想创建描述符,我希望能够使用@atomic_property装饰器而不是@property
class atomic_property(property):
def __init__(self, func, name=None, doc=None):
self.__name__ = name or func.__name__
self.__module__ = func.__module__
self.__doc__ = doc or func.__doc__
self.func = func
self.lock = threading.Lock()
def __get__(self, obj, objtype=None):
with self.lock:
return self.func(obj)
def __set__(self, obj, value):
with self.lock:
return self.func(obj, value)
这是来自 ipython 的回溯。
In [12]: class a(object):
def __init__(self):
self._b = 1
@utils.atomic_property
def b(self):
return self._b
@b.setter
def b(self, val):
self._b = val
....:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-daec89385bc3> in <module>()
----> 1 class a(object):
2 def __init__(self):
3 self._b = 1
4 @utils.atomic_property
5 def b(self):
<ipython-input-12-daec89385bc3> in a()
5 def b(self):
6 return self._b
----> 7 @b.setter
8 def b(self, val):
9 self._b = val
TypeError: __init__() takes from 2 to 4 positional arguments but 5 were given
最佳答案
您距离使用代码正确子类化 property
还很远:这一次
您重写了一些方法,但从不关心调用上游方法,以便它可以完成其业务。
并不是说不能以这种方式完成,如果您实际上在子类中重现了父类(super class)上的方法将执行的所有行为 - 但即使不查看父类(super class)的代码(在 cPython 的情况下是 native 代码) ) - 我们可以看到 self.func
要么是 getter 函数,要么是 setter 函数 - 不能两者兼而有之。
如果您只关心注释您将使用的属性并执行您想要的操作,并将其余部分委托(delegate)给原始代码,那么它将非常有用 可能只是工作:
class atomic_property(property):
def __init__(self,*args, **kw):
super(atomic_property, self).__init__(*args, **kw)
self.lock = threading.Lock()
def __get__(self, obj, obj_type):
with self.lock:
return super(atomic_property, self).__get__(obj, objtype)
def __set__(self, obj, value):
with self.lock:
return super(atomic_property, self).__set__(obj, value)
关于python - 子类化属性在 __init__ 上引发 TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37927612/