如何为已经实例化的类python覆盖__repr__方法

问题描述 投票:3回答:3

我正在使用第三方库,它对一个类的repr很差,我想在创建该类的实例后覆盖它。

我看到了如何在现有对象中创建绑定方法。

class toy():
    pass

inst= toy()

class inhtoy():
    def __new__(cls,obj):
        def __repr__(self):
            return 'Sucessful'
        import types
        obj.__repr__ = types.MethodType(__repr__,obj)
        return obj

t = inhtoy(inst)

实际上,如果我调用t.repr()它可以工作,但它不会覆盖原始的repr。它看起来像<bound method inhtoy.__new__.<locals>.__repr__ of <__main__.toy object at 0x7f76e0b61f98>>一种本地方法。 调用repr(t)仍然指向原始表示'<__main__.toy object at 0x7f76e0b61f98>'但不是被覆盖的。

有没有办法正确地做到这一点? 谢谢

python attributes new-operator overwrite
3个回答
2
投票

@Nullman的答案是有效的,因为他们的解决方案实际上正在改变类对象toyt是一个实例,而不是实例本身,就像你的方法一样。

特殊属性__class__引用实例所属的类对象。

print(t.__class__ is toy) # True

因此,t.__class__.__repr__ = my_custom_repr__repr__类上分配给toy,而不是t

当比较你的方法和Nullman之间的print(t.__repr__)的输出时,这变得可见。假设模块级函数__repr__看起来像这样:

def __repr__(self):
    return repr(self.__class__)

您的解决方案显示

<bound method __repr__ of <__main__.toy object at 0x00000000029E5A90>>

请注意,它说__main__.toy object。 Nullman的解决方案显示为:

<bound method __repr__ of <class '__main__.toy'>>

当你使用你的方法调用t.__repr__()时,你调用你在实例t上设置的方法,因此它返回你重新调整的内容;你的例子中的字符串Success。 但是,在使用repr()时,类定义输出:

类可以通过定义__repr__()方法来控制此函数为其实例返回的内容。

正如Nullman正确地指出的那样,他们的方法将改变所有现有和未来对象的行为,从toy实例化。

至于奇怪的名称,指定的方法在使用代码时显示:

<bound method inhtoy.__new__.<locals>.__repr__ of <__main__.toy object at 0x7f76e0b61f98>>

......这是来自qualified name特殊属性的函数对象的__qualname__。它是你的类__repr__的方法inhtoy的本地范围的函数__new__。 说到这一点,通过你的inst类的魔术方法__new__传递你的实例inhtoy并没有真正实现。您的代码在功能上等同于:

def __repr__(self):
    return "Success"

inst.__repr__ = types.MethodType(__repr__, obj)

1
投票

经过一些环顾四周,我找到了this的回答。实现它的方法是在一个实例上:

t.__class__.__repr__ = my_custom_repr

请注意,这会更改所有类实例,而不仅仅是此实例


0
投票

您可以使用继承来创建从感兴趣的类派生的新类,然后重写repr方法

class inhtoy(toy):

    def __init__(self):
        toy.__init__(self)

    def __repr__(self):
        # Your repr method
© www.soinside.com 2019 - 2024. All rights reserved.