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

时间:2012-06-04 01:36:50

标签: python function repr

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

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

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

4 个答案:

答案 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中你不能编辑内置类,只能将它们子类化,你不能。

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

  1. 以kwatford建议的方式包含一些功能
  2. 使用您自己的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__()