Làm thế nào để liệt kê tất cả các chức năng trong một mô-đun Python?


418

Tôi có một mô-đun python được cài đặt trên hệ thống của mình và tôi muốn có thể xem các chức năng / lớp / phương thức nào có sẵn trong nó.

Tôi muốn gọi hàm doc trên mỗi cái. Trong ruby ​​tôi có thể làm một cái gì đó như ClassName.methods để có được danh sách tất cả các phương thức có sẵn trên lớp đó. Có một cái gì đó tương tự trong python?

ví dụ. cái gì đó như:

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

3
vui lòng xem xét xem xét câu trả lời được lựa chọn! có những giải pháp tốt hơn / dễ sử dụng hơn được đề xuất trong các câu trả lời khác.
Zahra

Câu trả lời:


139

Các inspectmô-đun. Cũng xem pydocmô-đun, help()chức năng trong trình thông dịch tương tác và pydoccông cụ dòng lệnh tạo tài liệu bạn đang theo dõi. Bạn chỉ có thể cung cấp cho họ lớp bạn muốn xem tài liệu của. Họ cũng có thể tạo ra, ví dụ, đầu ra HTML và ghi nó vào đĩa.


3
Tôi đã tạo ra trường hợp sử dụng astmô-đun trong các tình huống nhất định trong câu trả lời của tôi .
csl

28
TL; DR của các câu trả lời dưới đây: sử dụng dirđể trả về các hàm và biến; chỉ sử dụng inspectđể lọc các chức năng; và sử dụng astđể phân tích mà không cần nhập khẩu.
Jonathan H

Thật đáng để thử nghiệm từng phương pháp được Sheljohn tóm tắt vì kết quả đầu ra khác biệt lớn từ giải pháp này đến giải pháp tiếp theo.
clozach

1
@ Hack-R Đây là mã để liệt kê tất cả các chức năng trong mymodule: [f [0] cho f trong tests.getmembers (mymodule, tests.isfeft)]
SurpriseDog

498

Bạn có thể sử dụng dir(module)để xem tất cả các phương thức / thuộc tính có sẵn. Ngoài ra hãy kiểm tra PyDocs.


15
Điều này không đúng. Các dir()chức năng “nỗ lực để sản xuất phù hợp nhất, chứ không phải là đầy đủ, thông tin”. Nguồn: docs.python.org/l Library / fiances.html # ir .
Zearin

15
@jAckOdE Trích dẫn? Sau đó, bạn sẽ nhận được các phương thức và thuộc tính có sẵn của mô-đun chuỗi.
OrangeTux

@OrangeTux: Rất tiếc, đó là một câu hỏi. yeap, bạn đã trả lời nó
jAckOdE

1
OP yêu cầu rõ ràng về các chức năng, không phải các biến. Cf trả lời bằng cách sử dụng inspect.
Jonathan H

168

Khi bạn đã importchỉnh sửa mô-đun, bạn có thể thực hiện:

 help(modulename)

... Để có được các tài liệu trên tất cả các chức năng cùng một lúc, tương tác. Hoặc bạn có thể sử dụng:

 dir(modulename)

... Để chỉ liệt kê tên của tất cả các hàm và biến được định nghĩa trong mô-đun.


1
@ Sheljohn gay những gì điểm của phê bình này? Giải pháp của tôi cũng liệt kê các hàm và inspect mô-đun cũng có thể liệt kê các biến, mặc dù không được yêu cầu rõ ràng ở đây. Giải pháp này chỉ yêu cầu các đối tượng tích hợp sẵn, có thể rất hữu ích trong một số trường hợp Python được cài đặt trong môi trường bị ràng buộc / khóa / hỏng.
Dan Lenski

Cảm ơn, điều này gần như đã làm việc, nhưng tôi nghĩ rằng dirsẽ in kết quả, tuy nhiên có vẻ như bạn cần phải làm print(dir(modulename)).
Eliot

96

Một ví dụ với thanh tra:

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 trả về một danh sách các bộ dữ liệu (object_name, object_type).

Bạn có thể thay thế chức năng bằng bất kỳ chức năng isXXX nào khác trong mô-đun kiểm tra.


27
getmemberscó thể lấy một vị ngữ, vì vậy ví dụ của bạn cũng có thể được viết: functions_list = [o for o in getmembers(my_module, isfunction)]
Christopher Currie

27
@ChristopherCurrie, bạn cũng có thể tránh việc hiểu danh sách vô dụng functions_list = getmembers(my_module, predicate)vì nó đã trả về một danh sách;)
Nil

