उन सभी मॉड्यूल की सूची बनाएं जो एक अजगर पैकेज का हिस्सा हैं?


107

क्या उन सभी मॉड्यूलों को खोजने का एक सीधा तरीका है जो अजगर पैकेज का हिस्सा हैं? मुझे यह पुरानी चर्चा मिली है , जो वास्तव में निर्णायक नहीं है, लेकिन मैं अपने स्वयं के समाधान os.listdir () पर आधारित रोल आउट करने से पहले एक निश्चित उत्तर देना पसंद करूंगा।


6
@ एस.लॉट: अधिक सामान्य समाधान उपलब्ध हैं, पायथन पैकेज हमेशा फाइलसिस्टम में निर्देशिका में नहीं होते हैं, लेकिन ज़िप के अंदर भी हो सकते हैं।
u0b34a0f6ae

4
पहिया को क्यों मजबूत करें? अगर अजगर पायथन 4 में हाइपरमॉड्यूल्स प्राप्त करता है, तो pkgutil और उसी के साथ अपडेट किया जाता है, मेरा कोड अभी भी काम करेगा। मुझे उपलब्ध अमूर्त का उपयोग करना पसंद है। प्रदान की गई स्पष्ट पद्धति का उपयोग करें, यह काम करने के लिए परीक्षण और ज्ञात है। इसे लागू करना .. अब आपको हर कोने के मामले को खुद ढूंढना होगा और काम करना होगा।
u0b34a0f6ae

1
@ एस.लॉट: तो हर बार आवेदन शुरू होने के बाद, यह जांचने के लिए एक के अंदर स्थापित होने पर अपने स्वयं के अंडे को अनज़िप कर देगा? कृपया इस फ़ंक्शन में पहिया को फिर से मजबूत करने के लिए मेरी परियोजना के खिलाफ एक पैच सबमिट करें: git.gnome.org/cgit/kupfer/tree/kupfer/plugins.py#n17 । कृपया अंडे और सामान्य निर्देशिका दोनों पर विचार करें, 20 लाइनों से अधिक न हो।
u0b34a0f6ae

1
@ एस.लॉट: आप यह क्यों नहीं समझते कि यह प्रासंगिक है कुछ ऐसा है जिसे आप समझ नहीं सकते हैं। इस प्रोग्राम की खोज इस बारे में है कि एप्लिकेशन पैकेज की सामग्री में दिलचस्पी लेता है, न कि उपयोगकर्ता।
u0b34a0f6ae 19

3
बेशक मैं प्रोग्रामेटिक रूप से मतलब है! अन्यथा मैंने "os.listdir ()" के साथ अपना स्वयं का समाधान शुरू करने का उल्लेख नहीं किया होगा
static_rtti

जवाबों:


145

हां, आप कुछ pkgutilइसी तरह या उसके आधार पर चाहते हैं - इस तरह से आप सभी पैकेजों के साथ एक जैसा व्यवहार कर सकते हैं, भले ही वे अंडे या ज़िप में हों या (जहाँ os.listdir मदद नहीं करेगा)।

import pkgutil

# this is the package we are inspecting -- for example 'email' from stdlib
import email

package = email
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__):
    print "Found submodule %s (is a package: %s)" % (modname, ispkg)

उन्हें भी कैसे आयात करें? आप __import__सामान्य रूप से उपयोग कर सकते हैं :

import pkgutil

# this is the package we are inspecting -- for example 'email' from stdlib
import email

package = email
prefix = package.__name__ + "."
for importer, modname, ispkg in pkgutil.iter_modules(package.__path__, prefix):
    print "Found submodule %s (is a package: %s)" % (modname, ispkg)
    module = __import__(modname, fromlist="dummy")
    print "Imported", module

9
क्या यह है importerद्वारा लौटाए गए pkgutil.iter_modules? क्या मैं इसे "हैकिश" के उपयोग के बजाय मॉड्यूल आयात करने के लिए उपयोग कर सकता हूं __import__(modname, fromlist="dummy")?
MestreLion

29
मैं इस तरह आयातक का उपयोग करने में सक्षम था: m = importer.find_module(modname).load_module(modname)और फिर mमॉड्यूल है, इसलिए उदाहरण के लिए:m.myfunc()
क्रिसल्यूग

