Bir python paketinin parçası olan tüm modülleri bulmanın basit bir yolu var mı? Gerçekten kesin olmayan bu eski tartışmayı buldum , ancak os.listdir () tabanlı kendi çözümümü sunmadan önce kesin bir cevaba sahip olmayı çok isterim.
Bir python paketinin parçası olan tüm modülleri bulmanın basit bir yolu var mı? Gerçekten kesin olmayan bu eski tartışmayı buldum , ancak os.listdir () tabanlı kendi çözümümü sunmadan önce kesin bir cevaba sahip olmayı çok isterim.
Yanıtlar:
Evet, buna dayalı pkgutil
veya benzeri bir şey istiyorsunuz - bu şekilde, yumurta veya fermuarlı olup olmadıklarına bakılmaksızın tüm paketlere aynı şekilde davranabilirsiniz (burada os.listdir yardımcı olmaz).
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)
Bunları da nasıl içe aktarabilirim? __import__
Normal olarak kullanabilirsiniz :
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
importer
döndürülür pkgutil.iter_modules
? Görünüşe göre "bilgisayar korsanlığı" yerine onu bir modülü içe aktarmak için kullanabilir miyim __import__(modname, fromlist="dummy")
?
m = importer.find_module(modname).load_module(modname)
ve sonra m
modül, yani örneğin:m.myfunc()
_path_
). Toplam dört (yani __path__
) olmak üzere her iki tarafta iki tane olmalıdır .
Bu iş için doğru araç pkgutil.walk_packages'dır.
Sisteminizdeki tüm modülleri listelemek için:
import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=None, onerror=lambda x: None):
print(modname)
Walk_packages'ın tüm alt paketleri içe aktardığını, ancak alt modülleri almadığını unutmayın.
Belirli bir paketin tüm alt modüllerini listelemek isterseniz, bunun gibi bir şey kullanabilirsiniz:
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 yalnızca tek düzey derinlikteki modülleri listeler. walk_packages tüm alt modülleri alır. Scipy durumunda, örneğin, walk_packages şunu döndürür:
scipy.stats.stats
iter_modules yalnızca döndürürken
scipy.stats
Pkgutil ( http://docs.python.org/library/pkgutil.html ) üzerindeki dokümantasyon, /usr/lib/python2.6/pkgutil.py'de tanımlanan tüm ilginç işlevleri listelemiyor.
Belki de bu, işlevlerin "genel" arayüzün parçası olmadığı ve değişebileceği anlamına gelir.
Ancak, en azından Python 2.6'da (ve belki de daha önceki sürümlerde?) Pkgutil, mevcut tüm modülleri özyinelemeli olarak gezen bir walk_packages yöntemiyle birlikte gelir.
walk_packages
şu anda belgelerde: docs.python.org/library/pkgutil.html#pkgutil.walk_packages
_
Önce ve sonra iki alt çizgi ( ) olmalıdır path
- yani kullanmakpackage.__path__
yerine kullanınpackage._path_
. Kodu yeniden yazmak yerine kesip yapıştırmayı denemek daha kolay olabilir.
package
bir modülü değil, bir paketi işaret ettiğinden emin olun . Modüller dosyalardır, paketler ise dizindir. Tüm paketler __path__
özniteliğe sahiptir (... birisi herhangi bir nedenle özniteliği silmediyse.)
Bu benim için çalışıyor:
import types
for key, obj in nltk.__dict__.iteritems():
if type(obj) is types.ModuleType:
print key
Paketimde canlı olarak düzenlediğim tüm alt modülleri yeniden yüklemenin bir yolunu arıyordum. Bu, yukarıdaki cevapların / yorumların bir kombinasyonudur, bu yüzden bunu bir yorum yerine burada bir cevap olarak göndermeye karar verdim.
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))
İşte aklıma gelen tek yol:
>>> 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)>]
Kesinlikle temizlenebilir ve geliştirilebilir.
DÜZENLEME: İşte biraz daha güzel bir sürüm:
>>> [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']
NOT: Bu aynı zamanda, paketin bir alt dizininde bulunması gerekmeyen modülleri de bulacaktır, eğer __init__.py
dosyasında çekilirlerse , yani bir paketin "parçası" derken neyi kastettiğinize bağlıdır.