Возможно ли изменить 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__
функция для данного класса, который в данном случае является встроенным классом функций (types.FunctionType
). Поскольку в Python вы не можете редактировать встроенные классы, только подклассы, вы не можете.
однако, есть два подхода, которые вы могли бы следовать:
- оберните некоторые функции, как предложил kwatford
-
создайте свой собственный протокол представления с собственной функцией 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__
не всегда желательно.