从父类方法访问子类属性

时间:2021-04-01 10:19:17

标签: python python-3.x inheritance

我试图让下面的代码背后的想法起作用,也就是说,让一个父类定义一堆方法,这些方法使用 __class__ 访问静态属性,这些属性在子类中定义。然而,我天真的尝试会引发 AttributeError,因为当我调用 son.fun() 时,它会在 bar 中查找 ParentParent 永远不需要自己实例化,也不需要支持菱形继承模式。

class Parent:    
    def fun(self):
        print(__class__.bar)
    
class Daughter(Parent):
    bar = 2.71

class Son(Parent):
    bar = 3.14
    

daughter = Daughter()
son = Son()

son.fun()  # AttributeError: type object 'Parent' has no attribute 'bar'

在我的代码库中,我有两个看起来像 DaughterSon 的类,它们有自己的 fun 版本。类似的东西:

class Daughter:
    bar = 2.71

    def fun(self):
        print(__class__.bar)

class Son:
    bar = 3.14

    def fun(self):
        print(__class__.bar)

daughter = Daughter()
son = Son()

son.fun()  # All good

这可行,但它引入了大量代码重复,这些重复只会随着我添加更多类而增加。当前的实现要求我每次想要调整 fun 时都修改所有类,我觉得必须有更好的方法。

我想通过添加 ParentSon 中定义的属性来修改 Daughter去做吧。

2 个答案:

答案 0 :(得分:0)

您可以通过 __class__ 访问 self 属性 - 这将解析为 Son 类并获取属性:

class Parent:
    def fun(self):
        print(self.__class__.bar)


class Daughter(Parent):
    bar = 2.71


class Son(Parent):
    bar = 3.14


daughter = Daughter()
son = Son()

son.fun()
daughter.fun()

打印:

3.14
2.71

答案 1 :(得分:0)

>>> class Parent:
    def fun(self):
        print(__class__.bar)
...
>>> class Son(Parent):
    bar = 3.14
...
>>> son = Son()
>>> son.__dict__
{}
>>> Son.__dict__
mappingproxy({'__module__': '__main__', 'bar': 3.14, '__doc__': None})
>>> son.__class__ is Son
True
>>> Parent.__dict__
mappingproxy({'__module__': '__main__', 'fun': <function Parent.fun at 0x102483dc0>, '__dict__': <attribute '__dict__' of 'Parent' objects>, '__weakref__': <attribute '__weakref__' of 'Parent' objects>, '__doc__': None})
>>>

类实例具有 __dict__ 属性,用于存储实例的属性。

当您执行 son.bar 时,Python 会尝试在 bar 中查找属性 son.__dict__。如果在那里找不到它,它会查看 son.__class__.__dict__。如果在那里找不到它,它会尝试在父母的 __dict__ 中找到该属性。

相关问题