在 Python 中获取 class 变量时调用了哪些魔术方法?

Which magic methods are called when getting a class variable in Python?

我正在努力思考 __getattribute____getattr__ 在 Python 中如何针对未实例化的 classes 和 subclassing 工作.具体来说,我想在超级 class 中捕获一个 getattribute 调用并可能相应地修改它。

在下面的代码片段中,我预计在调用任何方法时至少有 一些 中间打印语句,但我什么也没得到。找到并返回 class 变量,但似乎调用了 none 魔术方法。这是为什么?

class SuperbClass:
    def __getattribute__(self, attr):
        print(f"called in superb, found {attr}")
        # get the attribute via `object`
        return f"{super(SuperbClass, self).__getattribute__(attr)}MODIFIED_IN_SUPER"

    def __getattr__(self, attr):
        self.__getattribute__(attr)

class SubberClass(SuperbClass):
    MyClassVar = "I am a cool message"

    def __getattribute__(self, attr):
        print("called in subber")
        super(SuperbClass, self).__getattribute__(attr)

    def __getattr__(self, attr):
        self.__getattribute__(attr)


if __name__ == '__main__':
    print(SubberClass.MyClassVar)
    # Only prints `I am a cool message`
    inst = SubberClass()
    print(inst.MyClassVar)
    # prints called in subber
    # and prints None

编辑:更新代码以反映 class 和实例

之间的区别

A​​ class 的 __getattribute____getattr__ 处理 class 的 实例 的属性解析。如果要为 class 本身处理属性解析,则需要在 class 的 上定义 __getattribute____getattr__ class:它的元class.

class Meta(type):
    def __getattribute__(self, attr):
        print('*This* prints.')
        return super().__getattribute__(attr)

class Blah(metaclass=Meta):
    MyClassVar = 'blah'

if __name__ == '__main__':
    Blah.MyClassVar