我使用以下类来定义事件:
class Event(object):
def __init__(self):
self.handlers = set()
def handle(self, handler):
self.handlers.add(handler)
return self
def unhandle(self, handler):
try:
self.handlers.remove(handler)
except:
raise ValueError("Handler is not handling this event, so cannot unhandle it.")
return self
def fire(self, *args, **kwargs):
for handler in self.handlers:
print(handler)
handler(*args, **kwargs)
def getHandlerCount(self):
return len(self.handlers)
__iadd__ = handle
__isub__ = unhandle
__call__ = fire
__len__ = getHandlerCount
我有一些模型类定义如下:
class SomeModel(object):
def __init__(self):
self._foo = 0
self.fooChanged = Event()
@property
def foo(self):
return self._foo
@foo.setter
def foo(self, value):
self._foo = value
self.fooChanged(value)
现在,假设我想这样改变foo
:
model = SomeModel()
other_model = SomeModel()
model.fooChanged += other_model.foo
model.foo = 1
在model.foo = 1
之后,我得到以下错误:
TypeError: 'int' object is not callable
现在,假设我使用以下代码来定义模型:
class SomeModel(object):
def __init__(self):
self._foo = 0
self.fooChanged = Event()
def get_foo(self):
return self._foo
def set_foo(self, value):
self._foo = value
self.fooChanged(value)
foo = property(get_foo, set_foo)
下面的代码更改foo
的值:
model = SomeModel()
other_model = SomeModel()
model.fooChanged += other_model.set_foo
model.foo = 1
第二个版本的作品很好,但它似乎有点不Python我。我必须定义get_foo
方法,这是我想要避免的(因为属性是可用的)。这里是否有其他解决方法,以便可以运行第一个版本的代码?你知道吗
注意:错误取决于self._foo
类型。如果是None
,则返回错误,指出NoneType
不可调用;如果是字符串,则返回错误,指出str
对象不可调用。你知道吗
经过大量的挖掘,我发现这个answer非常有用,它把我推向了正确的方向。你知道吗
利用这些知识,我能够通过以下方法解决这个问题:
或者
后一行在我看来更像python,因为没有调用双下划线函数。你知道吗
当您编写
model.fooChanged += other_model.foo
时,我想您实际上想要的是它的setter方法,但是由于other_model.foo
是一个property object,您必须从它的类other_model.__class__.foo.fset
中获取,编写为:奥托,我觉得你的第二个版本对我来说很像Python,比如:
相关问题 更多 >
编程相关推荐