在Python 2.7中,如何覆盖单个函数的字符串表示?

时间:2015-08-22 14:01:58

标签: python python-2.7

如何在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__(以自定义字符串表示)来获得预期的行为。不过,我很好奇我是否可以获得与常规功能类似的东西。

2 个答案:

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