অজগর প্যাকেজের অংশ এমন সমস্ত মডিউল তালিকাবদ্ধ করে?


107

পাইথন প্যাকেজের অংশ এমন সমস্ত মডিউল খুঁজে পাওয়ার কোনও সরল উপায় আছে? আমি এই পুরানো আলোচনাটি পেয়েছি , যা সত্যই চূড়ান্ত নয়, তবে os.listdir () এর ভিত্তিতে নিজের সমাধানটি সমাধান করার আগে আমি একটি নির্দিষ্ট উত্তর দিতে পছন্দ করব।


6
@ এস.লট: আরও সাধারণ সমাধান পাওয়া যায়, পাইথন প্যাকেজগুলি সর্বদা ফাইল সিস্টেমে ডিরেক্টরিতে থাকে না, তবে জিপগুলির অভ্যন্তরেও হতে পারে।
u0b34a0f6ae

4
চাকা পুনরুদ্ধার কেন? পাইথন পাইথন 4-তে হাইপারমডিউলগুলি অর্জন করে, পিকগটিল এবং তার সাথে আপডেট হলে আমার কোডটি এখনও কাজ করবে। আমি উপলব্ধ বিমূর্ত ব্যবহার করতে চাই। প্রদত্ত স্পষ্ট পদ্ধতিটি ব্যবহার করুন, এটি পরীক্ষিত এবং কাজ করার জন্য পরিচিত। এটি পুনরায় বাস্তবায়ন করা .. এখন আপনাকে প্রতিটি কোণার কেস নিজেই খুঁজে পেতে এবং কাজ করতে হবে।
u0b34a0f6ae

1
@ এস.লোট: সুতরাং যতবারই অ্যাপ্লিকেশন শুরু হয়, এটি পরীক্ষা করার জন্য যদি কোনওটির ভিতরে ইনস্টল করা হয় তবে এটি নিজের ডিমটি আনজিপ করে দেবে? এই ফাংশনটিতে হুইলটি পুনঃস্থাপন করতে দয়া করে আমার প্রকল্পের বিরুদ্ধে একটি প্যাচ জমা দিন: git.gnome.org/cgit/kupfer/tree/kupfer/plugins.py#n17 । দয়া করে ডিম এবং সাধারণ উভয় ডিরেক্টরি বিবেচনা করুন, 20 লাইন অতিক্রম করবেন না।
u0b34a0f6ae

1
@ এস.লোট: আপনি কেন বুঝতে পারছেন না যে এটি প্রাসঙ্গিক এমন একটি জিনিস যা আপনি বুঝতে পারবেন না। এই প্রোগ্রামটিমেটিকভাবে আবিষ্কার করা সম্পর্কেই এই অ্যাপ্লিকেশনটি প্যাকেজের সামগ্রীতে আগ্রহী, ব্যবহারকারী নয়।
u0b34a0f6ae

3
অবশ্যই আমি প্রোগ্রামিয়ালি মানে! অন্যথায় আমি "আমার নিজের সমাধানটি os.listdir ()" এর সাথে ঘুরিয়ে দেওয়ার উল্লেখ করতাম না
স্থিতি_আরটি

উত্তর:


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)mm.myfunc()
জাতীয়ভাবে

@ ক্রিসলেগ আমি পাইথন ২.7 এর সাথে ইউর পদ্ধতিটি ব্যবহার করছিলাম তবে এখন আমার পাইথন ৩.৪ নিয়ে অগ্রসর হওয়া দরকার, সুতরাং আপনি জানেন যে পাইথন 3 পিকুইটিলিটার_মডিউলগুলি ফলন (মডিউল_ফাইন্ডার, নাম, ইস্পকজি) এর পরিবর্তে (মডিউল_লোডার, নাম, ইস্পিজি কে)। এটি আগেরটির মতো কাজ করতে আমি কী করতে পারি?
ক্র্যাক্স

আপনার প্রথম উদাহরণটি নিম্নলিখিত ত্রুটিটি উত্পন্ন করে: "AttributeError: 'মডিউল' অবজেক্টটির ' _path_ ' কোনও বৈশিষ্ট্য নেই " পাইথন সংস্করণটির সাথে কি এর কোনও যোগসূত্র রয়েছে ? (আমি পাইথন ২.7 ব্যবহার করি)
অ্যাপোস্টোলস

@ অ্যাপোস্টোলোস, আপনি পথের উভয় দিকে (যেমন _path_) কেবল একটি আন্ডারস্কোর ব্যবহার করছেন । মোট চারটি (অর্থাত্ __path__) জন্য দু'দিকে দুটি হওয়া উচিত ।
therealmitchconnors

46

এই কাজের জন্য সঠিক সরঞ্জামটি হল pkgutil.walk_packages।

আপনার সিস্টেমে সমস্ত মডিউল তালিকাভুক্ত করতে:

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