@chrisleague मैं python 2.7 के साथ उर विधि का उपयोग कर रहा था, लेकिन अब मुझे python 3.4 के साथ आगे बढ़ने की आवश्यकता है, इसलिए आप जानते हैं कि python में 3 pkutil.iter_modules पैदावार (मॉड्यूल_फाइंडर, नाम, ispkg) के बजाय (मॉड्यूल_ लोडर, नाम, ispkg) है। मैं इसे पिछले एक की तरह काम करने के लिए क्या कर सकता हूं?
क्रेक्स

आपका पहला उदाहरण निम्नलिखित त्रुटि पैदा करता है: "गुण: 'मॉड्यूल' ऑब्जेक्ट में कोई विशेषता नहीं है ' _path_ '" क्या पायथन संस्करण के साथ इसका कोई लेना देना है? (मैं पायथन 2.7 का उपयोग करता हूं)
एपोस्टोलोस

@ एपोस्टोलोस, आप पथ के दोनों ओर केवल एक अंडरस्कोर का उपयोग कर रहे हैं (यानी _path_)। कुल चार (यानी __path__) के लिए दो तरफ होना चाहिए ।
उपचारात्मक

46

इस काम के लिए सही उपकरण pkgutil.walk_packages है।

अपने सिस्टम के सभी मॉड्यूलों को सूचीबद्ध करने के लिए:

import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=None, onerror=lambda x: None):
    print(modname)

इस बात से अवगत रहें कि walk_packages सभी उप-पैकेजों का आयात करता है, लेकिन सबमॉड्यूल्स का नहीं।

यदि आप एक निश्चित पैकेज के सभी सबमॉडल्स को सूचीबद्ध करना चाहते हैं तो आप कुछ इस तरह का उपयोग कर सकते हैं:

import pkgutil
import scipy
package=scipy
for importer, modname, ispkg in pkgutil.walk_packages(path=package.__path__,
                                                      prefix=package.__name__+'.',
                                                      onerror=lambda x: None):
    print(modname)

iter_modules केवल उन मॉड्यूल को सूचीबद्ध करता है जो एक-स्तरीय गहरे हैं। walk_packages में सभी सबमॉड्यूल मिलते हैं। डरपोक के मामले में, उदाहरण के लिए, walk_packages रिटर्न

scipy.stats.stats

जबकि iter_modules ही लौटते हैं

scipy.stats

Pkgutil ( http://docs.python.org/library/pkgutil.html ) पर प्रलेखन /usr/lib/python2.6/pkgutil.py में परिभाषित सभी दिलचस्प कार्यों को सूचीबद्ध नहीं करता है।

शायद इसका मतलब यह है कि फ़ंक्शन "सार्वजनिक" इंटरफ़ेस का हिस्सा नहीं हैं और परिवर्तन के अधीन हैं।

हालांकि, कम से कम पाइथन 2.6 (और शायद पहले के संस्करणों?) के रूप में pkgutil एक walk_packages विधि के साथ आता है जो कि उपलब्ध सभी मॉड्यूल के माध्यम से पुनरावृत्ति करता है।


5
walk_packagesअब दस्तावेज़ में है: docs.python.org/library/pkgutil.html#pkgutil.walk_packages
मैकेनिकल घोंघा

1
आपका दूसरा उदाहरण निम्नलिखित त्रुटि पैदा करता है: "AttributeError: 'मॉड्यूल' ऑब्जेक्ट में कोई विशेषता नहीं है ' _path_ '" - मैंने इसे 'scipy' के साथ नहीं बल्कि कुछ अन्य पैकेजों के साथ परीक्षण किया। यह पायथन संस्करण के साथ कुछ भी करना है? (मैं पायथन 2.7 का उपयोग करता हूं)
एपोस्टोलोस

1
@Apostolos: वहाँ दो अंडरस्कोर (होना चाहिए _) पहले और बाद में path- जाता है कि, का उपयोगpackage.__path__ करने के बजाय package._path_। कोड को फिर से टाइप करने के बजाय काटने और चिपकाने की कोशिश करना आसान हो सकता है।
अनटु

उनमें से दो थे, जब मैंने टिप्पणी लिखी थी! :) लेकिन वे सिस्टम द्वारा छीन लिए गए हैं। मेरी गलती; मुझे तीन अंडर कर देने चाहिए थे। लेकिन फिर, यह ठीक होगा यदि मैं इटैलिक का उपयोग करना चाहता था, जो मैंने नहीं किया था! ... यह घाटे-नुकसान की स्थिति है। :) वैसे भी, जब मैं कोड चलाता हूं तो मैंने उनमें से दो का उपयोग किया है, बिल्कुल। (मैं कोड को कॉपी-पेस्ट करता हूं।)
एपोस्टोलोस

