2009-12-15 21 views
198

Quiero iterar a través de los métodos en una clase, o manejar objetos de clase o instancia de forma diferente en función de los métodos presentes. ¿Cómo obtengo una lista de métodos de clase?¿Cómo obtengo la lista de métodos en una clase de Python?

Véase también:

+38

@ S. Lott Por qué no puedes usar la Fuerza? ¿Qué pasa con la Fuerza? – jononomo

+0

La fuente ..... la fuente ... – RickyA

+0

@JonCrowell no es así como funciona la Fuerza. –

Respuesta

225

Un ejemplo (una lista de los métodos de la clase optparse.OptionParser):

>>> from optparse import OptionParser 
>>> import inspect 
>>> inspect.getmembers(OptionParser, predicate=inspect.ismethod) 
[([('__init__', <unbound method OptionParser.__init__>), 
... 
('add_option', <unbound method OptionParser.add_option>), 
('add_option_group', <unbound method OptionParser.add_option_group>), 
('add_options', <unbound method OptionParser.add_options>), 
('check_values', <unbound method OptionParser.check_values>), 
('destroy', <unbound method OptionParser.destroy>), 
('disable_interspersed_args', 
    <unbound method OptionParser.disable_interspersed_args>), 
('enable_interspersed_args', 
    <unbound method OptionParser.enable_interspersed_args>), 
('error', <unbound method OptionParser.error>), 
('exit', <unbound method OptionParser.exit>), 
('expand_prog_name', <unbound method OptionParser.expand_prog_name>), 
... 
] 

en cuenta que getmembers devuelve una lista de 2-tuplas. El primer elemento es el nombre del miembro, el segundo elemento es el valor.

También puede pasar una instancia de getmembers:

>>> parser = OptionParser() 
>>> inspect.getmembers(parser, predicate=inspect.ismethod) 
... 
+3

perfecto, la parte del predicado es la clave, de lo contrario obtendrá lo mismo que __dict__ con la meta información adicional. Gracias. – Purrell

+1

¿Producirá esto una lista de todos los métodos de la clase (incluidos los heredados de otras clases), o solo enumerará los métodos que se definen explícitamente en esa clase? –

+0

Incluye métodos heredados. – codeape

22

Tratar la propiedad __dict__.

+11

Creo que te refieres a __dict__. Pero eso enumera los atributos de la instancia, no los métodos. –

+1

... eso tampoco funcionó para mí. Habiendo consultado la sintaxis de Markdown, creo que me refiero a \ _ \ _ dict \ _ \ _. –

+2

@me_y probablemente esté haciendo "self .__ dict__" o, más genéricamente, llamando a la versión de instancia de '__dict__'. Sin embargo, las clases también tienen '__dict__' y deberían mostrar los métodos de clase :) – Seaux

129

No es el método dir(theobject) enumerar todos los campos y métodos de su objeto (como una tupla) y el módulo de inspección (como codeape escritura) para listar los campos y métodos con su doc ​​(en "" ").

Porque todo (incluso campos) se podría llamar en Python, no estoy seguro de que es una función incorporada a la lista únicos métodos. es posible que desee probar si el objeto se obtiene a través dir es o no callable

9

Tenga en cuenta que debe considerar si desea métodos de clases base que se hereden (pero no se anulan) incluyendo Uded en el resultado. Las operaciones dir() y inspect.getmembers() incluyen métodos de clase base, pero el uso del atributo __dict__ no.

0
def find_defining_class(obj, meth_name): 
    for ty in type(obj).mro(): 
     if meth_name in ty.__dict__: 
      return ty 

Así

print find_defining_class(car, 'speedometer') 

Piense página Python 210

+2

¿Sangría de 5? ¿Capitalizando palabras clave? ¿Espaciado sin estilo de pep8? – towerofnix

+0

¡No una vez que los nazis llegaron a la convención de codificación! – rbennell

-1

Sé que esto es una entrada antigua, pero acabo de escribir esta función y lo dejo aquí es si alguien tropieza buscando una respuesta:

def classMethods(the_class,class_only=False,instance_only=False,exclude_internal=True): 

    def acceptMethod(tup): 
     #internal function that analyzes the tuples returned by getmembers tup[1] is the 
     #actual member object 
     is_method = inspect.ismethod(tup[1]) 
     if is_method: 
      bound_to = tup[1].im_self 
      internal = tup[1].im_func.func_name[:2] == '__' and tup[1].im_func.func_name[-2:] == '__' 
      if internal and exclude_internal: 
       include = False 
      else: 
       include = (bound_to == the_class and not instance_only) or (bound_to == None and not class_only) 
     else: 
      include = False 
     return include 
    #uses filter to return results according to internal function and arguments 
    return filter(acceptMethod,inspect.getmembers(the_class)) 
+0

Este código no hace lo que está destinado a ser publicado. Dar class_only o instance_only resultará en una lista vacía. – Oz123

10

también puede importar el FunctionType de tipos y probarlo con el class.__dict__:

from types import FunctionType 

class Foo: 
    def bar(self): pass 
    def baz(self): pass 

def methods(cls): 
    return [x for x, y in cls.__dict__.items() if type(y) == FunctionType] 

methods(Foo) # ['bar', 'baz'] 
+0

Esto funcionó bien para mí. Agregué 'y no x.inicia con ('_')' al final de la lista de comprensión para mi uso para ignorar '__init__' y métodos privados. –

+1

Puede deshacerse de la 'importación' de' FunctionType' utilizando un lambda desechable con 'tipo()': 'tipo (lambda: 0)' – Tersosauros

30

Python 3.x respuesta sin librerías externas

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func))] 

dunder-excluidos resultado:

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")] 
Cuestiones relacionadas