可以在python中更改函数的repr吗?

bea*_*rdc 14 python function repr

我只看过__repr__在类定义中设置方法的示例.是否__repr__可以在定义中或定义后更改for函数?

我试图没有成功......

>>> def f():
    pass
>>> f
<function f at 0x1026730c8>
>>> f.__repr__ = lambda: '<New repr>'
>>> f
<function __main__.f>
Run Code Online (Sandbox Code Playgroud)

kwa*_*ord 17

是的,如果你愿意放弃功能实际上是一个功能.

首先,为我们的新类型定义一个类:

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)
Run Code Online (Sandbox Code Playgroud)

添加装饰器功能:

def withrepr(reprfun):
    def _wrap(func):
        return reprwrapper(reprfun, func)
    return _wrap
Run Code Online (Sandbox Code Playgroud)

现在我们可以定义repr和函数:

@withrepr(lambda x: "<Func: %s>" % x.__name__)
def mul42(y):
    return y*42
Run Code Online (Sandbox Code Playgroud)

现在repr(mul42)生产'<Func: mul42>'

  • 请使用`functools.wraps`为装饰器更新装饰函数的名称和文档字符串. (3认同)

JBe*_*rdo 6

没有,因为repr(f)作为做type(f).__repr__(f)代替.


小智 5

为此,您需要更改__repr__给定类的函数,在本例中为内置函数类 ( types.FunctionType)。因为在 Python 中你不能编辑内置类,只能对它们进行子类化,所以你不能。

但是,您可以遵循两种方法:

  1. 按照 kwatford 的建议包装一些函数
  2. 使用您自己的 repr 函数创建您自己的表示协议。例如,您可以定义一个首先myrepr查找__myrepr__方法的函数,您不能将其添加到函数类,但您可以按照您的建议将其添加到各个函数对象(以及您的自定义类和对象),然后默认为 repr if__myrepr__没有找到。一个可能的实现是:

    def myrepr(x):
      try:
        x.__myrepr__
      except AttributeError:
        return repr(x)
      else:
        return x.__myrepr__()
    
    Run Code Online (Sandbox Code Playgroud)

    然后您可以定义__myrepr__方法并使用该myrepr函数。或者,您也可以将__builtins__.repr = myrepr您的函数设置为默认函数repr并继续使用repr. 这种方法最终会完全按照您想要的方式进行,尽管编辑__builtins__可能并不总是令人满意。