@Apostolos: सुनिश्चित करें कि चर packageएक पैकेज की ओर इशारा कर रहा है, मॉड्यूल नहीं। मॉड्यूल फाइलें हैं जबकि पैकेज निर्देशिका हैं। सभी पैकेजों में __path__विशेषता है (... जब तक किसी ने किसी कारण से विशेषता को हटा नहीं दिया है।)
अनटुब

2

यह मेरे लिए काम करता है:

import types

for key, obj in nltk.__dict__.iteritems():
    if type(obj) is types.ModuleType: 
        print key

1
यह दो तरह से विफल रहता है। 1. पैकेज हमेशा अपने सबमॉडल्स को स्पष्ट रूप से शीर्ष-स्तरीय नाम स्थान में आयात नहीं करते हैं। 2. पैकेज अन्य 3-पार्टी मॉड्यूल को उनके शीर्ष-स्तरीय नाम स्थान में आयात कर सकते हैं
wim

0

मैं सभी सबमॉडल्स को पुनः लोड करने का एक तरीका ढूंढ रहा था जो मैं अपने पैकेज में लाइव संपादित कर रहा हूं। यह ऊपर दिए गए उत्तरों / टिप्पणियों का एक संयोजन है, इसलिए मैंने इसे टिप्पणी के बजाय उत्तर के रूप में यहां पोस्ट करने का निर्णय लिया है।

package=yourPackageName
import importlib
import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=package.__path__, prefix=package.__name__+'.', onerror=lambda x: None):
    try:
        modulesource = importlib.import_module(modname)
        reload(modulesource)
        print("reloaded: {}".format(modname))
    except Exception as e:
        print('Could not load {} {}'.format(modname, e))

-4

यहाँ एक तरीका है, मेरे सिर के ऊपर से:

>>> import os
>>> filter(lambda i: type(i) == type(os), [getattr(os, j) for j in dir(os)])
[<module 'UserDict' from '/usr/lib/python2.5/UserDict.pyc'>, <module 'copy_reg' from '/usr/lib/python2.5/copy_reg.pyc'>, <module 'errno' (built-in)>, <module 'posixpath' from '/usr/lib/python2.5/posixpath.pyc'>, <module 'sys' (built-in)>]

यह निश्चित रूप से साफ किया जा सकता है और सुधार हुआ है।

संपादित करें: यहाँ थोड़ा अच्छा संस्करण है:

>>> [m[1] for m in filter(lambda a: type(a[1]) == type(os), os.__dict__.items())]
[<module 'copy_reg' from '/usr/lib/python2.5/copy_reg.pyc'>, <module 'UserDict' from '/usr/lib/python2.5/UserDict.pyc'>, <module 'posixpath' from '/usr/lib/python2.5/posixpath.pyc'>, <module 'errno' (built-in)>, <module 'sys' (built-in)>]
>>> [m[0] for m in filter(lambda a: type(a[1]) == type(os), os.__dict__.items())]
['_copy_reg', 'UserDict', 'path', 'errno', 'sys']

नोट: यह उन मॉड्यूलों को भी खोजेगा जो जरूरी नहीं कि पैकेज के एक उपनिर्देशिका में स्थित हो सकते हैं, यदि वे इसकी __init__.pyफ़ाइल में खींच लिए जाते हैं , तो यह इस बात पर निर्भर करता है कि आप पैकेज के "भाग" से क्या मतलब रखते हैं।


क्षमा करें, इसका कोई उपयोग नहीं है। झूठी सकारात्मकता के अलावा, यह केवल पहले से ही आयात किए गए सबमॉडल्स पैकेजों को भी ढूंढेगा।
u0b34a0f6ae
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.