Jak wyświetlić listę wszystkich funkcji w module Python?

418

Mam moduł Pythona zainstalowany w moim systemie i chciałbym móc zobaczyć, jakie funkcje / klasy / metody są w nim dostępne.

Chcę wywołać funkcję doc na każdym z nich. W Ruby mogę zrobić coś takiego jak ClassName.methods, aby uzyskać listę wszystkich metod dostępnych w tej klasie. Czy w Pythonie jest coś podobnego?

na przykład. coś jak:

from somemodule import foo
print foo.methods # or whatever is the correct method to call
Chris Gow
źródło
3
rozważ przejrzenie wybranej odpowiedzi! istnieją lepsze / łatwiejsze w użyciu rozwiązania sugerowane w innych odpowiedziach.
Zahra,

Odpowiedzi:

139

inspectModuł. Zobacz także pydocmoduł, help()funkcję interaktywnego interpretera i pydocnarzędzie wiersza poleceń, które generuje poszukiwaną dokumentację. Możesz po prostu dać im klasę, której dokumentację chcesz zobaczyć. Mogą również generować na przykład dane wyjściowe HTML i zapisywać je na dysku.

Thomas Wouters
źródło
3
astW mojej odpowiedzi uzasadniłem użycie modułu w określonych sytuacjach .
csl
28
TL; DR odpowiedzi poniżej: służy dirdo zwracania funkcji i zmiennych; służy inspectdo filtrowania tylko funkcji; i użyj astdo parsowania bez importowania.
Jonathan H
Warto przetestować każde z podejść podsumowanych przez Sheljohna, ponieważ uzyskana wydajność różni się drastycznie od jednego rozwiązania do drugiego.
clozach
1
@ Hack-R Oto kod, aby wyświetlić listę wszystkich funkcji w mymodule: [f [0] dla fw inspect.getmembers (mymodule, inspect.isfunction)]
SurpriseDog
498

Możesz użyć, dir(module)aby zobaczyć wszystkie dostępne metody / atrybuty. Sprawdź także PyDocs.

camflan
źródło
15
To nie jest do końca prawda. W dir()funkcji „próby wytworzenia najbardziej istotne, niż kompletną informację”. Źródło: docs.python.org/library/functions.html#dir .
Zearin,
15
@jAckOdE Cytowany? Następnie otrzymasz dostępne metody i atrybuty modułu ciągu.
OrangeTux
@OrangeTux: ups, to powinno być pytanie. tak, odpowiedziałeś na to.
jAckOdE
1
OP wyraźnie prosi o funkcje, a nie zmienne. Por. Odpowiedzi za pomocą inspect.
Jonathan H
168

Po importedycji modułu możesz po prostu:

 help(modulename)

... Aby uzyskać dokumenty dotyczące wszystkich funkcji jednocześnie, interaktywnie. Lub możesz użyć:

 dir(modulename)

... Aby po prostu wymienić nazwy wszystkich funkcji i zmiennych zdefiniowanych w module.

Dan Lenski
źródło
1
@ sheljohn… jaki jest sens tej krytyki? Moje rozwiązanie zawiera również listę funkcji, a inspect moduł może również wyświetlać zmienne, nawet jeśli nie jest to wyraźnie wymagane. To rozwiązanie wymaga tylko wbudowanych obiektów, co może być bardzo przydatne w niektórych przypadkach, w których Python jest zainstalowany w środowisku ograniczonym / zablokowanym / uszkodzonym.
Dan Lenski
Dzięki, to prawie działało, ale pomyślałem, dirże wydrukuje wyniki, ale wygląda na to, że musisz to zrobić print(dir(modulename)).
Eliot
96

Przykład z inspekcją:

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 zwraca listę krotek (nazwa_obiektu, typ_obiektu).

Możesz zastąpić isfunkcję dowolną inną funkcją isXXX w module inspekcji.

