我只看过在类定义中设置__repr__
方法的示例。是否可以在定义中或定义函数后更改__repr__
函数?
我试图没有成功......
>>> def f():
pass
>>> f
<function f at 0x1026730c8>
>>> f.__repr__ = lambda: '<New repr>'
>>> f
<function __main__.f>
答案 0 :(得分:16)
是的,如果你愿意放弃功能实际上是一个功能。
首先,为我们的新类型定义一个类:
import functools
class reprwrapper(object):
def __init__(self, repr, func):
self._repr = repr
self._func = func
functools.update_wrapper(self, func)
def __call__(self, *args, **kw):
return self._func(*args, **kw)
def __repr__(self):
return self._repr(self._func)
添加装饰器功能:
def withrepr(reprfun):
def _wrap(func):
return reprwrapper(reprfun, func)
return _wrap
现在我们可以定义repr以及函数:
@withrepr(lambda x: "<Func: %s>" % x.__name__)
def mul42(y):
return y*42
现在repr(mul42)
生成'<Func: mul42>'
答案 1 :(得分:6)
不,因为repr(f)
代替了type(f).__repr__(f)
。
答案 2 :(得分:4)
为了做到这一点,你需要更改给定类的__repr__
函数,在本例中是内置函数类(types.FunctionType
)。因为在Python中你不能编辑内置类,只能将它们子类化,你不能。
但是,您可以遵循以下两种方法:
使用您自己的repr函数创建自己的表示协议。例如,您可以定义一个myrepr
函数,该函数首先查找__myrepr__
方法,您无法将其添加到函数类中,但可以按照建议将其添加到单个函数对象(以及您的自定义)类和对象),如果找不到__myrepr__
,则默认为repr。可能的实现方式是:
def myrepr(x):
try:
x.__myrepr__
except AttributeError:
return repr(x)
else:
return x.__myrepr__()
然后您可以定义__myrepr__
方法并使用myrepr
函数。或者,您也可以__builtins__.repr = myrepr
使您的函数成为默认值repr
并继续使用repr
。虽然编辑__builtins__
可能并不总是可取的,但这种方法最终会完全符合您的要求。
答案 3 :(得分:1)
这似乎很难。 Kwatford 的方法仅部分解决了这个问题,因为它不适用于类中的函数,因为 self
将被视为位置参数,如 Decorating Python class methods - how do I pass the instance to the decorator? 中所述 - 但是,该问题的解决方案不适用不幸的是,对于这种情况,使用 __get__()
和 functools.partial
会覆盖自定义 __repr__()
。