سؤال

لدي وحدة python مثبتة على نظامي وأود أن أتمكن من رؤية الوظائف/الفئات/الأساليب المتوفرة فيها.

أريد استدعاء وظيفة المستند على كل واحد.في روبي، يمكنني أن أفعل شيئًا مثل ClassName.methods للحصول على قائمة بجميع الطرق المتاحة في هذا الفصل.هل هناك شيء مماثل في بيثون؟

على سبيل المثال.شيء مثل:

from somemodule import foo
print foo.methods # or whatever is the correct method to call
هل كانت مفيدة؟

المحلول

ال inspect وحدة.انظر أيضا pydoc الوحدة النمطية، help() وظيفة في المترجم التفاعلي و pydoc أداة سطر الأوامر التي تنشئ الوثائق التي تبحث عنها.يمكنك فقط منحهم الفصل الذي ترغب في رؤية وثائقه.يمكنهم أيضًا إنشاء، على سبيل المثال، مخرجات HTML وكتابتها على القرص.

نصائح أخرى

يمكنك استخدام dir(module) لرؤية جميع الأساليب/السمات المتاحة.تحقق أيضًا من PyDocs.

بمجرد الانتهاء من ذلك importبعد تعديل الوحدة، يمكنك فقط القيام بما يلي:

 help(modulename)

...للحصول على المستندات الخاصة بجميع الوظائف مرة واحدة وبشكل تفاعلي.أو يمكنك استخدام:

 dir(modulename)

...لسرد أسماء جميع الوظائف والمتغيرات المحددة في الوحدة ببساطة.

مثال مع التفتيش:

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 الأخرى في وحدة الفحص.

import types
import yourmodule

print([getattr(yourmodule, a) for a in dir(yourmodule)
  if isinstance(getattr(yourmodule, a), types.FunctionType)])

من أجل الاكتمال، أود أن أشير إلى أنه في بعض الأحيان قد ترغب في ذلك تحليل الرمز بدلاً من استيراده.ان import سوف ينفذ تعبيرات المستوى الأعلى، والتي يمكن أن تكون مشكلة.

على سبيل المثال، أسمح للمستخدمين بتحديد وظائف نقطة الإدخال للحزم التي يتم إنشاؤها بها com.zipapp.استخدام import و inspect مخاطر تشغيل التعليمات البرمجية الضالة، مما يؤدي إلى حدوث أعطال، وطباعة رسائل المساعدة، وظهور مربعات حوار واجهة المستخدم الرسومية وما إلى ذلك.

بدلا من ذلك أستخدم أست الوحدة النمطية لسرد جميع وظائف المستوى الأعلى:

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.

هذا وسوف تفعل خدعة:

dir(module) 

ومع ذلك، إذا وجدت أنه من المزعج قراءة القائمة التي تم إرجاعها، فما عليك سوى استخدام الحلقة التالية للحصول على اسم واحد في كل سطر.

for i in dir(module): print i

dir(module) هي الطريقة القياسية عند استخدام البرنامج النصي أو المترجم القياسي، كما هو مذكور في معظم الإجابات.

ولكن مع قذيفة بيثون التفاعلية مثل IPython يمكنك استخدام إكمال علامة التبويب للحصول على نظرة عامة على جميع الكائنات المحددة في الوحدة.هذا أكثر ملاءمة من استخدام البرنامج النصي و print لمعرفة ما تم تعريفه في الوحدة.

  • module.<tab> سيُظهر لك جميع الكائنات المحددة في الوحدة (الوظائف والفئات وما إلى ذلك)
  • module.ClassX.<tab> سوف تظهر لك أساليب وسمات الفصل
  • module.function_xy? أو module.ClassX.method_xy? سوف تظهر لك مستندات تلك الوظيفة/الطريقة
  • module.function_x?? أو module.SomeClass.method_xy?? سيُظهر لك الكود المصدري للوظيفة/الطريقة.

بالنسبة للتعليمات البرمجية التي لا ترغب في تحليلها، أوصي باستخدام النهج القائم على AST الخاص بـ @csl أعلاه.

بالنسبة لكل شيء آخر، وحدة الفحص صحيحة:

import inspect

import <module_to_inspect> as module

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

وهذا يعطي قائمة من 2-tuples في النموذج [(<name:str>, <value:function>), ...].

تم التلميح إلى الإجابة البسيطة أعلاه في العديد من الردود والتعليقات، ولكن لم يتم ذكرها بشكل صريح.

للوظائف العالمية dir() هو الأمر الذي يجب استخدامه (كما هو مذكور في معظم هذه الإجابات)، ولكن هذا يسرد كلاً من الوظائف العامة والوظائف غير العامة معًا.

على سبيل المثال تشغيل:

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

إرجاع وظائف/فئات مثل:

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

بعضها ليس مخصصًا بشكل عام للاستخدام العام للبرمجة (ولكن من خلال الوحدة نفسها، باستثناء حالة DunderAliases مثل __doc__, __file__ إلخ).لهذا السبب قد لا يكون من المفيد إدراجها مع العناصر العامة (هذه هي الطريقة التي تعرف بها بايثون ما يجب الحصول عليه عند الاستخدام from module import *).

__all__ يمكن استخدامها لحل هذه المشكلة، فهي تقوم بإرجاع قائمة بجميع الوظائف والفئات العامة في الوحدة النمطية (تلك التي لا ابدأ بالشرطات السفلية - _).يرىهل يمكن لأي شخص أن يشرح __all__ في بايثون؟ لاستخدام __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__'
>>>

لن تعمل أي من هذه الإجابات إذا لم تتمكن من استيراد ملف 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])

باستثناء dir(module) أو help(module) المذكورين في الإجابات السابقة، يمكنك أيضًا تجربة:
- فتح بايثون
- استيراد اسم الوحدة
- اكتب اسم الوحدة، ثم اضغط على علامة التبويب.سيتم فتح نافذة صغيرة بها قائمة بجميع الوظائف في وحدة بايثون.
يبدو أنيقًا جدًا.

فيما يلي مقتطف يسرد جميع وظائف وحدة 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

يمكنك استخدام الطريقة التالية للحصول على قائمة بجميع الوظائف في الوحدة النمطية الخاصة بك من Shell:

import module

module.*?

سيؤدي هذا إلى إلحاق جميع الوظائف المحددة في your_module في القائمة.

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

ليس من المناسب (أو على الأقل لم يعد) استخدام dir(module).يجب أن يقرأ الكود هكذا:

dir('module') or dir('modules') 

أو يمكنك تحديد الوحدة التي تريدها مثل هذا: dir('sys') لإنتاج نتائج من اسم الوحدة sys. dir() إرجاع الأخطاء في حين dir('') هو ما تحتاجه.*help('') ستعيد معلومات المساعدة إذا كانت متوفرة لمعظم الوظائف.على سبيل المثال؛ help('modules') سيعود معلومات مساعدة الوحدة.

شكرا لجميع الأصوات أسفل.كنت أستخدم Python3.2.2 وإصدارات 3x الأخرى عندما نشرت هذا.كان الهدف هو استخدام ('الأشياء') بدلاً من (الأشياء) السابقة.لكنني أفترض أن كل ما لديك عالق في Python2 أو تستخدم إصدارات أحدث للكمبيوتر الشخصي وليس للجوال كما كنت.

http://effbot.org/librarybook/sys.htm

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top