Python 如何跳过inspect.getmembers中的缓存属性
我有一个python类Foo,它将观察者注册到可观察对象。 我有几个类继承自Foo并填充观察者列表,每个类都有不同的观察者 由于与当前设计相关的原因,观察者列表在每个派生类\uuuu init\uuuuuuuuuuu中显式初始化,并且不能移动到可重写的方法(将从基类\uuuu init\uuuuuuuuuuu调用)。 因此,我无法在构造函数中调用observable.RegisterObserver(因为观察者列表尚未填充) 为了确保观察员已注册,我创建了observable as cached属性。通过这种方式,我可以保证,没有人会在不先注册观察员的情况下直接进入现场 对my_observable的第一次调用应该发生在init完成之后。 问题是在基类init的末尾有一个inspect.getmembers调用。 inspect.getmembers()使用getattr,并以此计算缓存的\u属性 如果不满足某些条件(即,我们仍在初始化中),我尝试抛出AttributeError,但我不喜欢这种解决方案,如果有人以不同的方式实现派生类,它将失败。 有没有办法告诉inspect跳过缓存属性? 也可以使用可信的方法来判断init(派生类)是否完成 伪代码:Python 如何跳过inspect.getmembers中的缓存属性,python,Python,我有一个python类Foo,它将观察者注册到可观察对象。 我有几个类继承自Foo并填充观察者列表,每个类都有不同的观察者 由于与当前设计相关的原因,观察者列表在每个派生类\uuuu init\uuuuuuuuuuu中显式初始化,并且不能移动到可重写的方法(将从基类\uuuu init\uuuuuuuuuuu调用)。 因此,我无法在构造函数中调用observable.RegisterObserver(因为观察者列表尚未填充) 为了确保观察员已注册,我创建了observable as cached
class Foo(object):
def __init__(self):
self._observers = []
for _, member in inspect.getmembers(self):
# do something with member
continue
@cached_property
def my_observable:
observable = Observable()
observable.RegisterObservers(self._observers)
return observable
class Bar(Foo):
def __init__(self):
super(Bar, self).__init__()
self._observers = [MyObserver()]
找到了解决我问题的办法。 它并没有解决inspect.getmembers评估我的缓存属性的问题,但它实际上以更好的方式解决了设计问题 我将定义一个元类,它将覆盖调用,并调用类上的特定方法。 在元类中重写调用允许我们在返回新实例之前注入该步骤 所以它看起来像这样:
class MyMetaClass(type):
def __call__(cls, *args, **kwargs):
"""Called when the object is initialized."""
obj = type.__call__(cls, *args, **kwargs)
obj.FinalizeInit()
return obj
class Foo(object):
__metaclass__ = MyMetaClass
def __init__(self):
self._observers = []
for _, member in inspect.getmembers(self):
# do something with member
continue
self._observable = None
def FinalizeInit(self):
self._observable = Observable()
self._observable.RegisterObservers(self._observers)
在
\uuuu init\uuuu
中使用一个标志怎么样?例如,最后将initialized
设置为True
,我考虑过了,但是派生类将调用super的init,然后才执行自己的init。。所以这个标志应该在派生类init中设置…我认为,为了防止通过硬编码实现错误,格式良好的文档更有用。。。由于您的用户也是程序员,他们应该正确地实现派生类。