22

我只看到了__repr__在类定义中设置方法的示例。是否可以在定义中或定义后更改__repr__for 函数?

我试过没有成功...

>>> def f():
    pass
>>> f
<function f at 0x1026730c8>
>>> f.__repr__ = lambda: '<New repr>'
>>> f
<function __main__.f>
4

4 回答 4

26

是的,如果你愿意放弃实际上是一个函数的函数。

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

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>'

于 2012-06-04T01:52:58.307 回答
9

不,因为repr(f)是这样做的type(f).__repr__(f)

于 2012-06-04T01:44:06.510 回答
5

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

但是,您可以采用两种方法:

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

    def myrepr(x):
      try:
        x.__myrepr__
      except AttributeError:
        return repr(x)
      else:
        return x.__myrepr__()
    

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

于 2012-06-04T07:56:32.893 回答
1

这似乎很难。Kwatford 的方法仅部分解决了这个问题,因为它不适用于类中的函数,因为它self会被视为位置参数,如装饰 Python 类方法中所述 - 如何将实例传递给装饰器?- 但是,不幸的是,该问题的解决方案不适用于这种情况,因为使用__get__()andfunctools.partial会覆盖 custom __repr__()

于 2021-04-04T11:55:57.767 回答