adnan
źródło
27
getmembersmoże przyjąć predykat, aby można było napisać przykład: functions_list = [o for o in getmembers(my_module, isfunction)]
Christopher Currie,
27
@ChristopherCurrie, można również uniknąć niepotrzebnego zrozumienia listy, functions_list = getmembers(my_module, predicate)ponieważ zwraca ona już listę;)
zero
5
Aby sprawdzić, czy funkcja jest zdefiniowana w tym module (a nie zaimportowana), dodaj: do „if isfunction (o [1]) i o [1] .__ module__ == mój_moduł .__ nazwa__ ” - pamiętaj, że niekoniecznie będzie działać, jeśli importowana funkcja pochodzi z modułu o tej samej nazwie co ten moduł.
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
źródło
8
Na tej trasie użyj getattr (twój moduł, a, Brak) zamiast swojego modułu .__ dict __. Get (a)
Thomas Wouters
4
twój_moduł .__ dict__ jest moim wyborem, ponieważ faktycznie dostajesz dyk zawierający functionName: <funkcja> i masz teraz możliwość wywoływania tej funkcji dynamicznie. dobre czasy!
jsh
1
Python 3 przyjazny dla niektórych cukrów: typy importu def print_module_functions (module): print ('\ n' .join ([str (moduł .__ dict __. Get (a) .__ name__) dla in in dir (module) if isinstance (module. __dict __. get (a), types.FunctionType)]))
y.selivonchyk
1
Spowoduje to również wyświetlenie wszystkich funkcji importowanych przez ten moduł. To może, ale nie musi być to, czego chcesz.
scubbo
47

Dla kompletności chciałbym zauważyć, że czasami możesz chcieć przeanalizować kod zamiast go importować. importBędzie wykonać wyrażenia najwyższego poziomu, a to może być problem.

Na przykład pozwalam użytkownikom wybrać funkcje punktu wejścia dla pakietów tworzonych za pomocą zipappa . Używanie importi inspectryzyko uruchomienia błędnego kodu, co prowadzi do awarii, pomaga drukować komunikaty, wyświetla się okna dialogowe GUI i tak dalej.

Zamiast tego używam modułu ast , aby wyświetlić listę wszystkich funkcji najwyższego poziomu:

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)

Umieszczając ten kod list.pyi wykorzystując go jako dane wejściowe, otrzymuję:

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

Oczywiście nawigacja w AST może być czasem trudna, nawet w przypadku stosunkowo prostego języka, takiego jak Python, ponieważ poziom AST jest dość niski. Ale jeśli masz prosty i przejrzysty przypadek użycia, jest to wykonalne i bezpieczne.

Jednak wadą jest to, że nie można wykryć funkcji generowanych w czasie wykonywania, takich jak foo = lambda x,y: x*y.

csl
źródło
2
Lubię to; Obecnie próbuję dowiedzieć się, czy ktoś napisał już narzędzie, które robi coś takiego jak pydoc, ale nie importuje modułu. Jak dotąd jest to najlepszy przykład, jaki znalazłem :)
James Mills,
Zgodził się z tą odpowiedzią. Potrzebuję tej funkcji do działania niezależnie od tego, co plik docelowy może zaimportować lub dla jakiej wersji języka Python jest napisany. Nie dotyczy to problemów z importem, które powodują imp i importlib.
Eric Evans,
A co ze zmiennymi modułowymi ( __version__itp.). Czy istnieje sposób na uzyskanie tego?
frakman1
29

W przypadku kodu, którego nie chcesz analizować, zalecam podejście oparte na AST @csl powyżej.

W pozostałych przypadkach moduł sprawdzania jest poprawny:

import inspect

import <module_to_inspect> as module

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

Daje to listę 2-krotek w formularzu [(<name:str>, <value:function>), ...].

Prosta odpowiedź powyżej jest podana w różnych odpowiedziach i komentarzach, ale nie jest wyraźnie wzywana.

Cireo
źródło
Dzięki, że to przeliterowałeś; Myślę, że to właściwa odpowiedź, jeśli możesz uruchomić importowanie modułu w celu sprawdzenia.
Jonathan H
25

To załatwi sprawę:

dir(module) 

Jeśli jednak irytujesz czytanie przeczytanej listy, po prostu użyj następującej pętli, aby uzyskać jedną nazwę w wierszu.

for i in dir(module): print i
Algorias
źródło
2
OP wyraźnie prosi o funkcje, a nie zmienne. Por. Odpowiedzi za pomocą inspect. Poza tym, czym różni się to od odpowiedzi @ DanLenski?
Jonathan H
20

dir(module) jest standardowym sposobem korzystania ze skryptu lub standardowego interpretera, jak wspomniano w większości odpowiedzi.

