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

时间:2019-04-30 10:18:14

标签: python attributes new-operator overwrite

我正在使用一个第三方库,该库的某个类的 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>',而不是覆盖的表示形式。

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

4 个答案:

答案 0 :(得分:2)

@Nullman的答案行之有效,因为他们的解决方案实际上是在更改类对象toy,就像您的方法一样,t是实例的实例,而不是实例本身。

特殊属性__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()时, class 定义输出:

  

一个类可以通过以下方法控制此函数为其实例返回的内容   定义一个__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 :(得分:1)

经过四处环顾,我发现了this的答案。在活动实例上执行此操作的方法是:

t.__class__.__repr__ = my_custom_repr

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

答案 2 :(得分:0)

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

class inhtoy(toy):

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

    def __repr__(self):
        # Your repr method

答案 3 :(得分:0)

使用子类并将其分配给实例,您可以像这样从库中获取:

class Toy():
    pass
inst = Toy()  # from 3rd party library

class Toy_MyRepr(Toy):
    def __repr__(self):
        return '<my repr of Toy instance >'

inst.__class__ = Toy_MyRepr