Python在类定义之外覆盖__str__

时间:2018-10-06 17:12:04

标签: python class

说我有一个导入的模块可以正常工作,但是不能提供好的__str__方法,我想添加一个模块。

以某种混合语言:

from foo import Foo

Foo.prototype._str__ = function myNIcePrintFunction(){

}

请问如何在Python中执行此操作?

2 个答案:

答案 0 :(得分:5)

您可以先定义一个函数,然后对其进行猴子修补。

赞:

def foostr(self):
    return 'A foo str'

Foo.__str__ = foostr

或带有 lambda表达式

Foo.__str__ = lambda self: 'Another foo str'

但是,此方法将具有不同的Foo.__str__.__name__等,这一点之间的差别很小。但是str(..)内置函数将按预期工作。正如@chepner所说,我们可以使用wrap中的functools函数来保留大多数元数据:

from functools import wraps

def foostr(self):
    return 'A foo str'

Foo.__str__ = wraps(Foo.__str__)(foostr)

但是随后Foo.__str__.__qualname__会导致'superfoo.__str__'superfoo是{{1}的方法解析顺序(MRO)中的第一类) }实现了Foo)。

例如:

__str__

如果您可以访问>>> class Foo: ... pass ... >>> str(Foo()) '<__main__.Foo object at 0x7f807046e668>' >>> Foo.__str__ = lambda self: 'another Foo str' >>> str(Foo()) 'another Foo str' 类的实现,那么最好只在该类中定义一个Foo函数,而不要稍后对其进行 monkey patch 在此过程中。

答案 1 :(得分:1)

您可以在保持原始功能的同时覆盖此类的任何类函数:

class a():
    pass

def monkey(fn):
    def newfn(self,*args, **kw):
        print('hijacked!')
        return fn(self,*args, **kw)
    return newfn

a.__str__ = monkey(a.__str__)


b = a()

print(str(b))

>>> hijacked!                                                                                                                                                                            
>>> <__main__.a object at 0x7f61f19faa58>