Jednak dzięki interaktywnej powłoce pythonowej, takiej jak IPython , można użyć tabulacji, aby uzyskać przegląd wszystkich obiektów zdefiniowanych w module. Jest to o wiele wygodniejsze niż używanie skryptu i printsprawdzanie, co jest zdefiniowane w module.

  • module.<tab> pokaże wszystkie obiekty zdefiniowane w module (funkcje, klasy i tak dalej)
  • module.ClassX.<tab> pokaże metody i atrybuty klasy
  • module.function_xy? lub module.ClassX.method_xy? pokaże ci dokumentację tej funkcji / metody
  • module.function_x??lub module.SomeClass.method_xy??pokaże kod źródłowy funkcji / metody.
bmu
źródło
19

W przypadku funkcji globalnych dir()należy użyć polecenia (jak wspomniano w większości tych odpowiedzi), jednak zawiera ono zarówno funkcje publiczne, jak i funkcje niepubliczne.

Na przykład bieganie:

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

Zwraca funkcje / klasy, takie jak:

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

Niektóre z nich zasadniczo nie są przeznaczone do ogólnego użytku w programowaniu (ale przez sam moduł, z wyjątkiem DunderAliases, takich jak __doc__, __file__ect). Z tego powodu może być nieprzydatne, aby wymienić je na publiczne (w ten sposób Python wie, co uzyskać, używając from module import *).

__all__może być użyty do rozwiązania tego problemu, zwraca listę wszystkich funkcji publicznych i klas w module (tych, które nie zaczynają się od podkreślenia - _). Zobacz Czy ktoś może wyjaśnić __all__ w Pythonie? do użytku __all__.

Oto przykład:

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

Wszystkie funkcje i klasy ze znakami podkreślenia zostały usunięte, pozostawiając tylko te, które są zdefiniowane jako publiczne i dlatego mogą być używane przez import *.

Pamiętaj, że __all__nie zawsze jest zdefiniowane. Jeśli nie jest uwzględniony, to AttributeErrorjest podnoszony.

Przykładem może być moduł ast:

>>> import ast
>>> ast.__all__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'ast' has no attribute '__all__'
>>>
Szymon
źródło
4

Żadna z tych odpowiedzi nie zadziała, jeśli nie będzie można zaimportować wspomnianego pliku Python bez błędów importu. Tak było w przypadku, gdy sprawdzałem plik pochodzący z dużej bazy kodu z wieloma zależnościami. Poniżej przetworzy plik jako tekst i wyszuka wszystkie nazwy metod zaczynające się od „def” i wydrukuje je wraz z numerami wierszy.

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
źródło
3
W takim przypadku znacznie lepiej jest użyć astmodułu. Zobacz moją odpowiedź na przykład.
csl
Myślę, że to jest poprawna metoda. Po co głosować negatywnie, kiedy to robi?
m3nda
2

Poza katalogiem (moduł) lub pomocą (moduł) wspomnianym w poprzednich odpowiedziach możesz także spróbować:
- Otwórz ipython
- import nazwa_modułu
- wpisz nazwa_modułu, naciśnij klawisz tab. Otworzy małe okno z listą wszystkich funkcji w module python.
Wygląda bardzo schludnie.

Oto fragment listy wszystkich funkcji modułu 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
źródło
1

Spowoduje to dodanie do listy wszystkich funkcji zdefiniowanych w module_urządzenia.

result=[]
for i in dir(your_module):
    if type(getattr(your_module, i)).__name__ == "function":
        result.append(getattr(your_module, i))
Manish Kumar
źródło
Co to unit8_conversion_methodsjest Czy to tylko przykład nazwy modułu?
nocibambi
@nocibambi tak, to tylko nazwa modułu.
Manish Kumar
2
dzięki Manish. Proponuję następującą liniową alternatywę:[getattr(your_module, func) for func in dir(your_module) if type(getattr(your_module, func)).__name__ == "function"]
amina
0

Możesz użyć następującej metody, aby uzyskać listę wszystkich funkcji w module z powłoki:

import module

module.*?
Vishal Lamba
źródło
1
@GabrielFair na jakiej wersji / platformie używasz Pythona? Otrzymuję błąd składniowy na 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
źródło
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)

Wynik :

******************************************************************************************
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
źródło