Encontrar qué métodos tiene un objeto Python

431

Dado un objeto Python de cualquier tipo, ¿hay una manera fácil de obtener la lista de todos los métodos que tiene este objeto?

O,

Si esto no es posible, ¿existe al menos una manera fácil de verificar si tiene un método en particular que no sea simplemente verificar si se produce un error cuando se llama al método?

Thomas Lötzer
fuente
Relevante: stackoverflow.com/q/46033277/1959808
Ioannis Filippidis

Respuestas:

525

Para muchos objetos , puede usar este código, reemplazando 'objeto' con el objeto que le interesa:

object_methods = [method_name for method_name in dir(object)
                  if callable(getattr(object, method_name))]

Lo descubrí en diveintopython.net (ahora archivado). ¡Con suerte, eso debería proporcionar más detalles!

Si obtienes un AttributeError, puedes usar esto en su lugar :

getattr(es intolerante a las subclases virtuales abstractas de estilo pandas python3.6. Este código hace lo mismo que el anterior e ignora las excepciones.

import pandas as pd 
df = pd.DataFrame([[10, 20, 30], [100, 200, 300]],  
                  columns=['foo', 'bar', 'baz']) 
def get_methods(object, spacing=20): 
  methodList = [] 
  for method_name in dir(object): 
    try: 
        if callable(getattr(object, method_name)): 
            methodList.append(str(method_name)) 
    except: 
        methodList.append(str(method_name)) 
  processFunc = (lambda s: ' '.join(s.split())) or (lambda s: s) 
  for method in methodList: 
    try: 
        print(str(method.ljust(spacing)) + ' ' + 
              processFunc(str(getattr(object, method).__doc__)[0:90])) 
    except: 
        print(method.ljust(spacing) + ' ' + ' getattr() failed') 


get_methods(df['foo']) 
ljs
fuente
3
Es una comprensión de la lista, que devuelve una lista de métodos donde el método es un elemento en la lista devuelta por dir (objeto), y donde cada método se agrega a la lista solo si getattr (objeto, método) devuelve un invocable.
Mnebuerquo
1
¿Cómo usas esto exactamente? Para decir imprimir una lista de los métodos.
pantano
13
@marsh Para imprimir los métodos: print [method for method in dir(object) if callable(getattr(object, method))].
Orienteerix
1
Recibo un mensaje AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'cuando intento ejecutar esto. Consulte los detalles en stackoverflow.com/q/54713287/9677043 .
Karl Baker
1
no funciona para el objeto de marco de datos de pandas en python 3.6.
Stefan Karlsson
226

Puede usar la dir()función integrada para obtener una lista de todos los atributos que tiene un módulo. Pruebe esto en la línea de comando para ver cómo funciona.

>>> import moduleName
>>> dir(moduleName)

Además, puede usar la hasattr(module_name, "attr_name")función para averiguar si un módulo tiene un atributo específico.

Consulte la Guía de introspección de Python para obtener más información.

Bill el lagarto
fuente
hasattrayudó a mi caso de uso a encontrar si el objeto python tiene una variable miembro o método particular.
Akshay
No estoy seguro de por qué esta solución no se ha votado lo suficiente. Esto es conciso y preciso.
Prasad Raghavendra
93

El método más simple es usar dir(objectname). Mostrará todos los métodos disponibles para ese objeto. Buen truco.

Pawan Kumar
fuente
3
También muestra los atributos del objeto, por lo que si desea buscar métodos específicamente, no funcionará.
Eric
Si. Convenido. Pero no conozco ninguna otra técnica para obtener solo la lista de métodos. ¿Quizás la mejor idea es obtener la lista de atributos y métodos y luego usar <hasattr (object, "method_name"> para filtrarlo más?
Pawan Kumar
1
@neuronet, estoy tratando de ejecutar la respuesta aceptada pero obtengo una AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'. ¿Algunas ideas? Consulte los detalles en stackoverflow.com/q/54713287/9677043 . +1 a @Pawan Kumar b / c la respuesta funciona, y a @ljs por la promesa de una lista filtrada de solo los métodos.
Karl Baker
30

Para verificar si tiene un método particular:

hasattr(object,"method")
Bill el lagarto
fuente
14
dado que el OP está buscando un método y no solo un atributo, creo que quiere ir un paso más allá con:if hasattr(obj,method) and callable(getattr(obj,method)):
Bruno Bronosky
28

Creo que lo que quieres es algo como esto:

una lista de atributos de un objeto

En mi humilde opinión, la función integrada dir()puede hacer este trabajo por usted. Tomado de la help(dir)salida en su Python Shell:

dir (...)

dir([object]) -> list of strings

Si se llama sin argumento, devuelve los nombres en el ámbito actual.

De lo contrario, devuelva una lista alfabética de nombres que comprendan (algunos de) los atributos del objeto dado y de los atributos accesibles desde él.

Si el objeto proporciona un método llamado __dir__, se usará; de lo contrario, se usa la lógica dir () predeterminada y devuelve:

  • para un objeto de módulo: los atributos del módulo.
  • para un objeto de clase: sus atributos, y recursivamente los atributos de sus bases.
  • para cualquier otro objeto: sus atributos, los atributos de su clase y recursivamente los atributos de las clases base de su clase.

Por ejemplo:

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> a = "I am a string"
>>>
>>> type(a)
<class 'str'>
>>>
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_formatter_field_name_split', '_formatter_parser', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip',
'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
'translate', 'upper', 'zfill']

Mientras revisaba su problema, decidí demostrar mi línea de pensamiento, con un mejor formato de la salida de dir().

dir_attributes.py (Python 2.7.6)

#!/usr/bin/python
""" Demonstrates the usage of dir(), with better output. """

__author__ = "ivanleoncz"

obj = "I am a string."
count = 0

print "\nObject Data: %s" % obj
print "Object Type: %s\n" % type(obj)

for method in dir(obj):
    # the comma at the end of the print, makes it printing 
    # in the same line, 4 times (count)
    print "| {0: <20}".format(method),
    count += 1
    if count == 4:
        count = 0
        print

dir_attributes.py (Python 3.4.3)

#!/usr/bin/python3
""" Demonstrates the usage of dir(), with better output. """

__author__ = "ivanleoncz"

obj = "I am a string."
count = 0

print("\nObject Data: ", obj)
print("Object Type: ", type(obj),"\n")

for method in dir(obj):
    # the end=" " at the end of the print statement, 
    # makes it printing in the same line, 4 times (count)
    print("|    {:20}".format(method), end=" ")
    count += 1
    if count == 4:
        count = 0
        print("")

Espero haber contribuido :).

