Come elencare tutte le funzioni in un modulo Python?


418

Ho un modulo Python installato sul mio sistema e mi piacerebbe poter vedere quali funzioni / classi / metodi sono disponibili in esso.

Voglio chiamare la funzione doc su ognuna. In ruby ​​posso fare qualcosa come ClassName.methods per ottenere un elenco di tutti i metodi disponibili su quella classe. C'è qualcosa di simile in Python?

per esempio. qualcosa di simile a:

from somemodule import foo
print foo.methods # or whatever is the correct method to call

3
si prega di considerare la revisione della risposta selezionata! ci sono soluzioni migliori / più facili da usare suggerite in altre risposte.
Zahra,

Risposte:


139

Il inspectmodulo. Vedi anche il pydocmodulo, la help()funzione nell'interprete interattivo e lo pydocstrumento da riga di comando che genera la documentazione che stai cercando. Puoi semplicemente dare loro la classe di cui desideri vedere la documentazione. Possono anche generare, ad esempio, output HTML e scriverlo su disco.


3
astNella mia risposta ho spiegato come utilizzare il modulo in determinate situazioni .
CSL il

28
TL; DR delle risposte di seguito: utilizzare dirper restituire funzioni e variabili; utilizzare solo inspectper filtrare le funzioni; e utilizzare astper analizzare senza importare.
Jonathan H,

Vale la pena testare ciascuno degli approcci riassunti da Sheljohn poiché l'output risultante è drasticamente diverso da una soluzione all'altra.
clozach,

1
@ Hack-R Ecco il codice per elencare tutte le funzioni in mymodule: [f [0] per f in inspect.getmembers (mymodule, inspect.isfunction)]
SurpriseDog

498

Puoi usare dir(module)per vedere tutti i metodi / attributi disponibili. Dai un'occhiata anche a PyDocs.


15
Questo non è strettamente vero. La dir()funzione "tenta di produrre le informazioni più pertinenti, piuttosto che complete". Fonte: docs.python.org/library/functions.html#dir .
Zearin,

15
@jAckOdE citato? Quindi otterrai i metodi e gli attributi disponibili del modulo stringa.
OrangeTux,

@OrangeTux: oops, quella dovrebbe essere una domanda. sì, hai risposto.
jAckOdE

1
L'OP chiede chiaramente funzioni, non variabili. Cf risponde usando inspect.
Jonathan H,

168

Dopo aver modificato importil modulo, puoi semplicemente fare:

 help(modulename)

... Per ottenere i documenti su tutte le funzioni contemporaneamente, in modo interattivo. Oppure puoi usare:

 dir(modulename)

... Per elencare semplicemente i nomi di tutte le funzioni e variabili definite nel modulo.


1
@ sheljohn ... qual è il punto di questa critica? La mia soluzione elenca anche le funzioni e il inspect modulo può anche elencare le variabili, anche se non esplicitamente richiesto qui. Questa soluzione richiede solo oggetti integrati, che può essere molto utile in alcuni casi in cui Python è installato in un ambiente vincolato / bloccato / rotto.
Dan Lenski,

Grazie, ha funzionato quasi, ma ho pensato che diravrebbe stampato i risultati, tuttavia sembra che tu debba farlo print(dir(modulename)).
Eliot,

96

Un esempio con inspect:

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 restituisce un elenco di tuple (nome_oggetto, tipo_oggetto).

È possibile sostituire isfunction con una qualsiasi delle altre funzioni isXXX nel modulo inspect.


27
getmemberspuò prendere un predicato, quindi il tuo esempio potrebbe anche essere scritto: functions_list = [o for o in getmembers(my_module, isfunction)]
Christopher Currie il

27
@ChristopherCurrie, potresti anche evitare l'inutile comprensione della lista functions_list = getmembers(my_module, predicate)perché restituisce già una lista;)
Nil

