Возможно ли изменить repr функции в python?

Я видел только примеры для настройки __repr__ метод определения класса. Можно ли изменить __repr__ для функций либо в их определениях, либо после их определения?

Я попытался без успеха...

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

3 ответов


да, если вы готовы отказаться от функции, фактически являясь функцией.

во-первых, определить класс для нашего нового типа:

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


нет, потому что repr(f) делается type(f).__repr__(f) вместо.


для этого вам нужно будет изменить __repr__ функция для данного класса, который в данном случае является встроенным классом функций (types.FunctionType). Поскольку в Python вы не можете редактировать встроенные классы, только подклассы, вы не можете.

однако, есть два подхода, которые вы могли бы следовать:

  1. оберните некоторые функции, как предложил kwatford
  2. создайте свой собственный протокол представления с собственной функцией repr. Например, вы может определить ищет __myrepr__ сначала методы, которые вы не можете добавить в класс функций, но вы можете добавить его в отдельные объекты функций, как вы предлагаете (а также ваши пользовательские классы и объекты), а затем по умолчанию repr if __myrepr__ не нашел. Возможной реализацией для этого будет:

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

    тогда вы можете определить __myrepr__ методы и использовать . Кроме того, вы также можете сделать __builtins__.repr = myrepr чтобы сделать вашу функцию по умолчанию repr и repr. Этот подход в конечном итоге будет делать именно то, что вы хотите, хотя редактирование __builtins__ не всегда желательно.