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

3

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


1
请记住:双下划线函数在类上查找,而非实例。 - Ashwini Chaudhary
2个回答

6
您无法这样做。__str__和__repr__是特殊方法,因此始终在类型上查找,而不是实例。您需要在此处覆盖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__)

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'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接