5
Per scoprire se la funzione è definita in quel modulo (piuttosto che importata) aggiungi: a "if isfunction (o [1]) e o [1] .__ module__ == my_module .__ name__ " - nota che non funzionerà necessariamente se la funzione importata proviene da un modulo con lo stesso nome di questo modulo.
Michael Scott Cuthbert,

72
import types
import yourmodule

print([getattr(yourmodule, a) for a in dir(yourmodule)
  if isinstance(getattr(yourmodule, a), types.FunctionType)])

8
Per questo percorso, utilizza getattr (yourmodule, a, None) anziché yourmodule .__ dict __. Get (a)
Thomas Wouters,

4
your_module .__ dict__ è la mia scelta perché in realtà ottieni un dict contenente functionName: <function> e ora hai la possibilità di CHIAMARE dinamicamente quella funzione. bei tempi!
jsh,

1
Python 3 amichevole con un po 'di zucchero: tipi di importazione def print_module_functions (modulo): print (' \ n'.join ([str (module .__ dict __. Get (a) .__ name__) per a in dir (module) se isinstance (module. __dict __. get (a), types.FunctionType)]))
y.selivonchyk

1
Questo elencherà anche tutte le funzioni che quel modulo importa. Potrebbe essere o meno quello che vuoi.
scubbo,

48

Per completezza, vorrei sottolineare che a volte potresti voler analizzare il codice invece di importarlo. Una importsarà eseguito le espressioni di livello superiore, e che potrebbe essere un problema.

Ad esempio, sto permettendo agli utenti di selezionare le funzioni del punto di ingresso per i pacchetti creati con zipapp . Utilizzando importeinspect rischio di eseguire codice fuorviato, causando arresti anomali, aiutano a stampare i messaggi, vengono visualizzate finestre di dialogo della GUI e così via.

Invece uso il modulo ast per elencare tutte le funzioni di livello superiore:

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)

Inserendo questo codice list.pye usando se stesso come input, ottengo:

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

Certo, a volte navigare in un AST può essere complicato, anche per un linguaggio relativamente semplice come Python, perché l'AST è di livello piuttosto basso. Ma se hai un caso d'uso semplice e chiaro, è fattibile e sicuro.

Tuttavia, un aspetto negativo è che non è possibile rilevare funzioni generate in fase di esecuzione, come foo = lambda x,y: x*y.


3
Mi piace questo; Attualmente sto cercando di scoprire se qualcuno ha già scritto uno strumento che fa qualcosa di simile a pydoc ma senza importare il modulo. Finora questo è il miglior esempio che ho trovato su questo :)
James Mills il

Concordato con questa risposta. Ho bisogno che questa funzione funzioni indipendentemente da ciò che il file di destinazione può importare o per quale versione di Python è stata scritta. Questo non si verifica nei problemi di importazione che imp e importlib fanno.
Eric Evans,

Che ne dici di variabili del modulo ( __version__ecc.). C'è un modo per ottenerlo?
frakman1,

29

Per il codice che non si desidera analizzare, si consiglia l'approccio basato su AST di @csl sopra.

Per tutto il resto, il modulo inspect è corretto:

import inspect

import <module_to_inspect> as module

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

Questo fornisce un elenco di 2 tuple nel modulo [(<name:str>, <value:function>), ...].

La semplice risposta sopra è accennata in varie risposte e commenti, ma non chiamata esplicitamente.


Grazie per averlo spiegato; Penso che questa sia la risposta giusta, se è possibile eseguire l'importazione sul modulo per ispezionare.
Jonathan H,

25

Questo farà il trucco:

dir(module) 

Tuttavia, se trovi fastidioso leggere l'elenco restituito, usa il seguente ciclo per ottenere un nome per riga.

for i in dir(module): print i

2
L'OP chiede chiaramente funzioni, non variabili. Cf risponde usando inspect. Inoltre, in che modo differisce dalla risposta di @ DanLenski?
Jonathan H,

20

dir(module) è il modo standard quando si utilizza uno script o l'interprete standard, come indicato nella maggior parte delle risposte.

