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

Ich möchte haben:

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

Wie mache ich das? Das Einfügen von __repr__ in die Funktion hehe funktioniert nicht.

BEARBEITEN:

Falls ihr euch fragt, warum ich das machen will:

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

Ich mag es einfach nicht, wie es hier gezeigt wird.

11
arjunaskykok 20 Nov. 2013 im 14:48

4 Antworten

Beste Antwort

Wenn Sie etwas an der Funktion ändern möchten, z. B. Funktionssignatur, Funktionsverhalten oder Funktionsattribute, sollten Sie normalerweise die Verwendung eines Dekorateurs in Betracht ziehen. So können Sie das implementieren, was Sie möchten:

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

Beachten Sie, dass Sie nur einen klassenbasierten Dekorator verwenden können, da Sie die Methode __repr__ überschreiben müssen, was mit einem Funktionsobjekt nicht möglich ist.

9
Alexander Zhukov 10 Sept. 2016 im 12:10

Hier ist eine etwas flexiblere Version der Antwort von Alexander Zhukov:

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)

Ausgabe:

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

Da representation() einen Dekorateur zurückgibt, können Sie Folgendes tun, wenn Sie dasselbe Boilerplate für mehrere Funktionen wünschen:

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

@myrepr
def f():
    ...

@myrepr
def g():
    ...

etc
2
Community 23 Mai 2017 im 11:51

Nein, Sie können die Darstellung eines Funktionsobjekts nicht ändern. Wenn Sie Dokumentation hinzufügen möchten, fügen Sie eine Dokumentzeichenfolge hinzu:

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

Und greifen Sie mit help(foo) oder print foo.__doc__ darauf zu.

Sie können ein aufrufbares Objekt mit einem benutzerdefinierten __repr__ erstellen, das sich wie eine Funktion verhält:

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'
10
Martijn Pieters 20 Nov. 2013 im 10:57

Nicht direkt die Antwort auf Ihre Frage, aber vielleicht möchten Sie wirklich einen 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
2
Mark Tolonen 20 Nov. 2013 im 10:52