5
Để tìm xem hàm có được xác định trong mô-đun đó (chứ không phải nhập), hãy thêm: vào "if isfeft (o [1]) và o [1] .__ module__ == my_module .__ name__ " - lưu ý rằng nó sẽ không hoạt động nhất thiết nếu chức năng được nhập xuất phát từ một mô-đun có cùng tên với mô-đun này.
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
Đối với tuyến đường này, hãy sử dụng getattr (yourmodule, a, none) thay vì yourmodule .__ dict __. Get (a)
Thomas Wouters

4
your_module .__ dict__ là lựa chọn của tôi bởi vì bạn thực sự có được một dict chứa functionName: <function> và bây giờ bạn có khả năng GỌI chức năng đó một cách linh hoạt. thời gian tốt!
21 giờ 31 phút

1
Python 3 thân thiện với một số đường: nhập các loại def print_module_fifts (module): print ('\ n'.join ([str (module .__ dict __. Get (a) .__ name__) cho a trong dir (mô-đun) nếu isinstance (mô-đun. __dict __. get (a), type.FeftType)]))
y.selivonchyk

1
Điều này cũng sẽ liệt kê tất cả các chức năng mà mô-đun nhập khẩu. Đó có thể hoặc không thể là những gì bạn muốn.
scubbo

48

Để hoàn thiện, tôi muốn chỉ ra rằng đôi khi bạn có thể muốn phân tích mã thay vì nhập mã. An importsẽ thực hiện các biểu thức cấp cao nhất và đó có thể là một vấn đề.

Ví dụ: tôi cho phép người dùng chọn các chức năng điểm nhập cảnh cho các gói được tạo bằng zipapp . Sử dụng importvà có inspectnguy cơ chạy mã lạc lối, dẫn đến sự cố, thông báo trợ giúp được in ra, hộp thoại GUI bật lên, v.v.

Thay vào đó tôi sử dụng mô-đun ast để liệt kê tất cả các chức năng cấp cao nhất:

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)

Đưa mã này vào list.pyvà sử dụng chính nó làm đầu vào, tôi nhận được:

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

Tất nhiên, việc điều hướng AST đôi khi có thể khó khăn, ngay cả đối với một ngôn ngữ tương đối đơn giản như Python, vì AST ở mức độ khá thấp. Nhưng nếu bạn có một trường hợp sử dụng đơn giản và rõ ràng, thì cả hai đều có thể thực hiện được và an toàn.

Mặc dù, một nhược điểm là bạn không thể phát hiện các chức năng được tạo khi chạy, như thế nào foo = lambda x,y: x*y.


3
Tôi thích điều này; Hiện tại tôi đang cố gắng tìm hiểu xem ai đó đã viết một công cụ hoạt động giống như pydoc nhưng không nhập mô-đun. Cho đến nay, đây là ví dụ tốt nhất mà tôi đã tìm thấy về điều này :)
James Mills

Đồng ý với câu trả lời này. Tôi cần chức năng này để hoạt động bất kể tệp mục tiêu có thể nhập vào hoặc phiên bản python được viết cho mục đích gì. Điều này không chạy vào các vấn đề nhập khẩu mà imp và importlib làm.
Eric Evans

Làm thế nào về các biến mô-đun ( __version__vv). Có cách nào để có được điều đó?
frakman1

29

Đối với mã mà bạn không muốn phân tích cú pháp, tôi khuyên bạn nên sử dụng cách tiếp cận dựa trên AST của @csl ở trên.

Đối với mọi thứ khác, mô-đun kiểm tra là chính xác:

import inspect

import <module_to_inspect> as module

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

Điều này đưa ra một danh sách 2-tuples trong mẫu [(<name:str>, <value:function>), ...].

Câu trả lời đơn giản ở trên được gợi ý trong các phản hồi và bình luận khác nhau, nhưng không được gọi ra một cách rõ ràng.


Cảm ơn đã đánh vần nó ra; Tôi nghĩ rằng đây là câu trả lời đúng, nếu bạn có thể chạy nhập trên mô-đun để kiểm tra.
Jonathan H

25

Điều này sẽ thực hiện các mẹo:

dir(module) 

Tuy nhiên, nếu bạn thấy khó chịu khi đọc danh sách được trả về, chỉ cần sử dụng vòng lặp sau để nhận một tên trên mỗi dòng.

for i in dir(module): print i

2
OP yêu cầu rõ ràng về các chức năng, không phải các biến. Cf trả lời bằng cách sử dụng inspect. Bên cạnh đó, điều này khác với câu trả lời của @ DanLenski như thế nào?
Jonathan H

20

