在修改其任何属性时,是否有一些通用方法可以使类运行函数?我想知道是否可以运行一些子进程来监视对该类的更改,但是也许有一种方法可以继承class
并修改属于Python类的一部分on_change
函数,有点像可以修改类的默认__repr__
方法。什么是明智的选择呢?
实际的应用程序不只是打印输出,而是更新数据库中与实例化类的数据属性相对应的条目。
#!/usr/bin/env python
class Event(object):
def __init__(self):
self.a = [10, 20, 30]
self.b = 15
#def _on_attribute_change(self):
# print(f'attribute \'{name_of_last_attribute_that_was_changed}\' changed')
event = Event()
event.a[1] = 25
# printout should happen here: attribute 'a' changed
event.a.append(35)
# printout should happen here: attribute 'a' changed
event.c = 'test'
# printout should happen here: attribute 'c' changed
答案 0 :(得分:2)
您可以覆盖__setattr__
魔术方法。
class Foo:
def on_change(self):
print("changed")
def __setattr__(self, name, value):
self.__dict__[name] = value
self.on_change()
答案 1 :(得分:1)
您可以覆盖__setattr__
。
class Event:
def __init__(self):
self.a = [10, 20, 30]
self.b = 15
def __setattr__(self, attr, value):
print(f'attribute {attr} changed')
super().__setattr__(attr, value)
但是,这仅检测到直接 分配给该属性。 event.a[1] = 25
是对event.a.__setitem__(1, 25)
的调用,因此Event
对此一无所知。由event.a
解析的任何值完全处理。
如果您不希望__init__
中的分配触发通知,请直接致电super().__setattr__
以避免调用您的替代。
def __init__(self):
super().__setattr__('a', [10, 20, 30])
super().__setattr(__('b', 15)
答案 2 :(得分:1)
最近我在python上开发了服务器端,我不得不检测列表/字典/所需内容上的更改,挽救了我生命的库是traits
。我强烈推荐它。您可以轻松检查属性中已更改/删除/添加的内容。
您可以阅读更多here。
具体针对您的情况,notification这一章最相关
这是我刚运行的一小段代码:
from traits.api import *
class DataHandler(HasTraits):
a = List([10, 20, 30])
b = Int(15)
class Event(HasTraits):
def __init__(self):
super().__init__()
self.data_handler = DataHandler()
self.data_handler.on_trait_change(Event._anytrait_changed)
@staticmethod
def _anytrait_changed(obj, name, old, new):
is_list = name.endswith('_items')
if is_list:
name = name[0:name.rindex('_items')]
current_val = getattr(obj, name)
if is_list:
# new handles all the events(removed/changed/added to the list)
if any(new.added):
print("{} added to {} which is now {}".format(new.added, name, current_val))
if any(new.removed):
print("{} removed from {} which is now {}".format(new.removed, name, current_val))
else:
print('The {} trait changed from {} to {} '.format(name, old, (getattr(obj, name))))
e = Event()
e.data_handler.b = 13
e.data_handler.a.append(15)
e.data_handler.a.remove(15)
e.data_handler.a.remove(20)
输出:
The b trait changed from 15 to 13
[15] added to a which is now [10, 20, 30, 15]
[15] removed from a which is now [10, 20, 30]
[20] removed from a which is now [10, 30]
希望这会有所帮助。