Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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.

like image 691
arjunaskykok Avatar asked Nov 20 '13 10:11

arjunaskykok


3 Answers

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__.

You can create a callable object with a custom __repr__, which acts just like a function:

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'
like image 174
Martijn Pieters Avatar answered Oct 12 '22 17:10

Martijn Pieters


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.

like image 37
Alexander Zhukov Avatar answered Oct 12 '22 15:10

Alexander Zhukov


Not directly the answer to your question, but perhaps you really want a 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
like image 44
Mark Tolonen Avatar answered Oct 12 '22 16:10

Mark Tolonen