¿Cómo enumerar todas las funciones en un módulo de Python?

418

Tengo un módulo de Python instalado en mi sistema y me gustaría poder ver qué funciones / clases / métodos están disponibles en él.

Quiero llamar a la función doc en cada uno. En ruby ​​puedo hacer algo como ClassName.methods para obtener una lista de todos los métodos disponibles en esa clase. ¿Hay algo similar en Python?

p.ej. algo como:

from somemodule import foo
print foo.methods # or whatever is the correct method to call
Chris Gow
fuente
3
por favor considere revisar la respuesta seleccionada! Existen soluciones mejores / más fáciles de usar sugeridas en otras respuestas.
Zahra

Respuestas:

139

El inspectmodulo. Consulte también el pydocmódulo, la help()función en el intérprete interactivo y la pydocherramienta de línea de comandos que genera la documentación que busca. Puede darles la clase de la que desea ver la documentación. También pueden generar, por ejemplo, salida HTML y escribirla en el disco.

Thomas Wouters
fuente
3
He defendido el uso del astmódulo en ciertas situaciones en mi respuesta .
csl
28
TL; DR de las respuestas a continuación: se usa dirpara devolver funciones y variables; usar inspectpara filtrar funciones solamente; y usar astpara analizar sin importar.
Jonathan H
Vale la pena probar cada uno de los enfoques resumidos por Sheljohn ya que el resultado resultante es drásticamente diferente de una solución a la siguiente.
clozach
1
@ Hack-R Aquí está el código para enumerar todas las funciones en mymodule: [f [0] para f en inspect.getmembers (mymodule, inspect.isfunction)]
SurpriseDog
498

Puede usar dir(module)para ver todos los métodos / atributos disponibles. También echa un vistazo a PyDocs.

camflan
fuente
15
Esto no es estrictamente cierto. La dir()función "intenta producir la información más relevante, en lugar de completa". Fuente: docs.python.org/library/functions.html#dir .
Zearin
15
@jAckOdE Citado? Luego obtendrá los métodos y atributos disponibles del módulo de cadena.
OrangeTux
@OrangeTux: Uy, eso se supone que es una pregunta. Sí, lo respondiste.
jAckOdE
1
El OP claramente solicita funciones, no variables. Cf responde usando inspect.
Jonathan H
168

Una vez que haya importeditado el módulo, puede hacer lo siguiente:

 help(modulename)

... Para obtener los documentos sobre todas las funciones a la vez, de forma interactiva. O puedes usar:

 dir(modulename)

... Simplemente enumerar los nombres de todas las funciones y variables definidas en el módulo.

Dan Lenski
fuente
1
@ Sheljohn ... ¿cuál es el punto de esta crítica? Mi solución también enumera funciones, y el inspect módulo también puede enumerar variables, aunque no se solicite explícitamente aquí. Esta solución solo requiere objetos integrados, lo que puede ser muy útil en algunos casos donde Python se instala en un entorno restringido / bloqueado / roto.
Dan Lenski
Gracias, esto casi funcionó, pero pensé que dirimprimiría los resultados, sin embargo, parece que debe hacerlo print(dir(modulename)).
Eliot
96

Un ejemplo con inspeccionar:

from inspect import getmembers, isfunction
from my_project import my_module

functions_list = [o for o in getmembers(my_module) if isfunction(o[1])]

getmembers devuelve una lista de tuplas (object_name, object_type).

Puede reemplazar isfunction con cualquiera de las otras funciones isXXX en el módulo de inspección.

adnan
fuente
27
getmemberspuede tomar un predicado, por lo que su ejemplo también podría escribirse: functions_list = [o for o in getmembers(my_module, isfunction)]
Christopher Currie
27
@ChristopherCurrie, también podría evitar la comprensión inútil de la lista functions_list = getmembers(my_module, predicate)porque ya devuelve una lista;)
Nil
55
Para saber si la función está definida en ese módulo (en lugar de importarse) agregue: a "if isfunction (o [1]) y o [1] .__ module__ == my_module .__ name__ " - tenga en cuenta que no funcionará necesariamente si la función importada proviene de un módulo con el mismo nombre que este módulo.
Michael Scott Cuthbert
72
import types
import yourmodule

print([getattr(yourmodule, a) for a in dir(yourmodule)
  if isinstance(getattr(yourmodule, a), types.FunctionType)])
Oli
fuente
8
Para esta ruta, use getattr (yourmodule, a, None) en lugar de yourmodule .__ dict __. Get (a)
Thomas Wouters
44
your_module .__ dict__ es mi elección porque en realidad obtienes un dict que contiene functionName: <function> y ahora tienes la capacidad de LLAMAR esa función dinámicamente. ¡Buenos tiempos!
jsh
1
Python 3 compatible con algo de azúcar: tipos de importación def print_module_functions (module): print ('\ n'.join ([str (module .__ dict __. Get (a) .__ name__) para un directorio dir (módulo) si esinstance (module. __dict __. get (a), types.FunctionType)]))
y.selivonchyk
1
Esto también enumerará todas las funciones que importa ese módulo. Eso puede o no ser lo que quieres.
scubbo
48

