【问题标题】:Why doesn't str() use __getattribute__ to get __str__ and how to produce the effect?为什么 str() 不使用 __getattribute__ 来获取 __str__ 以及如何产生效果?
【发布时间】:2020-08-03 11:04:06
【问题描述】:

当我在具有重载__getattribute__ 方法的对象上调用str() 时,它似乎没有使用它,而是直接调用__str__。是否有其他一些我应该修改的功能或让它使用__getattribute__ 的方法?如果我直接重载__str__,它会按预期运行,但这并不适合我的需求。

class A(object):
    def __getattribute__(self, attr):
        if attr == "__str__":
            return lambda: "Hello"
        return object.__getattribute__(self, attr)

x = A()

print(x)
print(str(x))
print(x.__str__())

输出:
ma​​in.A 对象位于 0x000001FDF7AEA760>
ma​​in.A 对象位于 0x000001FDF7AEA760>
你好

预期输出:
你好
你好
你好

【问题讨论】:

    标签: python python-3.x getattribute python-datamodel


    【解决方案1】:

    是的,这是documented behavior

    在查找特殊方法时,仍可能会绕过此方法 通过语言语法或内置的隐式调用的结果 功能。

    还有here

    对于自定义类,特殊方法的隐式调用仅 如果在对象的类型上定义,则保证正常工作,而不是在 对象的实例字典

    ...

    除了绕过任何实例属性之外 正确性,隐式特殊方法查找一般也会绕过 对象元类的__getattribute__() 方法...

    ...

    至于为什么

    以这种方式绕过__getattribute__() 机器可以提供 口译员的速度优化空间很大,在 处理特殊方法的一些灵活性的成本( 必须在类对象本身上设置特殊方法才能 解释器始终调用)。

    【讨论】:

    • 非常感谢!这是一个很好的解释!这是否意味着唯一合理的方法是重载__str__ 以及我想以这种方式实现的任何其他特殊方法?
    • @RedKnite 是的,就是这个意思。