2010-03-29 15 views
5

Quiero obtener los nombres de los argumentos de palabra clave de los métodos de una clase. Creo que he entendido cómo obtener los nombres de los métodos y cómo obtener los nombres de las variables de un método específico, pero no entiendo cómo combinar estas:Python Introspection: ¿Cómo obtener varnames de los métodos de clase?

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 

que tendrán que exponer los nombres de los métodos y sus argumentos a una API externa. He escrito una aplicación retorcida para enlazar con la API mencionada y esta aplicación retorcida tendrá que publicar esta información a través de la API.

Por lo tanto, creo que voy a usar algo como:

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

vez, el entorno se vuelven más estables voy a pensar en una solución mejor.

+1

¿Por qué quieres hacer esto? – ironfroggy

+0

python 2.5 no le gusta A .__ dict __ [methodname] .__ code __. Co_varnames - 'function' object no tiene atributo '__code__' Usar inspection puede ser más estable entre versiones de python. –

Respuesta

5

Bueno, como una extensión directa de lo que hizo:

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

impresiones:

self 
test1 

PS: para ser honesto, tengo una sensación de que esto se puede hacer de manera más elegante .. .

Por ejemplo, se puede reemplazar con a.__class__A, pero sabía que ;-)

+0

Gracias! Si conoces una solución mejor, de nada. Mi cerebro de lunes por la mañana es solo un poco ... ya sabes ... ;-) – daccle

+1

No hay nada de útil en mostrar a las personas cómo hacer cosas tontas. – ironfroggy

+2

@ironfroggy ¿por qué crees que es una tontería? – 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

He visto muchos ejemplos usando el módulo de inspección. ¿Por qué el uso de inspeccionar es una buena idea? ¿Por qué no usar clases de métodos propios para hacer el trabajo? – daccle

+0

@daccle: mi conjetura es que 'inspeccionar' ha estado allí antes de que las clases permitieran tales niveles de introspección –

+1

inspeccionar que la API está limpia. Usarlo hace que el código sea más legible, creo. –

Cuestiones relacionadas