我希望通过类的实例(而不是继承)使类的属性可以直接访问。所以基本上如果我有:
class A:
@property
def foo(self):
print("foo")
@property
def bar(self):
print("bar")
class B:
def __init__(self):
self._a = A()我不想做b._a.bar,而是希望能够做b.bar。基于this answer here,我在B类中尝试了以下几点:
class B:
def __init__(self):
self._a = A()
attrs = [attr for attr in dir(self._a)
if not callable(self._a.__getattribute__(attr))
and not attr.startswith("__")]
for attr in attrs:
setattr(self.__class__, attr,
property(lambda s: s._a.__getattribute__(attr)))但是,当实例化和测试出来时,我得到了一个奇怪的python时刻:
>>> b = B()
foo
bar
>>> b.foo
bar
>>> b.bar
bar发布于 2018-07-02 12:08:49
创建实例时会打印bar和foo,因为执行_a.__getattribute__("foo")和_a.foo都会调用属性对象来获取值。
在B中设置的两个属性都使用lambda从A获得正确的property。当调用lambda时,这是一个常见的错误。因为attr值是从外部范围继承的,因此在计算lambda时不会冻结它。相反,它只是与封闭作用域的attr引用相同的attr,并进行了相应的更改。因此,所有的lambda都将具有相同的attr值。
您可以定义一个B.__getattr__方法。当普通属性查找失败时,将调用此方法。
class B:
def __init__(self):
self._a = A()
def __getattr__(self, name):
return getattr(self._a, name)
b = B()
b.bar # bar
b.foo # foohttps://stackoverflow.com/questions/51135620
复制相似问题