(Ovo je drugi u nizu postova o Python programiranju koji sam započeo postom o ubacivanju metoda u postojeće Python objekte)
Nedavno sam za jedan svoj projekt razvio sustav koji ima osnovni dio i nekolicinu plugina/modula/drivera za specifičnu funkcionalnost. Sustav sam organizirao tako da je svaki od plugina bio u posebnom Python modulu, svi su moduli bili u jednom direktoriju a __init__.py iz tog direktorija sadržavao je kod za importanje svakog od pojedinih modula. Nezadovoljan time što imam 20 importova koje moram prepravljati svaki put kad dodam ili maknem plugin, odlučio sam učitavanje modula malo automatizirati.
Kako automatizirati otkrivanje i učitavanje modula u Python programu? Jednostavan način je pročešljati traženi direktorij, vidjeti postoji li nešto što izgleda kao Python source file i pokušati prilikom izvođenja programa importati taj modul. Problematičan dio je ubacivanje imporanih podataka tamo gdje želimo, odnosno pojednostavniti njihovo dohvaćanje iz ostatka programa.
Prvo kod (koji ide u plugins/__init__.py), onda objašnjenje:
plugins = []
for entry in os.listdir(os.path.dirname(__file__)):
if entry.endswith('.py') and entry != '__init__.py':
entry = entry[:-3]
try:
m = __import__(__name__ + '.' + entry)
m = getattr(m, entry)
p = getattr(m, 'MyPluginClass')
plugins.append(p)
except Exception, e:
print "Error while importing plugin %s: %s" % (entry, e)
Iz lokacije trenutnog modula saznaje se koji direktorij treba pregledavati za module – za svaku Python datoteku iz tog direktorija (osim samog sebe), probamo napraviti import modula (kako su svi pluginovi podmoduli trenutnog, trenutno ime modula se koristi kako bi se dobio puno ime modula za import). Nakon toga iz modul objekta izvučemo referencu na MyPluginClass (naziv klase u svakom od pluginova), iz koje kasnije možemo instancirati objekte iz pojedinih pluginova. Ukoliko nešto pođe po zlu, samo ignoriramo trenutnu datoteku i pokušavamo dalje.
Stvar koja ovdje izgleda čudno je dvostruki getattr. Naime, __import__ zapravo vraća referencu na trenutni modul, pa nakon toga prvo moramo dobiti referencu na modul koji učitavamo, te naposlijetku i na klasu unutar modula.
Uz kod još jedna napomena, dio koji odlučuje koju datoteku učitati na osnovu ekstenzije pretpostavlja da python datoteke završavaju sa ".py", stoga bi ovu skriptu trebalo prilagoditi ako se koristi na sustavu koji koristi drugačije ekstenzije.

Komentiranje zatvoreno.