Como listar todas as funções em um módulo Python?

418

Eu tenho um módulo python instalado no meu sistema e gostaria de ver quais funções / classes / métodos estão disponíveis nele.

Eu quero chamar a função doc em cada um. Em ruby, posso fazer algo como ClassName.methods para obter uma lista de todos os métodos disponíveis nessa classe. Existe algo semelhante em python?

por exemplo. algo como:

from somemodule import foo
print foo.methods # or whatever is the correct method to call
Chris Gow
fonte
3
considere revisar a resposta selecionada! existem soluções melhores / mais fáceis de usar sugeridas em outras respostas.
Zahra

Respostas:

139

O inspectmódulo Veja também o pydocmódulo, a help()função no intérprete interativo e a pydocferramenta de linha de comando que gera a documentação que você procura. Você pode simplesmente dar a eles a classe da qual deseja ver a documentação. Eles também podem gerar, por exemplo, saída HTML e gravá-la no disco.

Thomas Wouters
fonte
3
Defendi o uso do astmódulo em determinadas situações na minha resposta .
CSL
28
TL; DR das respostas abaixo: use dirpara retornar funções e variáveis; use inspectpara filtrar apenas funções; e use astpara analisar sem importar.
Jonathan H
Vale a pena testar cada uma das abordagens resumidas por Sheljohn, pois a saída resultante é drasticamente diferente de uma solução para a seguinte.
clozach
1
@ Hack-R Aqui está o código para listar todas as funções em mymodule: [f [0] for f in inspect.getmembers (mymodule, inspect.isfunction)]
SurpriseDog
498

Você pode usar dir(module)para ver todos os métodos / atributos disponíveis. Verifique também PyDocs.

camflan
fonte
15
Isto não é estritamente verdade. A dir()função “tenta produzir as informações mais relevantes, e não completas”. Fonte: docs.python.org/library/functions.html#dir .
Zearin
15
@jAckOdE Quoted? Em seguida, você obterá métodos e atributos disponíveis do módulo string.
OrangeTux
@ OrangeTux: oops, isso deveria ser uma pergunta. sim, você respondeu.
JAckOdE
1
O OP claramente pede funções, não variáveis. Cf responde usando inspect.
Jonathan H
168

Depois de importeditar o módulo, você pode:

 help(modulename)

... Para obter os documentos de todas as funções de uma só vez, interativamente. Ou você pode usar:

 dir(modulename)

... Para simplesmente listar os nomes de todas as funções e variáveis ​​definidas no módulo.

Dan Lenski
fonte
1
@ sheljohn… qual é o objetivo dessa crítica? Minha solução também lista funções e o inspect módulo também pode listar variáveis, mesmo que não sejam explicitamente solicitadas aqui. Essa solução requer apenas objetos internos, o que pode ser muito útil em alguns casos em que o Python é instalado em um ambiente restrito / bloqueado / quebrado.
precisa
Obrigado, isso quase funcionou, mas eu pensei que diriria imprimir os resultados, no entanto, parece que você precisa fazer print(dir(modulename)).
Eliot
96

Um exemplo com inspecionar:

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 retorna uma lista de tuplas (object_name, object_type) tuplas.

Você pode substituir isfunction por qualquer uma das outras funções isXXX no módulo de inspeção.

adnan
fonte
27
getmemberspode usar um predicado, para que seu exemplo também possa ser escrito: functions_list = [o for o in getmembers(my_module, isfunction)]
Christopher Currie
27
@ChristopherCurrie, você também pode evitar a compreensão lista inútil com functions_list = getmembers(my_module, predicate)porque ele já retorna uma lista;)
Nil
5
Para descobrir se a função está definida nesse módulo (em vez de importada), adicione: to "if isfunction (o [1]) e o [1] .__ module__ == my_module .__ name__ " - observe que ela não funcionará necessariamente se a função importada vem de um módulo com o mesmo nome 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
fonte
8
. Por esta via, o uso getattr (SEUMODULO, um None) em vez de SEUMODULO .__ dict __ obter (a)
Thomas Wouters
4
your_module .__ dict__ é a minha escolha, porque você realmente recebe um ditado contendo functionName: <function> e agora tem a capacidade de CHAMAR essa função dinamicamente. bons tempos!
jsh
1
Python 3 amigável com algum açúcar: tipos de importação def print_module_functions (module): print ('\ n'.join ([str (module .__ dict __. Get (a) .__ name__) para a in dir (module) if isinstance (module. __dict __ obter (a), types.FunctionType)])).
y.selivonchyk
1
Isso também listará todas as funções que esse módulo importa. Isso pode ou não ser o que você deseja.
scubbo 10/06
48

Por uma questão de integridade, gostaria de salientar que às vezes você pode querer analisar o código em vez de importá-lo. Um importirá executar expressões de nível superior, e que poderia ser um problema.

Por exemplo, estou permitindo que os usuários selecionem funções de ponto de entrada para pacotes feitos com zipapp . O uso importe o inspectrisco de executar códigos extraviados, levando a falhas, ajudam a imprimir as mensagens, as caixas de diálogo da GUI são exibidas e assim por diante.

Em vez disso, uso o módulo ast para listar todas as funções de nível 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)

Colocando esse código list.pye usando-se como entrada, recebo:

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

É claro que navegar em um AST pode ser complicado às vezes, mesmo para uma linguagem relativamente simples como Python, porque o AST é de nível bastante baixo. Mas se você tiver um caso de uso simples e claro, é factível e seguro.

