简体   繁体   English

Python在类定义之外覆盖__str__

[英]Python override __str__ outside of class definition

Say I have a module that I've imported that works fine but doesn't provide a good __str__ method and I want to add one. 假设我有一个导入的模块可以正常工作,但是不能提供良好的__str__方法,我想添加一个。

In some hybrid language: 用某种混合语言:

from foo import Foo

Foo.prototype._str__ = function myNIcePrintFunction(){

}

How do I do this please in Python please? 请问如何在Python中执行此操作?

You can first define a function, and then monkey-patch it. 您可以先定义一个函数,然后再对其进行猴子修补。

Like: 喜欢:

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

Foo.__str__ = foostr

Or with a lambda expression : 或使用lambda表达式

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

There is however a small difference in the fact that this method will have a different Foo.__str__.__name__ , etc. But the str(..) builtin function will work as expected. 但是,此方法将具有不同的Foo.__str__.__name__等,这一事实之间存在很小的差异。但是str(..)内置函数将按预期工作。 As @chepner says, we can use the wrap function from functools to preserve most meta-data: 正如@chepner所说,我们可以使用functoolswrap函数来保留大多数元数据:

from functools import wraps

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

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

But then Foo.__str__.__qualname__ will for example result in 'superfoo.__str__' (with superfoo the first class in the method resolution order (MRO) of Foo that implemented __str__ ). 但随后Foo.__str__.__qualname__例如将导致'superfoo.__str__' (与superfoo中的方法解析顺序(MRO)第一类Foo该实施__str__ )。

For example: 例如:

>>> class Foo:
...   pass
... 
>>> str(Foo())
'<__main__.Foo object at 0x7f807046e668>'
>>> Foo.__str__ = lambda self: 'another Foo str'
>>> str(Foo())
'another Foo str'

If you have access to the implementation of the Foo class, it is however better to just define a __str__ function in the class, and not monkey patch it later in the process. 如果您可以访问Foo类的实现,则最好只在该类中定义__str__函数,而不是稍后在过程中进行猴子补丁

You can override any class function like this, while maintaining the original functionalities: 您可以覆盖这样的任何类函数,同时保留原始功能:

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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM