2016-07-02 8 views
0

Angenommen, ich möchte eine Introspektionszeilengruppe erstellen, die verfügbare Details einer Funktion anzeigt.
So etwas wie die Unterseite des folgenden Code:Wie drucke ich einen Python-Attributnamen?

def sample(_range=4): 
    """ produce a range of integers """ 
    for i in range(_range): 
     yield i 

f = sample 
for i in (f.__name__, f.__doc__, f.__dict__, f.__code__, f.__defaults__, f.__globals__, f.__closure__): 
    print("XXX", i) 

Was ich andernfalls die XXX etwas zu erreichen, ist zu ändern, die die Attributnamen gedruckt werden sollten, zum Beispiel statt

XXX sample 
XXX produce a range of integers 
XXX {} 
XXX <code object sample at 0xfff15890, file "/tmp/tmp.py", line 1> 
XXX (4,) 
XXX {'__loader__': <_frozen_importlib.SourceFileLoader object at 0xfff13b30>, '__package__': None, '__file__': '/tmp/tmp.py', '__cached__': None, 'i': {...}, 'f': <function sample at 0xfff5b1e0>, '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__spec__': None, '__name__': '__main__', 'sample': <function sample at 0xfff5b1e0>} 
XXX None 

I‘ d mögen vorschlagen

__name__ sample 
__doc__ produce a range of integers 
__dict__ {} 
__code__ <code object sample at 0xfff15890, file "/tmp/tmp.py", line 1> 
__defaults__ (4,) 
f.__globals__ {'__loader__': <_frozen_importlib.SourceFileLoader object at 0xfff13b30>, '__package__': None, '__file__': '/tmp/tmp.py', '__cached__': None, 'i': {...}, 'f': <function sample at 0xfff5b1e0>, '__builtins__': <module 'builtins' (built-in)>, '__doc__': None, '__spec__': None, '__name__': '__main__', 'sample': <function sample at 0xfff5b1e0>} 
__closure__ None 

Was möchten Sie sollte XXX ersetzen?

+0

Sie ein Wörterbuch verwenden könnte? Namen als Schlüssel und Werte als Attribute –

+2

Warum nicht stattdessen über die Namen iterieren? 'für name in ['__name__', '__doc__', ...]: ...'. – jonrsharpe

+0

@MosesKoledoye unter der Haube, genau das ist das "Probe" -Objekt! – jonrsharpe

Antwort

2

Wenn, wie in Ihrem Beispiel die Namen der Attribute, die Sie wünschen, würde diese Arbeit:

for fn in ('__name__', '__doc__', '__dict__', '__code__', '__defaults__', '__globals__', '__closure__'): 
    print(fn, getattr(f, fn)) 

Wenn Sie fragen, wie Sie den Namen erhalten, wenn alles, was Sie die Funktion, dann ist haben Ich glaube, du hast kein Glück; Der Name ist keine Eigenschaft der Funktion, sondern vielmehr, wie sie referenziert wird, ähnlich wie Sie nicht fragen können, wie der Name der Variablen, die die Zahl 3 enthält, nur aus der Zahl stammt. (Gedankenübung: Was wäre der Name für eine Funktion, die Teil von 3 unterschiedlichen Objekten ist, jedes unter einem anderen Namen?)

Ich vermute, wenn Sie den Namen einer Funktion in einem bestimmten Objekt wollten, könnten Sie iterieren über die Attribute dieses Objekts, nach deiner Funktion suchend; Wenn Sie es finden, ist der Name, den Sie verwendet haben, der Name, den Sie verwenden möchten.

+0

Das sollte 'getattr (f, fn)' sein. – jonrsharpe

+0

'def foo(): pass 'gibt dem Funktionsobjekt tatsächlich den Namen' foo'. Funktionen können und haben einen Namen; es ist nur die Variable, deren Name du nicht bekommen kannst. – poke

1

Da Sie bereits eine Liste der Attribute haben, könnten Sie getattr verwenden:

for name in ['__name__', '__doc__', '__dict__', '__code__', '__defaults__', '__globals__', '__closure__']: 
    print('{} -> {}'.format(name, getattr(f, name)))