Как перечислить все функции в модуле Python?

418

У меня установлен модуль Python в моей системе, и я хотел бы видеть, какие функции / классы / методы доступны в нем.

Я хочу, чтобы вызвать функцию док на каждом. В ruby ​​я могу сделать что-то вроде ClassName.methods, чтобы получить список всех методов, доступных в этом классе. Есть ли что-то подобное в питоне?

например. что-то вроде:

from somemodule import foo
print foo.methods # or whatever is the correct method to call
Крис Гоу
источник
3
пожалуйста, рассмотрите обзор выбранного ответа! Есть лучшие / более простые в использовании решения, предложенные в других ответах.
Захра

Ответы:

139

inspectМодуль. Также см. pydocМодуль, help()функцию в интерактивном интерпретаторе и pydocинструмент командной строки, который генерирует необходимую документацию. Вы можете просто дать им класс, который вы хотите увидеть в документации. Они также могут генерировать, например, вывод HTML и записывать его на диск.

Томас Воутерс
источник
3
В моем ответе я изложил причину использования astмодуля в определенных ситуациях .
csl
28
TL; DR ответов ниже: используйте dirдля возврата функций и переменных; использовать только inspectдля фильтрации функций; и использовать astдля анализа без импорта.
Джонатан Х
Стоит опробовать каждый из подходов, обобщенных Шелджоном, поскольку результирующий результат резко отличается от одного решения к другому.
Clozach
1
@ Hack-R Вот код для перечисления всех функций в моем модуле: [f [0] для f в inspect.getmembers (mymodule, inspect.isfunction)]
SurpriseDog
498

Вы можете использовать, dir(module)чтобы увидеть все доступные методы / атрибуты. Также проверьте PyDocs.

camflan
источник
15
Это не совсем верно. В dir()функции «попытки получить самую актуальную, а не полную, информацию». Источник: docs.python.org/library/functions.html#dir .
Зерин
15
@jAckOdE Цитируется? Затем вы получите доступные методы и атрибуты строкового модуля.
OrangeTux
@OrangeTux: ой, это должен быть вопрос. да, вы ответили
JAckOdE
1
ОП явно запрашивает функции, а не переменные. Cf ответы с помощью inspect.
Джонатан Х
168

После того, как вы отредактировали importмодуль, вы можете просто сделать:

 help(modulename)

... Чтобы получить документы на все функции одновременно, в интерактивном режиме. Или вы можете использовать:

 dir(modulename)

... Чтобы просто перечислить имена всех функций и переменных, определенных в модуле.

Дэн Ленски
источник
1
@ шелджон ... какой смысл этой критики? Мое решение также перечисляет функции, и inspect модуль может также перечислять переменные, хотя здесь явно не запрашивается. Это решение требует только встроенных объектов, что может быть очень полезно в некоторых случаях, когда Python установлен в ограниченной / заблокированной / сломанной среде.
Дэн Ленски
Спасибо, это почти сработало, но я думал, dirчто напечатает результаты, однако, похоже, что вам нужно сделать print(dir(modulename)).
Элиот
96

Пример с проверкой:

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 возвращает список кортежей (object_name, object_type).

Вы можете заменить функцию isfunction любой другой функцией isXXX в модуле проверки.

Аднан
источник
27
getmembersможно использовать предикат, поэтому ваш пример также может быть записан: functions_list = [o for o in getmembers(my_module, isfunction)]
Кристофер Керри
27
@ChristopherCurrie, вы могли бы также избежать бесполезного список понимание с , functions_list = getmembers(my_module, predicate)потому что это уже возвращает список;)
Nil
5
Чтобы определить, определена ли функция в этом модуле (а не импортирована), добавьте: в «if isfunction (o [1]) и o [1] .__ module__ == my_module .__ name__ » - обратите внимание, что она не будет работать обязательно, если импортированная функция происходит из модуля с тем же именем, что и у этого модуля.
Майкл Скотт Катберт
72
import types
import yourmodule

print([getattr(yourmodule, a) for a in dir(yourmodule)
  if isinstance(getattr(yourmodule, a), types.FunctionType)])
Oli
источник
8
Для этого маршрута используйте getattr (yourmodule, a, None) вместо yourmodule .__ dict __. Get (a)
Томас Воутерс
4
your_module .__ dict__ - мой выбор, потому что вы фактически получаете dict, содержащий functionName: <function>, и теперь у вас есть возможность вызывать эту функцию динамически. хорошие времена!
JSH
1
Python 3 дружественен к некоторому сахару: типы импорта def print_module_functions (module): print ('\ n'.join ([str (module .__ dict __. Get (a) .__ name__)) для in in dir (модуль), если isinstance (модуль). __dict __. get (a), types.FunctionType)]))
y.selivonchyk
1
Это также перечислит все функции, которые импортирует этот модуль. Это может или не может быть то, что вы хотите.
подводное
48

Для полноты картины я хотел бы отметить, что иногда вы можете захотеть разобрать код, а не импортировать его. importБудет выполнять выражения верхнего уровня, и это может быть проблемой.

Например, я позволяю пользователям выбирать функции точки входа для пакетов, создаваемых с помощью zipapp . Использование importи inspectриск запуска ошибочного кода, приводящего к сбоям, выводу справочных сообщений, появлению диалоговых окон GUI и так далее.

Вместо этого я использую модуль ast, чтобы перечислить все функции верхнего уровня:

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)

Поместив этот код list.pyи используя себя в качестве ввода, я получаю:

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

