简体   繁体   English

如何更改Python函数的表示?

[英]How do I change the representation of a Python function?

>>> def hehe():
...     return "spam"
... 
>>> repr(hehe)
'<function hehe at 0x7fe5624e29b0>'

I want to have: 我希望有:

>>> repr(hehe)
'hehe function created by awesome programmer'

How do I do that? 我怎么做? Putting __repr__ inside hehe function does not work. __repr__放在hehe函数中是行不通的。

EDIT: 编辑:

In case you guys are wondering why I want to do this: 如果你们想知道我为什么要这样做:

>>> defaultdict(hehe)
defaultdict(<function hehe at 0x7f0e0e252280>, {})

I just don't like the way it shows here. 我只是不喜欢它在这里显示的方式。

No, you cannot change the representation of a function object; 不,您无法更改函数对象的表示形式; if you wanted to add documentation , you'd add a docstring: 如果你想添加文档 ,你需要添加一个文档字符串:

def foo():
    """Frob the bar baz"""

and access that with help(foo) or print foo.__doc__ . 并使用help(foo)print foo.__doc__访问它。

You can create a callable object with a custom __repr__ , which acts just like a function: 可以使用自定义__repr__创建一个可调用对象,该函数就像一个函数:

class MyCallable(object):
    def __call__(self):
        return "spam"
    def __repr__(self):
        return 'hehe function created by awesome programmer'

Demo: 演示:

>>> class MyCallable(object):
...     def __call__(self):
...         return "spam"
...     def __repr__(self):
...         return 'hehe function created by awesome programmer'
... 
>>> hehe = MyCallable()
>>> hehe
hehe function created by awesome programmer
>>> hehe()
'spam'

Usually, when you want to change something about the function, say function signature, function behavior or function attributes, you should consider using a decorator. 通常,当您想要更改有关函数的内容时,比如函数签名,函数行为或函数属性,您应该考虑使用装饰器。 So here is how you might implement what you want: 所以这是你如何实现你想要的:

class change_repr(object):
    def __init__(self, functor):
        self.functor = functor

        #  lets copy some key attributes from the original function
        self.__name__ = functor.__name__
        self.__doc__ = functor.__doc__

    def __call__(self, *args, **kwargs):
        return self.functor(*args, **kwargs)

    def __repr__(self):
        return '<function %s created by ...>' % self.functor.__name__


@change_repr
def f():
    return 'spam'


print f()  # spam
print repr(f)  # <function hehe created by ...>

Note, that you can only use class based decorator, since you need to override __repr__ method, which you can't do with a function object. 请注意,您只能使用基于类的装饰器,因为您需要覆盖__repr__方法,而您无法使用函数对象。

Not directly the answer to your question, but perhaps you really want a docstring? 不直接回答你的问题,但也许你真的想要一个docstring?

>>> def hehe():
...  '''hehe function created by awesome programmer'''
...  return 'spam'
...
>>> help(hehe)
Help on function hehe in module __main__:

hehe()
    hehe function created by awesome programmer

Here's a slightly more flexible version of what's in Alexander Zhukov's answer : 这是亚历山大·朱可夫答案中的一个稍微灵活的版本:

def representation(repr_text):
    class Decorator(object):
        def __init__(self, functor):
            self.functor = functor

        def __call__(self, *args, **kwargs):
            return self.functor(*args, **kwargs)

        def __repr__(self):
            return (repr_text % self.functor.__name__ if '%' in repr_text
                    else repr_text)

    return Decorator

from collections import defaultdict

@representation('<function %s created by awesome programmer>')
def f():
    return list

dd = defaultdict(f)
print repr(dd)

Output: 输出:

defaultdict(<function f created by awesome programmer>, {})

Since representation() returns a decorator, if you wanted the same boilerplate on several functions you could do something like this: 由于representation()返回一个装饰器,如果你想在几个函数上使用相同的样板,你可以这样做:

myrepr = representation('<function %s created by awesome programmer>')

@myrepr
def f():
    ...

@myrepr
def g():
    ...

etc

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM