2008-08-29 26 views
233

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

O

si esto no es posible, hay al menos una forma fácil de comprobar si se dispone de un método particular que no sea simplemente para comprobar si se produce un error cuando se llama al método?

+0

Relevante: https://stackoverflow.com/q/46033277/1959808 –

Respuesta

297

Parece puede utilizar este código, en sustitución de 'objeto' con el objeto que le interesa: -

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

lo descubrí en this site, es de esperar que debería proporcionar algún detalle adicional!

+0

No estoy seguro de lo que está tratando de lograr aquí, pero tener "método" en aquellos lugares 3 no tiene sentido para mí . Si reemplaza "objeto" por "el objeto que le interesa" se devolverán todos los cálculos de cualquier objeto con un único aviso. Por favor, ayúdame a entender el punto. –

+0

Quizás quiso decir '[getattr (obj, method) para method en dir (obj) if method == method_name y invocable (getattr (obj, method_name))]' que podría usarse como: 'obj = {' foo ': 'bar'}; method_name = 'get'; x = [getattr (obj, método) para el método en dir (obj) if method == method_name y invocable (getattr (obj, method_name))]; ' y luego 'if (len (x)): x [0] ('foo')' ... Sé que es realmente desagradable en una línea, pero los comentarios no permiten saltos de línea –

+0

@RichardBronosky, podría no hacer tiene sentido para usted, pero funciona. – jwg

131

Puede usar la función incorporada en dir() 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 utilizar la función hasattr(module_name, "attr_name") para averiguar si un módulo tiene un atributo específico.

Consulte el Guide to Python introspection para obtener más información.

+0

'hasattr' ayudó a mi caso de uso a encontrar si el objeto python tiene una variable o método miembro particular. – Akshay

23

Para comprobar si tiene un método particular:

hasattr(object,"method") 
+11

ya que el OP está buscando un método y no solo y un atributo, creo que quiere dar un paso más con: 'if hasattr (obj, method) and invocable (getattr (obj, method)):' –

17

En la parte superior de las respuestas más directas, sería negligente si no mencionara iPython. Pulse 'tab' para ver los métodos disponibles, con autocompletado.

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

help(object.method) 

para ver el pydocs, método de firma, etc.

Ahh ... REPL.

1

... ¿hay al menos una forma fácil de comprobar si se dispone de un método particular que no sea simplemente para comprobar si se produce un error cuando se llama al método

Mientras que "Easier to ask for forgiveness than permission" es sin duda la Pythonic manera, lo que está buscando quizá:

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

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

+0

También muestra los atributos del objeto, por lo que si desea encontrar métodos específicamente, no funcionará. – neuronet

+0

Sí. Convenido. Pero, no conozco ninguna otra técnica para obtener solo la lista de métodos.Tal vez la mejor idea es obtener la lista de ambos atributos y métodos y luego usar para filtrar más lejos? –

+1

Ver la respuesta aceptada – neuronet

5

El problema con todos los métodos indicados aquí es que NO se puede estar seguro de que un método no exista.

En Python se puede interceptar el punto de llamar a través __getattr__ y __getattribute__, por lo que es 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 ejecutas, 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 utiliza los Easier to ask for forgiveness than permission paradigmas en Python.

7

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

Para los nombres de método:

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

Para los propios métodos:

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

veces inspect.isroutine puede ser útil también (para muebles empotrados, extensiones C, Cython sin la "unión" directiva del compilador)

+0

Respuesta pertinente: https://stackoverflow.com/a/1911287/1959808 –

2

Uno puede crear una función getAttrs que devolverá nombres de las propiedades de un objeto que se puede llamar

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

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

Eso sería volver

['__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'] 
2

No hay manera confiable para enumerar todos los métodos del objeto. dir(object) suele ser útil, pero en algunos casos puede no enumerar todos los métodos. De acuerdo con dir() documentation: "Con un argumento, intento para devolver una lista de atributos válidos para ese objeto."

Comprobando que existe ese método se puede hacer por callable(getattr(object, method)) como ya se mencionó allí.

15

Creo que lo que quiere es algo como esto:

una lista de atributos de un objeto

En mi humilde opinión, la función incorporada dir() puede hacer este trabajo para tú. Tomado de help(dir) salida del intérprete de comandos de Python:

dir (...)

dir([object]) -> list of strings 

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

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

Si el objeto proporciona un método denominado __dir__, que se utilizarán; de lo contrario la lógica dir predeterminado() se utiliza y devuelve:

  • para un objeto de módulo: atributos del módulo.
  • para un objeto de clase: sus atributos, y de forma recursiva los atributos de sus bases.
  • para cualquier otro objeto: sus atributos, atributos de su clase, y de forma recursiva 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'] 

Como me iba a registrar 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("") 

esperanza de que he contribuido :).

2

Open bash shell (ctrl + alt + T en Ubuntu). Inicie el shell python3 en él. Crear objeto para observar los métodos de. Sólo tiene que añadir un punto después de que dos veces y pulse "tab" y verá algo así:

[email protected]:~$ 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. 
>>> s = "Any object. Now it's a string" 
>>> s. # here tab should be pressed twice times 
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(   
0

Tomar una lista como un objeto

obj = [] 

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

Se 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'] 
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") 
Cuestiones relacionadas