Конечно, навигация по AST иногда бывает сложной, даже для относительно простого языка, такого как Python, потому что AST довольно низкоуровневый. Но если у вас есть простой и понятный вариант использования, он выполним и безопасен.

Однако недостатком является то, что вы не можете обнаружить функции, которые генерируются во время выполнения, например foo = lambda x,y: x*y.

CSL
источник
3
Мне это нравится; В настоящее время я пытаюсь выяснить, если кто-то уже написал инструмент, который делает что-то вроде pydoc, но без импорта модуля. Пока это лучший пример, который я нашел в этом :)
Джеймс Миллс
Согласился с этим ответом. Мне нужно, чтобы эта функция работала независимо от того, какой целевой файл может импортироваться или для какой версии python он написан. Это не приводит к проблемам с импортом, которые делают imp и importlib.
Эрик Эванс
Как насчет переменных модуля (и __version__т. Д.). Есть ли способ получить это?
frakman1
29

Для кода, который вы не хотите анализировать, я рекомендую основанный на AST подход @csl выше.

В остальном модуль проверки корректен:

import inspect

import <module_to_inspect> as module

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

Это дает список из 2-х кортежей в форме [(<name:str>, <value:function>), ...].

Простой ответ выше намекается в различных ответах и ​​комментариях, но не вызывается явно.

Cireo
источник
Спасибо за разъяснение; Я думаю, что это правильный ответ, если вы можете запустить импорт модуля для проверки.
Джонатан Х
25

Это сделает свое дело:

dir(module) 

Однако, если вам неудобно читать возвращенный список, просто используйте следующий цикл, чтобы получить по одному имени в строке.

for i in dir(module): print i
Algorias
источник
2
ОП явно запрашивает функции, а не переменные. Cf ответы с помощью inspect. Кроме того, как это отличается от ответа @ DanLenski?
Джонатан Х
20

dir(module) это стандартный способ при использовании сценария или стандартного интерпретатора, как упоминалось в большинстве ответов.

Однако с интерактивной оболочкой Python, такой как IPython, вы можете использовать табуляцию, чтобы получить обзор всех объектов, определенных в модуле. Это гораздо удобнее, чем использовать скрипт и printпосмотреть, что определено в модуле.

  • module.<tab> покажет вам все объекты, определенные в модуле (функции, классы и т. д.)
  • module.ClassX.<tab> покажет вам методы и атрибуты класса
  • module.function_xy?или module.ClassX.method_xy?покажет вам строку документации этой функции / метода
  • module.function_x??или module.SomeClass.method_xy??покажет вам исходный код функции / метода.
БМУ
источник
19

Для глобальных функций dir()это команда для использования (как упоминалось в большинстве этих ответов), однако в этом списке перечислены как публичные функции, так и непубличные функции.

Например работает:

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

Возвращает функции / классы, такие как:

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

Некоторые из них, как правило, не предназначены для общего использования в программировании (но самим модулем, за исключением случая с DunderAliases, например __doc__, __file__ect). По этой причине может быть бесполезно перечислять их с общедоступными (именно так Python знает, что получить при использовании from module import *).

__all__может быть использован для решения этой проблемы, он возвращает список всех открытых функций и классов в модуле (те, которые не начинаются с подчеркивания - _). См. Кто-нибудь может объяснить __all__ в Python? для использования __all__.

Вот пример:

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

Все функции и классы с подчеркиванием были удалены, оставив только те, которые определены как публичные и поэтому могут использоваться через import *.

Обратите внимание, что __all__это не всегда определяется. Если он не включен, то AttributeErrorподнимается.

Случай этого с модулем ast:

>>> import ast
>>> ast.__all__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'ast' has no attribute '__all__'
>>>
Саймон
источник
4

Ни один из этих ответов не будет работать, если вы не можете импортировать указанный файл Python без ошибок импорта. Это было так для меня, когда я проверял файл, полученный из большой базы кода с большим количеством зависимостей. Следующее будет обрабатывать файл как текст и искать все имена методов, начинающиеся с «def», и печатать их и номера строк.

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
В этом случае гораздо лучше использовать astмодуль. Смотрите мой ответ для примера.
csl
Я думаю, что это правильный метод. Зачем понижать голос, когда это происходит?
m3nda
2

Кроме dir (module) или help (module), упомянутых в предыдущих ответах, вы также можете попробовать:
- открыть ipython
- import имя_модуля
- ввести имя_модуля, нажать tab. Откроется небольшое окно со списком всех функций в модуле python.
Это выглядит очень аккуратно.

Вот фрагмент списка всех функций модуля 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
источник
1

Это добавит все функции, которые определены в your_module в список.

result=[]
for i in dir(your_module):
    if type(getattr(your_module, i)).__name__ == "function":
        result.append(getattr(your_module, i))
Маниш Кумар
источник
Что это unit8_conversion_methods? Это просто пример имени модуля?
Ноцибамби
@nocibambi да, это просто имя модуля.
Маниш Кумар
2
спасибо Маниш. Я предлагаю следующую однострочную альтернативу:[getattr(your_module, func) for func in dir(your_module) if type(getattr(your_module, func)).__name__ == "function"]
амин
0

Вы можете использовать следующий метод, чтобы получить список всех функций вашего модуля из оболочки:

import module

module.*?
Вишал Ламба
источник
1
@GabrielFair на какой версии / платформе вы используете python? Я получаю синтаксическую ошибку на 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)

Вывод :

******************************************************************************************
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
Жюльен Фожане
источник