Porém, uma desvantagem é que você não pode detectar funções geradas em tempo de execução, como foo = lambda x,y: x*y.

csl
fonte
3
Eu gosto disso; Atualmente, estou tentando descobrir se alguém já escreveu uma ferramenta que faz algo como pydoc, mas sem importar o módulo. Até agora, este é o melhor exemplo que eu encontrei deste :)
James Mills
Concordou com esta resposta. Preciso que essa função funcione independentemente do que o arquivo de destino possa importar ou para qual versão do python ele foi escrito. Isso não ocorre nos problemas de importação que imp e importlib fazem.
Eric Evans
Que tal variáveis ​​do módulo ( __version__etc). Existe uma maneira de conseguir isso?
frakman1
29

Para o código que você não deseja analisar, recomendo a abordagem baseada em AST do @csl acima.

Para todo o resto, o módulo de inspeção está correto:

import inspect

import <module_to_inspect> as module

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

Isso fornece uma lista de duas tuplas no formulário [(<name:str>, <value:function>), ...].

A resposta simples acima é sugerida em várias respostas e comentários, mas não citada explicitamente.

Cireo
fonte
Obrigado por esclarecer; Eu acho que esta é a resposta certa, se você pode executar a importação no módulo para inspecionar.
Jonathan H
25

Isto irá fazer o truque:

dir(module) 

No entanto, se você achar irritante ler a lista retornada, use o seguinte loop para obter um nome por linha.

for i in dir(module): print i
Algorias
fonte
2
O OP claramente pede funções, não variáveis. Cf responde usando inspect. Além disso, como isso é diferente da resposta de @ DanLenski?
Jonathan H
20

dir(module) é a maneira padrão ao usar um script ou intérprete padrão, conforme mencionado na maioria das respostas.

No entanto, com um shell python interativo como o IPython, você pode usar o preenchimento de tabulação para obter uma visão geral de todos os objetos definidos no módulo. Isso é muito mais conveniente do que usar um script e printver o que está definido no módulo.

  • module.<tab> mostrará todos os objetos definidos no módulo (funções, classes e assim por diante)
  • module.ClassX.<tab> mostrará os métodos e atributos de uma classe
  • module.function_xy?ou module.ClassX.method_xy?mostrará a documentação dessa função / método
  • module.function_x??ou module.SomeClass.method_xy??mostrará o código fonte da função / método.
bmu
fonte
19

Para funções globais dir()é o comando a ser usado (como mencionado na maioria dessas respostas), no entanto, ele lista funções públicas e funções não públicas juntas.

Por exemplo, executando:

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

Retorna funções / classes como:

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

Alguns dos quais não são geralmente destinados para uso programação geral (mas pelo próprio módulo, exceto no caso de DunderAliases como __doc__, __file__ect). Por esse motivo, pode não ser útil listá-los com os públicos (é assim que o Python sabe o que obter ao usar from module import *).

__all__pode ser usado para resolver esse problema, ele retorna uma lista de todas as funções e classes públicas em um módulo (aquelas que não começam com sublinhados - _). Consulte Alguém pode explicar __all__ em Python? para o uso de __all__.

Aqui está um exemplo:

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

Todas as funções e classes com sublinhados foram removidas, deixando apenas aquelas definidas como públicas e, portanto, podem ser usadas via import *.

Observe que __all__nem sempre é definido. Se não estiver incluído, um AttributeErroré gerado.

Um caso disso é com o 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__'
>>>
Simon
fonte
4

Nenhuma dessas respostas funcionará se você não conseguir importar o referido arquivo Python sem erros de importação. Esse foi o meu caso quando eu estava inspecionando um arquivo que vem de uma grande base de código com muitas dependências. A seguir, o arquivo será processado como texto e procurará todos os nomes de métodos que começam com "def" e os imprimirá e seus números de linha.

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
fonte
3
Nesse caso, é muito melhor usar o astmódulo. Veja minha resposta para um exemplo.
CSL
Eu acho que esse é um método válido. Por que um voto negativo quando isso acontece?
M3nda 20/10
2

Exceto dir (módulo) ou ajuda (módulo) mencionados nas respostas anteriores, você também pode tentar:
- Abrir ipython
- importar module_name
- digite module_name, pressione tab. Ele abrirá uma pequena janela com uma lista de todas as funções no módulo python.
Parece muito arrumado.

Aqui está um trecho de lista de todas as funções do 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
fonte
1

Isso acrescentará todas as funções definidas em seu_módulo em uma lista.

result=[]
for i in dir(your_module):
    if type(getattr(your_module, i)).__name__ == "function":
        result.append(getattr(your_module, i))
Manish Kumar
fonte
O que é isso unit8_conversion_methods? Este é apenas um exemplo do nome do módulo?
nocibambi 23/07/19
@nocibambi sim, é apenas um nome de módulo.
Manish Kumar
2
obrigado Manish. Proponho a seguinte alternativa de uma linha:[getattr(your_module, func) for func in dir(your_module) if type(getattr(your_module, func)).__name__ == "function"]
amine
0

Você pode usar o seguinte método para obter uma lista de todas as funções do seu módulo a partir do shell:

import module

module.*?
Vishal Lamba
fonte
1
@GabrielFair em qual versão / plataforma você está executando o python? Eu recebo um erro de sintaxe no Py3.7 / Win10.
precisa saber é o seguinte
0
import sys
from inspect import getmembers, isfunction
fcn_list = [o[0] for o in getmembers(sys.modules[__name__], isfunction)]
eid
fonte
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)

Resultado :

******************************************************************************************
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
fonte