我已经将子属性设置为尝试向其添加锁定,因此对它的访问是原子的(一次只有一个线程可以读取和写入)。但我在初始化程序中遇到错误,无法找出原因。
要明确:我不想创建描述符,我希望能够使用@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
答案 0 :(得分:2)
你远没有用你的代码正确地继承property
:一次
你重写了一些方法,但从不关心调用上游方法,以便它可以开展业务。
不是说不能这样做,如果你真的在你的子类中重现超类上的方法将执行的所有行为 - 但即使不查看超类的代码(在cPython的情况下是在本机代码中) ) - 可以看出self.func
是getter函数,或者它是setter函数 - 它不能同时存在。
如果你只是想注释你将使用的属性并执行你想要的动作,并将余数委托给原始代码,它将非常 可能只是工作:
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)
答案 1 :(得分:1)
似乎使用x = linspace(0, 1, 20);
y = x;
i_cell = {1:6, 7:11, 12:20};
for i = 1:length(i_cell)
figure
indices = i_cell{i}
plot(x(indices), y(indices))
end
再次调用property.setter
,这似乎很奇怪(多次初始化同一个对象?)
无论如何,您需要让__init__
完成它的工作,如果您根本不使用property
,您认为它如何正常工作?你可以做这样的事情,例如:
property.__init__