我只看到了对于类定义中设置 __repr__
方法的例子。是否可能在函数定义或定义后更改函数的 __repr__
?
我已经尝试过但没有成功...
>>> def f():
pass
>>> f
<function f at 0x1026730c8>
>>> f.__repr__ = lambda: '<New repr>'
>>> f
<function __main__.f>
是的,如果你愿意放弃函数的实际功能,这是可行的。
首先,为我们的新类型定义一个类:
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>'
functools.wraps
来更新被装饰函数的名称和文档字符串,以保持功能不变但更易理解。 - schlamarprint mul42.__name__
会引发一个 AttributeError,这对于一个函数来说是不应该的。因此,解决方法是:return wraps(func)(reprwrapper(reprfun, func))
。 - schlamarupdate_wrapper
稍微更合适/直接。我已经修改了包装器类,使其在构造函数中执行此操作。这样即使您直接使用该类而不是使用withrepr
装饰器,更新也会发生。 - kwatfordrepr(f)
是通过type(f).__repr__(f)
来执行的。__repr__
函数,而在本例中,该类是内置函数类 (types.FunctionType
)。由于在 Python 中您不能编辑内置类,只能对其进行子类化,因此您无法这样做。Create your own representation protocol with your own repr function. For example, you could define a myrepr
function that looks for __myrepr__
methods first, which you cannot add to the function class but you can add it to individual function objects as you suggest (as well as your custom classes and objects), then defaults to repr if __myrepr__
is not found. A possible implementation for this would be:
def myrepr(x):
try:
x.__myrepr__
except AttributeError:
return repr(x)
else:
return x.__myrepr__()
Then you could define __myrepr__
methods and use the myrepr
function. Alternatively, you could also do __builtins__.repr = myrepr
to make your function the default repr
and keep using repr
. This approach would end up doing exactly what you want, though editing __builtins__
may not always be desirable.
这似乎很困难。 Kwatford的方法只部分解决了这个问题,因为它不适用于类中的函数,因为self
会像位置参数一样被处理,如装饰Python类方法 - 如何将实例传递给装饰器?所述 - 然而,那个问题的解决方案不幸的是不适用于这种情况,因为使用__get__()
和functools.partial
会覆盖自定义的__repr__()
。
__repr__
和__call__
方法的类,然后可以像调用函数一样调用它。 - GKFX