সচেতন থাকুন যে ওয়াক_প্যাকেজগুলি সমস্ত উপ-প্যাকেজগুলি আমদানি করে, তবে সাবমডিউলগুলি নয়।

আপনি যদি একটি নির্দিষ্ট প্যাকেজের সমস্ত সাবমোডিয়ুল তালিকাভুক্ত করতে চান তবে আপনি এই জাতীয় কিছু ব্যবহার করতে পারেন:

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 কেবলমাত্র এক-স্তর গভীর মডিউলগুলি তালিকাভুক্ত করে। ওয়াক_প্যাকেজগুলি সমস্ত সাবমডিউল পায়। স্কিপির ক্ষেত্রে, উদাহরণস্বরূপ, ওয়াক_প্যাকেজগুলি ফেরত দেয়

scipy.stats.stats

যদিও iter_modules কেবল ফেরত দেয়

scipy.stats

Pkgutil ( http://docs.python.org/library/pkgutil.html ) - তে থাকা ডকুমেন্টেশনগুলি /usr/lib/python2.6/pkgutil.py এ সংজ্ঞায়িত সমস্ত আকর্ষণীয় ফাংশন তালিকাভুক্ত করে না।

সম্ভবত এর অর্থ এই যে ফাংশনগুলি "পাবলিক" ইন্টারফেসের অংশ নয় এবং পরিবর্তিত হতে পারে।

তবে পাইথন কমপক্ষে ২.6 হিসাবে (এবং সম্ভবত পূর্ববর্তী সংস্করণগুলি?) পিকগটিল ওয়াক_প্যাকেজ পদ্ধতিতে আসে যা উপলভ্য সমস্ত মডিউলগুলির মধ্যে পুনরাবৃত্তি করে।


5
walk_packagesডকুমেন্টেশনে এখন রয়েছে: docs.python.org/library/pkgutil.html#pkgutil.walk_packages
যান্ত্রিক শামুক

1
আপনার দ্বিতীয় উদাহরণটি নিম্নলিখিত ত্রুটিটি উত্পন্ন করে: "AttributeError: 'মডিউল' অবজেক্টটির ' _path_ '" বৈশিষ্ট্য নেই - আমি এটি 'স্কিপি' দিয়ে পরীক্ষা করিনি তবে কয়েকটি অন্যান্য প্যাকেজ নিয়ে with পাইথন সংস্করণটির সাথে এর কোনও সম্পর্ক আছে? (আমি পাইথন ২.7 ব্যবহার করি)
অ্যাপোস্টোলস

1
@ অ্যাপোস্টোলোস: এর _আগে ও পরে দুটি আন্ডারস্কোর থাকতে হবে path- এর পরিবর্তে ব্যবহার করুনpackage.__path__package._path_ । কোডটি পুনরায় টাইপ করার চেয়ে কাটা এবং পেস্ট করার চেষ্টা করা আরও সহজ হতে পারে।
unutbu

তাদের মধ্যে দু'জন ছিল, আমি যখন মন্তব্যটি লিখি! :) কিন্তু তারা সিস্টেম দ্বারা ছিনিয়ে নেওয়া হয়েছে। আমার খারাপ; আমার তিনটি আন্ডারকোর রাখা উচিত ছিল। তবে, আমি যদি ইটালিকগুলি ব্যবহার করতে চাইতাম তবে এটি ঠিক হবে, যা আমি করিনি! ... এটি লোকসানের লোকসানের পরিস্থিতি। :) যাইহোক, আমি কোডটি চালানোর সময় অবশ্যই আমি তাদের দুটি ব্যবহার করেছি। (আমি কোডটি অনুলিপি করে দিয়েছি))
Apostolos

@ অ্যাপোস্টোলোস: নিশ্চিত করুন যে ভেরিয়েবল packageকোনও প্যাকেজের দিকে নির্দেশ করছে, কোনও মডিউল নয়। মডিউলগুলি ফাইল যেখানে প্যাকেজগুলি ডিরেক্টরি। সমস্ত প্যাকেজটির __path__বৈশিষ্ট্য রয়েছে (... যদি না কারও কারও কারণে অ্যাট্রিবিউটটি মুছে ফেলা হয়।)
আনতবু

2

এটি আমার পক্ষে কাজ করে:

import types

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

1
এটি দুটি উপায়ে ব্যর্থ হয় 1. প্যাকেজগুলি সর্বদা সুস্পষ্টভাবে তাদের উপ-মডেলগুলি শীর্ষ-স্তরের নেমস্পেসে আমদানি করে না 2 প্যাকেজগুলি তাদের তৃতীয়-পক্ষের নেমস্পেসে অন্য তৃতীয় পক্ষের মডিউলগুলি আমদানি করতে পারে
উইম

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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.