En aras de la integridad, me gustaría señalar que a veces es posible que desee analizar el código en lugar de importarlo. Una importse ejecutan expresiones de alto nivel, y que podría ser un problema.

Por ejemplo, dejo que los usuarios seleccionen funciones de punto de entrada para paquetes que se hacen con zipapp . El uso importy el inspectriesgo de ejecutar el código de mal camino, lo que provoca bloqueos, mensajes de ayuda que se imprimen, cuadros de diálogo de GUI emergentes, etc.

En cambio, uso el módulo ast para enumerar todas las funciones de nivel superior:

import ast
import sys

def top_level_functions(body):
    return (f for f in body if isinstance(f, ast.FunctionDef))

def parse_ast(filename):
    with open(filename, "rt") as file:
        return ast.parse(file.read(), filename=filename)

if __name__ == "__main__":
    for filename in sys.argv[1:]:
        print(filename)
        tree = parse_ast(filename)
        for func in top_level_functions(tree.body):
            print("  %s" % func.name)

Al poner este código list.pyy usarlo como entrada, obtengo:

$ python list.py list.py
list.py
  top_level_functions
  parse_ast

Por supuesto, navegar un AST puede ser complicado a veces, incluso para un lenguaje relativamente simple como Python, porque el AST es de nivel bastante bajo. Pero si tiene un caso de uso simple y claro, es factible y seguro.

Sin embargo, una desventaja es que no puede detectar funciones que se generan en tiempo de ejecución, como foo = lambda x,y: x*y.

csl
fuente
3
Me gusta esto; Actualmente estoy tratando de averiguar si alguien ya ha escrito una herramienta que haga algo como pydoc pero sin importar el módulo. Hasta ahora, este es el mejor ejemplo que he encontrado de esto :)
James Mills
De acuerdo con esta respuesta. Necesito que esta función funcione independientemente de lo que pueda importar el archivo de destino o para qué versión de Python está escrito. Esto no se encuentra con los problemas de importación que tienen imp e importlib.
Eric Evans
¿Qué hay de las variables del módulo ( __version__etc.)? ¿Hay alguna manera de conseguir eso?
frakman1
29

Para el código que no desea analizar, le recomiendo el enfoque basado en AST de @csl anterior.

Para todo lo demás, el módulo de inspección es correcto:

import inspect

import <module_to_inspect> as module

functions = inspect.getmembers(module, inspect.isfunction)

Esto proporciona una lista de 2 tuplas en el formulario [(<name:str>, <value:function>), ...].

La respuesta simple anterior se insinúa en varias respuestas y comentarios, pero no se menciona explícitamente.

Cireo
fuente
Gracias por explicarlo; Creo que esta es la respuesta correcta, si puede ejecutar la importación en el módulo para inspeccionar.
Jonathan H
25

Esto hará el truco:

dir(module) 

Sin embargo, si le resulta molesto leer la lista devuelta, simplemente use el siguiente bucle para obtener un nombre por línea.

for i in dir(module): print i
Algorias
fuente
2
El OP claramente solicita funciones, no variables. Cf responde usando inspect. Además, ¿cómo es esto diferente de la respuesta de @ DanLenski?
Jonathan H
20

dir(module) es la forma estándar cuando se usa un script o el intérprete estándar, como se menciona en la mayoría de las respuestas.

Sin embargo, con un shell de Python interactivo como IPython puede usar la finalización de tabulación para obtener una visión general de todos los objetos definidos en el módulo. Esto es mucho más conveniente que usar un script y printver qué se define en el módulo.

  • module.<tab> le mostrará todos los objetos definidos en el módulo (funciones, clases, etc.)
  • module.ClassX.<tab> le mostrará los métodos y atributos de una clase
  • module.function_xy?o module.ClassX.method_xy?le mostrará la cadena de documentación de esa función / método
  • module.function_x??o module.SomeClass.method_xy??le mostrará el código fuente de la función / método.
bmu
fuente
19

Para las funciones globales dir()es el comando a usar (como se menciona en la mayoría de estas respuestas), sin embargo, esto enumera las funciones públicas y las funciones no públicas juntas.

Por ejemplo ejecutando:

>>> import re
>>> dir(re)

Devuelve funciones / clases como:

'__all__', '_MAXCACHE', '_alphanum_bytes', '_alphanum_str', '_pattern_type', '_pickle', '_subx'

Algunos de los cuales generalmente no están destinados para el uso de programación general (sino por el módulo en sí, excepto en el caso de DunderAliases como __doc__, __file__ect). Por esta razón, puede no ser útil enumerarlos con los públicos (así es como Python sabe qué obtener cuando se usa from module import *).

__all__podría usarse para resolver este problema, devuelve una lista de todas las funciones públicas y clases en un módulo (las que no comienzan con guiones bajos _). Ver ¿Puede alguien explicar __todos__ en Python? para el uso de __all__.

