我正在使用第三方库,它对一个类的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>'
但不是被覆盖的。
有没有办法正确地做到这一点? 谢谢
@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()
时,类定义输出:
类可以通过定义
__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)
您可以使用继承来创建从感兴趣的类派生的新类,然后重写repr方法
class inhtoy(toy):
def __init__(self):
toy.__init__(self)
def __repr__(self):
# Your repr method