2010-03-29 9 views
5

Voglio ottenere i nomi degli argomenti delle parole chiave dei metodi di una classe. Credo di aver capito come ottenere i nomi dei metodi e come ottenere i nomi delle variabili di un metodo specifico, ma non ottengo come combinare questi:Python Introspection: come ottenere i nomi dei metodi di classe?

class A(object): 
    def A1(self, test1=None): 
     self.test1 = test1 
    def A2(self, test2=None): 
     self.test2 = test2 
    def A3(self): 
     pass 
    def A4(self, test4=None, test5=None): 
     self.test4 = test4 
     self.test5 = test5 

a = A() 

# to get the names of the methods: 

for methodname in a.__class__.__dict__.keys(): 
    print methodname 

# to get the variable names of a specific method: 

for varname in a.A1.__func__.__code__.co_varnames: 
    print varname 

# I want to have something like this: 
for function in class: 
    print function.name 
    for varname in function: 
     print varname 

# desired output: 
A1 
self 
test1 
A2 
self 
test2 
A3 
self 
A4 
self 
test4 
test5 

ho dovranno esporre i nomi di i metodi e i loro argomenti a un'API esterna. Ho scritto un'app intrecciata per collegarmi all'api menzionata e questa app ritorta dovrà pubblicare questi dati tramite l'API.

Quindi, penso che usare qualcosa come:

for methodname in A.__dict__.keys(): 
if not methodname.startswith('__'): 
    print methodname 
    for varname in A.__dict__[methodname].__code__.co_varnames: 
     print varname 

volta, i dintorni diventano più stabili ci penserò su una soluzione migliore.

+1

Perché vuoi farlo? – ironfroggy

+0

python 2.5 non mi piace A .__ dict __ [methodname] .__ code __. Co_varnames - L'oggetto 'function' non ha attributo '__code__' L'uso di inspect può essere più stabile tra le versioni di Python. –

risposta

5

Beh, come un'estensione diretta di quello che hai fatto:

for varname in a.__class__.__dict__['A1'].__code__.co_varnames: 
    print varname 

stampe:

self 
test1 

PS: ad essere onesti, ho la sensazione questo può essere fatto in modo più elegante .. .

Ad esempio, è possibile sostituire con a.__class__A, ma si sapeva che ;-)

+0

Grazie! Se conosci una soluzione migliore, sei il benvenuto. Il mio cervello del lunedì mattina è solo un po '... sai ... ;-) – daccle

+1

Non c'è niente di utile nel mostrare alla gente come fare cose stupide. – ironfroggy

+2

@ironfroggy perché pensi che sia una cosa sciocca? – daccle

10
import inspect 

for name, method in inspect.getmembers(a, inspect.ismethod): 
    print name 
    (args, varargs, varkw, defaults) = inspect.getargspec(method) 
    for arg in args: 
     print arg 
+0

Ho visto molti esempi usando il modulo inspect. Perché usare ispezionare una buona idea? Perché non usare i metodi propri delle classi per svolgere il lavoro? – daccle

+0

@daccle: la mia ipotesi è che 'inspect' è stato lì prima che le classi permettessero tali livelli di introspezione. –

+1

inspect api è pulito. Usarlo rende il codice più leggibile, penso. –