我正在使用一个第三方库,该库的某个类的 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>'
,而不是覆盖的表示形式。
有没有办法正确地做到这一点?
谢谢
答案 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)
答案 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