I use following class to define event:
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
I have some model class defined like this:
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)
Now, suppose that I want to change foo
like this:
model = SomeModel()
other_model = SomeModel()
model.fooChanged += other_model.foo
model.foo = 1
After model.foo = 1
, I get following error:
TypeError: 'int' object is not callable
Now, suppose that I use this code for defining model:
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)
and this code to change the value of foo
:
model = SomeModel()
other_model = SomeModel()
model.fooChanged += other_model.set_foo
model.foo = 1
Second version works fine, however, it seems little un-Pythonic to me. I have to define get_foo
method, which I'd like to avoid (since properties are available). Is there some other workaround here, so first version of code could run?
Note: error will depend on self._foo
type. If it's None
, it will return error stating that NoneType
is not callable, if it's string, error will state that str
object is not callable.