Gibt es eine einfache Möglichkeit, alle Module zu finden, die Teil eines Python-Pakets sind? Ich habe this old discussion gefunden, was nicht wirklich aussagekräftig ist, aber ich würde gerne eine definitive Antwort haben, bevor ich meine eigene Lösung basierend auf os.listdir() auf den Markt bringe.Listen Sie alle Module auf, die Teil eines Python-Pakets sind.
Antwort
Ja, Sie wollen etwas basierend auf pkgutil
oder ähnlich - so können Sie alle Pakete gleich behandeln, egal ob sie in Eiern oder Zips oder so sind (wo os.listdir nicht hilft).
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)
Wie importieren Sie sie auch? Sie können nur __import__
als normal verwenden:
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
Was wird dieser 'Importeur' von' pkgutil.iter_modules' zurückgegeben? Kann ich es verwenden, um ein Modul zu importieren, anstatt diesen scheinbar "hackischen" "__import __ (modname, fromlist =" dummy ")' '? – MestreLion
Ich konnte den Importer so verwenden: 'm = importer.find_module (modname) .load_module (modname)' und dann 'm' ist das Modul, also zum Beispiel:' m.myfunc() ' – chrisleague
@chrisleague I benutzte Ur Methode mit Python 2.7, aber jetzt muss ich weiter mit Python 3.4, so dass Sie wissen, dass in Python 3 pkutil.iter_modules (Modul_Finder, Name, ISPkg) anstelle von (Modul_Loader, Name, ISPkg). Was kann ich tun, damit es wie das vorherige funktioniert? –
Hier ist ein Weg, aus der Spitze von meinem Kopf:
>>> 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)>]
Es sicherlich gereinigt und verbessert werden könnte.
EDIT: Hier ist eine etwas schönere Version:
>>> [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']
HINWEIS: Dies wird auch Module finden, die unbedingt möglicherweise nicht in einem Unterverzeichnis des Pakets befinden, wenn sie gezogen sind in in seine __init__.py
Datei, so kommt es darauf an, was Sie mit "Teil von" einem Paket meinen.
rausreite, das hat keinen Nutzen. Neben den Fehlalarmen werden nur bereits importierte Submodule von Paketen gefunden. – u0b34a0f6ae
Das richtige Werkzeug für diesen Job pkgutil.walk_packages ist.
Um alle Module auf Ihrem System auflisten:
import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=None, onerror=lambda x: None):
print(modname)
Beachten Sie, dass die Einfuhren alle Subpackages walk_packages, aber nicht Submodule.
Wenn Sie alle Submodule eines bestimmten Paketes zur Liste möchten, dann können Sie so etwas wie folgt verwenden:
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 listet nur die Module, die auf einer Ebene tief sind. walk_packages ruft alle Submodule ab. Im Fall von scipy zum Beispiel walk_packages kehren
scipy.stats.stats
während iter_modules nur
scipy.stats
Die Dokumentation auf pkgutil zurückgibt (http://docs.python.org/library/pkgutil.html) Liste nicht all interessant in /usr definierten Funktionen /lib/python2.6/pkgutil.py.
Vielleicht bedeutet dies, dass die Funktionen nicht Teil der "öffentlichen" Schnittstelle sind und Änderungen unterliegen können.
jedoch zumindest von Python 2.6 (und vielleicht auch frühere Versionen?) pkgutil kommt mit einer walk_packages Methode, die rekursiv die all verfügbaren Module Wanderungen durch.
'walk_packages' ist jetzt in der Dokumentation: http://docs.python.org/library/pkgutil.html#pkgutil.walk_packages –
Ihr zweites Beispiel erzeugt den folgenden Fehler: **" AttributeError: ' modul 'object hat kein Attribut' __path __ '"** - Ich habe es nicht mit' scipy 'getestet, sondern mit ein paar anderen Paketen. Hat das etwas mit der Python-Version zu tun? (Ich benutze Python 2.7) – Apostolos
@Apostolos: Es sollte zwei Unterstriche ('_') vor und nach 'Pfad' geben - das heißt, [verwenden' Paket .__ Pfad__'] (https://StackOverflow.com/q/ 2699287/190597) statt 'package._path_'. Es könnte einfacher sein, den Code auszuschneiden und einzufügen, anstatt ihn erneut einzugeben. – unutbu
arbeitet Dies ist für mich:
import types
for key, obj in nltk.__dict__.iteritems():
if type(obj) is types.ModuleType:
print key
Frage Bonus: Wie importieren Sie die gefundenen schön Module? –
Was ist falsch beim Lesen des Quellverzeichnisses? Welche weiteren Informationen benötigen Sie? Was ist los mit 'ls' (oder' dir')? –
@ S.Lott: Es gibt allgemeinere Lösungen zur Verfügung, Python-Pakete sind nicht immer in Verzeichnissen im Dateisystem, sondern können auch in Zips sein. – u0b34a0f6ae