Tuttavia con una shell interattiva in Python come IPython è possibile utilizzare il completamento con tabulazione per ottenere una panoramica di tutti gli oggetti definiti nel modulo. Questo è molto più conveniente rispetto all'utilizzo di uno script e printper vedere cosa è definito nel modulo.

  • module.<tab> ti mostrerà tutti gli oggetti definiti nel modulo (funzioni, classi e così via)
  • module.ClassX.<tab> ti mostrerà i metodi e gli attributi di una classe
  • module.function_xy?o module.ClassX.method_xy?ti mostrerà la documentazione di quella funzione / metodo
  • module.function_x??o module.SomeClass.method_xy??ti mostrerà il codice sorgente della funzione / metodo.

19

Per le funzioni globali dir()è il comando da usare (come menzionato nella maggior parte di queste risposte), tuttavia questo elenca insieme sia le funzioni pubbliche che quelle non pubbliche.

Ad esempio in esecuzione:

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

Restituisce funzioni / classi come:

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

Alcuni dei quali non sono generalmente pensati per un uso generale della programmazione (ma dal modulo stesso, tranne nel caso di DunderAliases come __doc__, __file__ecc.). Per questo motivo potrebbe non essere utile elencarli con quelli pubblici (questo è il modo in cui Python sa cosa ottenere durante l'utilizzo from module import *).

__all__potrebbe essere usato per risolvere questo problema, restituisce un elenco di tutte le funzioni e classi pubbliche in un modulo (quelle che non iniziano con caratteri di sottolineatura - _). Vedi Qualcuno può spiegare __all__ in Python? per l'uso di __all__.

Ecco un esempio:

>>> 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']
>>>

Tutte le funzioni e le classi con caratteri di sottolineatura sono state rimosse, lasciando solo quelle che sono definite come pubbliche e possono quindi essere utilizzate tramite import *.

Si noti che __all__non è sempre definito. Se non è incluso, quindi unAttributeError viene sollevato un.

Un caso di questo è con il modulo ast:

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

4

Nessuna di queste risposte funzionerà se non sei in grado di importare detto file Python senza errori di importazione. Questo è stato il caso per me quando stavo ispezionando un file che proviene da una grande base di codice con molte dipendenze. Di seguito elabora il file come testo e cerca tutti i nomi di metodi che iniziano con "def" e li stampa e i loro numeri di riga.

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])

3
In questo caso è molto meglio usare il astmodulo. Vedi la mia risposta per un esempio.
CSL il

Penso che questo sia un metodo valido. Perché un downvote quando lo fa?
m3nda,

2

Tranne dir (modulo) o help (modulo) menzionato nelle risposte precedenti, puoi anche provare:
- Apri ipython
- importa nome_modulo
- digita nome_modulo, premi tab. Si aprirà una piccola finestra con l'elenco di tutte le funzioni nel modulo Python.
Sembra molto pulito.

Ecco lo snippet che elenca tutte le funzioni del modulo 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

1

Questo aggiungerà tutte le funzioni definite in your_module in un elenco.

result=[]
for i in dir(your_module):
    if type(getattr(your_module, i)).__name__ == "function":
        result.append(getattr(your_module, i))

Che cos'è questo unit8_conversion_methods? Questo è solo un esempio del nome del modulo?
nocibambi,

@nocibambi sì, è solo un nome di modulo.
Manish Kumar il

2
grazie Manish. Propongo la seguente alternativa di una riga:[getattr(your_module, func) for func in dir(your_module) if type(getattr(your_module, func)).__name__ == "function"]
ammina

0

Puoi usare il seguente metodo per ottenere dalla shell tutte le funzioni del tuo modulo:

import module

module.*?

1
@GabrielFair su quale versione / piattaforma stai eseguendo Python? Ottengo un errore di sintassi su Py3.7 / Win10.
toonarmycaptain

0
import sys
from inspect import getmembers, isfunction
fcn_list = [o[0] for o in getmembers(sys.modules[__name__], isfunction)]

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)

Produzione :

******************************************************************************************
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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.