首页 > 解决方案 > 不明白为什么点表示法不适用于组合对象

问题描述

这是我正在尝试的

# This is how I understood composition to work
class A():
    def __init__(self):
        self.attr1 = ''
        self.attr2 = 0
        self.attr3 = ''

    def some_update(self, newval):
        self.attr3 = newval

class B():
    def __init__(self):
        self.attr4 = ''
        self.sub1 = A()
    self.sub2 = A()
        self.sub2.attr1 = subspecialval

    def different_update(self, newval1, newval2)
        self.sub1.attr2 = newval1
        self.sub2.attr2 = newval2

def __main__():
    my_obj = B()
    B.sub1.attr = 'some string'               # This doesn't work
    setattr(B, 'sub1.attr1', 'some string')   # This works
    print(B.sub1.attr1)                       # This doesn't work
    print(getattr(B, 'sub1.attr1'))           # This works

if __name__ == '__main__':
    main()

问题是,为什么点符号不能扩展到组合类(B),但 getattr/setattr 能够正确协商类层次结构?我假设每个点都会延伸到层次结构中的下一个对象级别,但它似乎不是那样工作的

标签: pythonclasshierarchycomposition

解决方案


getattr/setattr 能够正确协商类层次结构吗?

它不是。

setattr(B, 'sub1.attr1', 'some string')设置文字属性'sub1.attr1'。没有任何东西被遍历或协商。

请记住,您是在类 ( B) 而不是实例 ( my_obj) 上设置属性。my_obj.sub1.attr本来可以的。

class A:
    def __init__(self):
        self.attr2 = ''

class B:
    def __init__(self):
        self.a = A()


B.a.attr1 = ''

AttributeError: type object 'B' has no attribute 'a'

另一方面,

b = B()
b.a.attr1 = 'attr1'
print(b.a.attr1)

作品。


setattr(B, 'a.attr1', 'new')做什么?

'a.attr1它在B 本身上设置文字属性。没有任何东西被遍历或协商。

setattr(B, 'a.attr1', 'new')
print(B.__dict__)

输出

{'__module__': '__main__', '__init__': <function B.__init__ at 0x00000188F1EB9F28>, 
 '__dict__': <attribute '__dict__' of 'B' objects>, 
 '__weakref__': <attribute '__weakref__' of 'B' objects>, '__doc__': None, 
 'a.attr1': 'new'}

推荐阅读