如何在Python中覆盖单个函数的字符串表示形式?
我尝试过:
>>> def f(): pass
...
>>> f
<function f at 0x7f7459227758>
>>> f.__str__ = lambda self: 'qwerty'
>>> f
<function f at 0x7f7459227758>
>>> f.__repr__ = lambda self: 'asdfgh'
>>> f
<function f at 0x7f7459227758>
>>> f.__str__(f)
'qwerty'
>>> f.__repr__(f)
'asdfgh'
我知道我可以通过创建一个带有__call__
的类(使其看起来像一个函数)和__str__
(以自定义字符串表示)来获得预期的行为。不过,我很好奇我是否可以获得与常规功能类似的东西。
答案 0 :(得分:6)
你不能。 __str__
和__repr__
是特殊方法,因此是always looked up on the type,而不是实例。您必须在此处覆盖type(f).__repr__
,但这将适用于所有功能。
然后,唯一可行的选择是使用带有__call__
方法的包装器对象:
def FunctionWrapper(object):
def __init__(self, callable):
self._callable = callable
def __call__(self, *args, **kwargs):
return self._callable(*args, **kwargs)
def __repr__(self):
return '<custom representation for {}>'.format(self._callable.__name__)
答案 1 :(得分:3)
正如MartijnPieters所解释的那样,如果不通过课程,你就无法做到。但是你可以轻松地编写一个完全隐藏了复杂性的装饰器:
from functools import update_wrapper
class _CustomReprFunc(object):
def __init__(self, fn, repr_):
self.fn = fn
self.repr = repr_
update_wrapper(self, fn)
def __repr__(self):
return self.repr
def __call__(self, *args, **kwargs):
return self.fn(*args, **kwargs)
def custom_repr(repr_):
def decorator(fn):
return _CustomReprFunc(fn, repr_)
return decorator
用法:
@custom_repr('foobar')
def foo():
"""foo function"""
return 'bar'