ivanleoncz
fuente
1
Contribuido? Tu respuesta funcionó para mí en Python 2.7.12, ¡así que sí!
gsamaras
23

Además de las respuestas más directas, sería negligente si no mencionara iPython . Presione 'tab' para ver los métodos disponibles, con autocompletado.

Y una vez que haya encontrado un método, intente:

help(object.method) 

para ver los pydocs, la firma del método, etc.

Ahh ... REPL .

jmanning2k
fuente
12

Si desea métodos específicamente , debe usar inspect.ismethod .

Para nombres de métodos:

import inspect
method_names = [attr for attr in dir(self) if inspect.ismethod(getattr(self, attr))]

Para los métodos en sí mismos:

import inspect
methods = [member for member in [getattr(self, attr) for attr in dir(self)] if inspect.ismethod(member)]

A veces también inspect.isroutinepuede ser útil (para incorporados, extensiones C, Cython sin la directiva del compilador "vinculante").

paulmelnikow
fuente
¿No deberías usar en inspect.getmemberslugar de usar diren una lista de comprensión?
Boris
Sí, eso parece mejor!
paulmelnikow
11

Abra bash shell (ctrl + alt + T en Ubuntu). Inicie python3 shell en él. Crear objeto para observar métodos de. Simplemente agregue un punto después y presione dos veces "tab" y verá algo así:

 user@note:~$ python3
 Python 3.4.3 (default, Nov 17 2016, 01:08:31) 
 [GCC 4.8.4] on linux
 Type "help", "copyright", "credits" or "license" for more information.
 >>> import readline
 >>> readline.parse_and_bind("tab: complete")
 >>> s = "Any object. Now it's a string"
 >>> s. # here tab should be pressed twice
 s.__add__(           s.__rmod__(          s.istitle(
 s.__class__(         s.__rmul__(          s.isupper(
 s.__contains__(      s.__setattr__(       s.join(
 s.__delattr__(       s.__sizeof__(        s.ljust(
 s.__dir__(           s.__str__(           s.lower(
 s.__doc__            s.__subclasshook__(  s.lstrip(
 s.__eq__(            s.capitalize(        s.maketrans(
 s.__format__(        s.casefold(          s.partition(
 s.__ge__(            s.center(            s.replace(
 s.__getattribute__(  s.count(             s.rfind(
 s.__getitem__(       s.encode(            s.rindex(
 s.__getnewargs__(    s.endswith(          s.rjust(
 s.__gt__(            s.expandtabs(        s.rpartition(
 s.__hash__(          s.find(              s.rsplit(
 s.__init__(          s.format(            s.rstrip(
 s.__iter__(          s.format_map(        s.split(
 s.__le__(            s.index(             s.splitlines(
 s.__len__(           s.isalnum(           s.startswith(
 s.__lt__(            s.isalpha(           s.strip(
 s.__mod__(           s.isdecimal(         s.swapcase(
 s.__mul__(           s.isdigit(           s.title(
 s.__ne__(            s.isidentifier(      s.translate(
 s.__new__(           s.islower(           s.upper(
 s.__reduce__(        s.isnumeric(         s.zfill(
 s.__reduce_ex__(     s.isprintable(       
 s.__repr__(          s.isspace(           
Valery Ramusik
fuente
1
Mientras hablamos de soluciones como esta, agregaré que también puede ejecutar ipython, comenzar a escribir el objeto y presionar taby funcionará también. No hay ajustes necesarios readline
Max Coplan
1
@MaxCoplan He agregado la solución alternativa en el código para los casos en los que la finalización de la pestaña no está habilitada de forma predeterminada
Valery Ramusik,
8

El problema con todos los métodos indicados aquí es que NO PUEDE asegurarse de que no exista un método.

En Python puede interceptar el punto llamando a través __getattr__y __getattribute__, haciendo posible crear el método "en tiempo de ejecución"

Ejemplo:

class MoreMethod(object):
    def some_method(self, x):
        return x
    def __getattr__(self, *args):
        return lambda x: x*2

Si lo ejecuta, puede llamar al método no existente en el diccionario de objetos ...

>>> o = MoreMethod()
>>> o.some_method(5)
5
>>> dir(o)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'some_method']
>>> o.i_dont_care_of_the_name(5)
10

Y es por eso que usa el más fácil para pedir perdón que los paradigmas de permisos en Python.

Cld
fuente
6

La forma más sencilla de obtener una lista de métodos de cualquier objeto es usar el help()comando.

%help(object)

Enumerará todos los métodos disponibles / importantes asociados con ese objeto.

Por ejemplo:

help(str)
Paritosh Vyas
fuente
¿Qué hace el %en el primer ejemplo? No funciona en mi Python 2.7.
Scorchio
@Scorchio He usado "%" como indicador en su lugar ">>>" para python. Puede quitar% antes de ejecutar el comando.
Paritosh Vyas
3
import moduleName
for x in dir(moduleName):
print(x)

Esto debería funcionar :)

La mafia
fuente
1

Uno puede crear una getAttrsfunción que devolverá los nombres de propiedad invocables de un objeto

def getAttrs(object):
  return filter(lambda m: callable(getattr(object, m)), dir(object))

print getAttrs('Foo bar'.split(' '))

Eso volvería

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
 '__delslice__', '__eq__', '__format__', '__ge__', '__getattribute__', 
 '__getitem__', '__getslice__', '__gt__', '__iadd__', '__imul__', '__init__', 
 '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', 
 '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', 
 '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', 
 '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 
 'remove', 'reverse', 'sort']
james_womack
fuente
1

No hay una forma confiable de enumerar todos los métodos de los objetos. dir(object)suele ser útil, pero en algunos casos puede no enumerar todos los métodos. Según la dir()documentación : "Con un argumento, intente devolver una lista de atributos válidos para ese objeto".

La comprobación de que ese método existe puede hacerse callable(getattr(object, method))como ya se mencionó allí.

afirmar
fuente
1

Toma una lista como un objeto

obj = []

list(filter(lambda x:callable(getattr(obj,x)),obj.__dir__()))

Usted obtiene:

['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dir__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__iadd__',
 '__imul__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__reversed__',
 '__rmul__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']
Mahdi Ghelichi
fuente
0

... ¿hay al menos una manera fácil de verificar si tiene un método en particular que no sea simplemente verificar si se produce un error cuando se llama al método

Si bien "es más fácil pedir perdón que permiso " es sin duda la forma pitónica, lo que estás buscando quizás:

d={'foo':'bar', 'spam':'eggs'}
if 'get' in dir(d):
    d.get('foo')
# OUT: 'bar'
Bruno Bronosky
fuente
0

Para buscar un método específico en un módulo completo

for method in dir(module) :
  if "keyword_of_methode" in method :
   print(method, end="\n")
Simon PII
fuente
-1

Si, por ejemplo, usa shell plus, puede usar esto en su lugar:

>> MyObject??

de esa manera, con el '??' justo después de su objeto, le mostrará todos los atributos / métodos que tiene la clase.

Nick Cuevas
fuente