Aquí hay un ejemplo:

>>> import re
>>> re.__all__
['match', 'fullmatch', 'search', 'sub', 'subn', 'split', 'findall', 'finditer', 'compile', 'purge', 'template', 'escape', 'error', 'A', 'I', 'L', 'M', 'S', 'X', 'U', 'ASCII', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL', 'VERBOSE', 'UNICODE']
>>>

Se han eliminado todas las funciones y clases con guiones bajos, dejando solo aquellas que se definen como públicas y, por lo tanto, se pueden usar a través de import *.

Tenga en cuenta que __all__no siempre se define. Si no está incluido, AttributeErrorse levanta un.

Un caso de esto es con el módulo ast:

>>> import ast
>>> ast.__all__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'ast' has no attribute '__all__'
>>>
Simón
fuente
4

Ninguna de estas respuestas funcionará si no puede importar dicho archivo Python sin errores de importación. Este fue el caso para mí cuando estaba inspeccionando un archivo que proviene de una gran base de código con muchas dependencias. Lo siguiente procesará el archivo como texto y buscará todos los nombres de métodos que comiencen con "def" y los imprimirán junto con sus números de línea.

import re
pattern = re.compile("def (.*)\(")
for i, line in enumerate(open('Example.py')):
  for match in re.finditer(pattern, line):
    print '%s: %s' % (i+1, match.groups()[0])
ckb
fuente
3
En este caso, es mucho mejor usar el astmódulo. Vea mi respuesta para un ejemplo.
csl
Creo que este es un método válido. ¿Por qué un voto negativo cuando lo hace?
m3nda
2

Excepto dir (módulo) o ayuda (módulo) mencionado en respuestas anteriores, también puede intentar:
- Abrir ipython
- importar nombre_módulo
- escribir nombre_módulo, presionar tabulador. Se abrirá una pequeña ventana con una lista de todas las funciones en el módulo de Python.
Se ve muy bien.

Aquí hay un fragmento que enumera todas las funciones del módulo hashlib

(C:\Program Files\Anaconda2) C:\Users\lenovo>ipython
Python 2.7.12 |Anaconda 4.2.0 (64-bit)| (default, Jun 29 2016, 11:07:13) [MSC v.1500 64 bit (AMD64)]
Type "copyright", "credits" or "license" for more information.

IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.

In [1]: import hashlib

In [2]: hashlib.
             hashlib.algorithms            hashlib.new                   hashlib.sha256
             hashlib.algorithms_available  hashlib.pbkdf2_hmac           hashlib.sha384
             hashlib.algorithms_guaranteed hashlib.sha1                  hashlib.sha512
             hashlib.md5                   hashlib.sha224
Saurya Man Patel
fuente
1

Esto agregará todas las funciones que están definidas en your_module en una lista.

result=[]
for i in dir(your_module):
    if type(getattr(your_module, i)).__name__ == "function":
        result.append(getattr(your_module, i))
Manish Kumar
fuente
¿Qué es esto unit8_conversion_methods? ¿Es esto solo un ejemplo del nombre del módulo?
nocibambi
@nocibambi sí, es solo un nombre de módulo.
Manish Kumar
2
gracias Manish. Propongo la siguiente alternativa de una línea:[getattr(your_module, func) for func in dir(your_module) if type(getattr(your_module, func)).__name__ == "function"]
amina
0

Puede usar el siguiente método para obtener una lista de todas las funciones en su módulo desde el shell:

import module

module.*?
Vishal Lamba
fuente
1
@GabrielFair, ¿en qué versión / plataforma está ejecutando Python? Me sale un error de sintaxis en Py3.7 / Win10.
toonarmycaptain
0
import sys
from inspect import getmembers, isfunction
fcn_list = [o[0] for o in getmembers(sys.modules[__name__], isfunction)]
eid
fuente
0
r = globals()
sep = '\n'+100*'*'+'\n' # To make it clean to read.
for k in list(r.keys()):
    try:
        if str(type(r[k])).count('function'):
            print(sep+k + ' : \n' + str(r[k].__doc__))
    except Exception as e:
        print(e)

Salida:

******************************************************************************************
GetNumberOfWordsInTextFile : 

    Calcule et retourne le nombre de mots d'un fichier texte
    :param path_: le chemin du fichier à analyser
    :return: le nombre de mots du fichier

******************************************************************************************

    write_in : 

        Ecrit les donnees (2nd arg) dans un fichier txt (path en 1st arg) en mode a,
        :param path_: le path du fichier texte
        :param data_: la liste des données à écrire ou un bloc texte directement
        :return: None


 ******************************************************************************************
    write_in_as_w : 

            Ecrit les donnees (2nd arg) dans un fichier txt (path en 1st arg) en mode w,
            :param path_: le path du fichier texte
            :param data_: la liste des données à écrire ou un bloc texte directement
            :return: None
Julien Faujanet
fuente