C'è un modo semplice per trovare tutti i moduli che fanno parte di un pacchetto python? Ho trovato this old discussion, che non è davvero conclusivo, ma mi piacerebbe avere una risposta definitiva prima di distribuire la mia soluzione basata su os.listdir().Elenca tutti i moduli che fanno parte di un pacchetto python?
risposta
Sì, si desidera qualcosa basato su pkgutil
o simile - in questo modo è possibile trattare tutti i pacchetti uguali indipendentemente dal fatto che siano in egg o zip o così (dove os.listdir non aiuterà).
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)
Come importarli anche loro? Si può solo usare __import__
come normale:
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
cosa è questo 'importatore 'restituito da' pkgutil.iter_modules'? Posso usarlo per importare un modulo invece di usare questo apparentemente "hackish"? __import __ (modname, fromlist = "dummy") '? – MestreLion
Sono stato in grado di utilizzare l'importatore in questo modo: 'm = importer.find_module (modname) .load_module (modname)' e quindi 'm' è il modulo, quindi ad esempio:' m.myfunc() ' – chrisleague
@chrisleague I stavo usando il metodo ur con python 2.7, ma ora ho bisogno di andare avanti con python 3.4, quindi sai che in python 3 i rendimenti di pkutil.iter_modules (module_finder, name, ispkg) invece di (module_loader, name, ispkg). Cosa posso fare per farlo funzionare come il precedente? –
Ecco un modo, la parte superiore della mia testa:
>>> 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)>]
Si potrebbe certamente essere ripulito e migliorato.
EDIT: Ecco una versione leggermente più bello:
>>> [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']
NOTA: Questo sarà anche trovare i moduli che potrebbero non necessariamente essere situati in una sottodirectory del pacchetto, se sono tirato in a il suo file __init__.py
, quindi dipende da cosa intendi per "parte di" un pacchetto.
scusa, che non ha senso. A parte i falsi positivi, troverà solo i sottomoduli già importati di pacchetti. – u0b34a0f6ae
Lo strumento giusto per questo lavoro è pkgutil.walk_packages.
per elencare tutti i moduli del sistema:
import pkgutil
for importer, modname, ispkg in pkgutil.walk_packages(path=None, onerror=lambda x: None):
print(modname)
essere consapevoli del fatto che le importazioni walk_packages tutti i pacchetti secondari, ma non sottomoduli.
Se si desidera elencare tutti i sottomoduli di un certo pacchetto, potete usare qualcosa di simile:
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 elenca solo i moduli che sono uno-livello profondo. walk_packages ottiene tutti i sottomoduli. Nel caso di SciPy, per esempio, walk_packages rendimenti
scipy.stats.stats
mentre iter_modules restituisce solo
scipy.stats
La documentazione sulla pkgutil (http://docs.python.org/library/pkgutil.html) non elenca tutte le funzioni interessanti definite in /usr /lib/python2.6/pkgutil.py.
Forse questo significa che le funzioni non fanno parte dell'interfaccia "pubblica" e sono soggette a modifiche.
Tuttavia, almeno a partire da Python 2.6 (e versioni precedenti, forse?) pkgutil viene fornito con un metodo walk_packages che cammina in modo ricorsivo attraverso tutte le moduli disponibili.
'walk_packages' è ora nella documentazione: http://docs.python.org/library/pkgutil.html#pkgutil.walk_packages –
Il tuo secondo esempio produce il seguente errore: **" AttributeError: ' modulo 'oggetto non ha attributo' __path __ '"** - Non l'ho provato con' scipy 'ma con pochi altri pacchetti. Ha qualcosa a che fare con la versione di Python? (Io uso Python 2.7) – Apostolos
@Apostolos: Ci dovrebbero essere due caratteri di sottolineatura ('_') prima e dopo' path' - cioè, usare 'package .__ path__'] (https://stackoverflow.com/q/ 2699287/190597) anziché "pacchetto._punto_". Potrebbe essere più facile provare a tagliare e incollare il codice piuttosto che ridigitarlo. – unutbu
Questo funziona per me: domanda
import types
for key, obj in nltk.__dict__.iteritems():
if type(obj) is types.ModuleType:
print key
Bonus: come si fa a importare i moduli trovati bene? –
Cosa c'è di sbagliato leggendo la directory dei sorgenti? Di quali altre informazioni hai bisogno? Cosa c'è di sbagliato in 'ls' (o' dir')? –
@ S.Lott: ci sono più soluzioni generali disponibili, i pacchetti python non sono sempre presenti nelle directory nel filesystem, ma possono anche trovarsi all'interno delle zip. – u0b34a0f6ae