dir(module) là cách tiêu chuẩn khi sử dụng tập lệnh hoặc trình thông dịch chuẩn, như được đề cập trong hầu hết các câu trả lời.

Tuy nhiên, với trình bao python tương tác như IPython, bạn có thể sử dụng hoàn thành tab để có cái nhìn tổng quan về tất cả các đối tượng được xác định trong mô-đun. Điều này thuận tiện hơn nhiều so với việc sử dụng tập lệnh và printđể xem những gì được xác định trong mô-đun.

  • module.<tab> sẽ hiển thị cho bạn tất cả các đối tượng được xác định trong mô-đun (chức năng, lớp và vv)
  • module.ClassX.<tab> sẽ chỉ cho bạn các phương thức và thuộc tính của một lớp
  • module.function_xy?hoặc module.ClassX.method_xy?sẽ cho bạn thấy chuỗi doc của hàm / phương thức đó
  • module.function_x??hoặc module.SomeClass.method_xy??sẽ hiển thị cho bạn mã nguồn của hàm / phương thức.

19

Đối với các hàm toàn cục dir()là lệnh sử dụng (như được đề cập trong hầu hết các câu trả lời này), tuy nhiên, điều này liệt kê cả các chức năng công cộng và chức năng ngoài công cộng cùng nhau.

Ví dụ: chạy:

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

Trả về các hàm / lớp như:

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

Một số trong đó thường không có nghĩa là để sử dụng lập trình chung (nhưng bởi chính mô-đun, ngoại trừ trong trường hợp của DunderAliases như __doc__, __file__ect). Vì lý do này, có thể không hữu ích khi liệt kê chúng với những người công khai (đây là cách Python biết những gì sẽ nhận được khi sử dụng from module import *).

__all__có thể được sử dụng để giải quyết vấn đề này, nó trả về một danh sách tất cả các hàm và lớp công khai trong một mô-đun (những hàm không bắt đầu bằng dấu gạch dưới - _). Xem ai đó có thể giải thích __all__ bằng Python không? cho việc sử dụng __all__.

Đây là một ví dụ:

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

Tất cả các hàm và lớp có dấu gạch dưới đã bị xóa, chỉ còn lại các hàm được định nghĩa là công khai và do đó có thể được sử dụng thông qua import *.

Lưu ý rằng __all__không phải lúc nào cũng được xác định. Nếu nó không được bao gồm thì một AttributeErrorđược nâng lên.

Một trường hợp này là với mô-đun ast:

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

4

Không có câu trả lời nào trong số này sẽ hoạt động nếu bạn không thể nhập tệp Python đã nói mà không có lỗi nhập. Đây là trường hợp đối với tôi khi tôi đang kiểm tra một tệp xuất phát từ một cơ sở mã lớn với rất nhiều phụ thuộc. Sau đây sẽ xử lý tệp dưới dạng văn bản và tìm kiếm tất cả các tên phương thức bắt đầu bằng "def" và in chúng và số dòng của chúng.

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
Trong trường hợp này, tốt hơn là sử dụng astmô-đun. Xem câu trả lời của tôi cho một ví dụ.
csl

Tôi nghĩ rằng đây là một phương pháp hợp lệ. Tại sao một downvote khi nó làm?
m3nda

2

Ngoại trừ dir (mô-đun) hoặc trợ giúp (mô-đun) được đề cập trong các câu trả lời trước, bạn cũng có thể thử:
- Mở ipython
- nhập module_name
- gõ module_name, nhấn tab. Nó sẽ mở một cửa sổ nhỏ với việc liệt kê tất cả các chức năng trong mô-đun python.
Trông rất gọn gàng.

Dưới đây là đoạn trích liệt kê tất cả các chức năng của mô-đun 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

Điều này sẽ nối thêm tất cả các hàm được xác định trong your_module trong danh sách.

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

Đây là gì unit8_conversion_methods? Đây chỉ là một ví dụ về tên mô-đun?
nocibambi

@nocibambi vâng, nó chỉ là một tên mô-đun.
Manish Kumar

2
cảm ơn Manish. Tôi đề xuất phương án thay thế một dòng sau:[getattr(your_module, func) for func in dir(your_module) if type(getattr(your_module, func)).__name__ == "function"]
amin

0

Bạn có thể sử dụng phương pháp sau để lấy danh sách tất cả các hàm trong mô-đun của mình từ shell:

import module

module.*?

1
@GabrielFair bạn đang chạy python trên phiên bản / nền tảng nào? Tôi gặp lỗi cú pháp trên 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)

Đầu ra:

******************************************************************************************
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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.