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

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.


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.


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.


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.


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

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.


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.


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

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.

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

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

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

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

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.*?

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

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.