2009-06-21 13 views
15

In passato ho utilizzato la funzione AUTOLOAD di perl per implementare il caricamento pigro dei simboli in uno spazio dei nomi e volevo la stessa funzionalità in python.Autoload in Python

Tradizionalmente il più vicino che si riesce a ottenere è quello di utilizzare una classe e una classe __getattr__ per ottenere questo tipo di cose. Tuttavia Ho anche provato a rovistare sys.modules, e venire con questo:

# mymod.py 
def greet(greeting="Hello World"): 
    print greeting 

class autoload(object): 
    def __init__(self, __name__): 
     super(autoload, self).__init__() 
     self.wrapped_name = __name__ 
     self.wrapped = sys.modules[__name__] 
    def __getattr__(self, name): 
     try: 
      return getattr(self.wrapped, name) 
     except AttributeError: 
      def f(): 
       greet(name+" "+self.wrapped_name) 
      return f 

if __name__ != "__main__": 
    import sys 
    sys.modules[__name__] = autoload(__name__) 

Questo funziona il modo in cui mi piacerebbe da un punto di vista dell'utente:

~> python 
Python 2.5.1 (r251:54863, Jan 10 2008, 18:01:57) 
[GCC 4.2.1 (SUSE Linux)] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import mymod 
>>> mymod.hello() 
hello 
>>> from mymod import Hello_World 
>>> Hello_World() 
Hello_World 

Ma mi colpisce - c'è un approccio standard che le persone tendono ad usare per l'autoloading in Python?

In secondo luogo, una domanda per esperti sviluppatori Python è davvero "questo ti colpisce come buona o cattiva pratica"? Sono uno sviluppatore python abbastanza esperto e mi sembra davvero utile, ma mi sembra marginale e interessato a vedere se questo può essere visto come una buona pratica, una cattiva pratica o qualcosa di simile.

Grazie!

+0

https://stackoverflow.com/questions/2447353/getattr-on-a-module e https://stackoverflow.com/questions/922550/how-to-mark-a-global-as-deprecated-in -python/922693 # 922693 – n611x007

+0

Vorrei eliminarlo se possibile, perché le modifiche al testo della domanda e il codice e i tag non riflettono più la mia domanda originale. Le risposte qui sotto non sono particolarmente utili neanche.Mi auguro che la gente in realtà chieda prima di cambiare il testo di una domanda di qualcuno. Ad esempio, il motivo per cui il codice originale utilizzato "\ _ \ _ nome \ _ \ _" piuttosto che "nome_mod" è mostrare la diretta somiglianza a sys.modules [\ _ \ _ nome \ _ \ _] e così via. Questo è stato rotto da modifiche. –

+1

@MichaelSparks: ho inoltrato la domanda alla modifica secondaria di SilentGhost. Speriamo che abbini le risposte meglio ora. E nessuno dovrebbe modificare il codice nella domanda di qualcun altro. –

risposta

10

"Importazioni pigre" potrebbe essere costruito sopra i "nuovi ganci di importazione" specificati in PEP 302 e ora completamente implementato. PEP 369 usato per coprire "importazioni pigre" e ganci post-importazione, ma da allora è stato semplificato e ora copre solo i ganci post-importazione; tuttavia, potresti essere interessato allo original draft.

Una buona implementazione di "importazioni pigre" tramite il gancio meta_path può essere trovata in this recipe.

-1

No, non penso sia utile.

Perché creare una funzione al volo per l'attributo ogni che stai cercando di ottenere dal modulo? Sembra confondermi. Sembra che le nuove funzioni vengano create dalla magia, quindi è necessario esaminare in profondità l'implementazione per capire cosa sta succedendo. E tutto ciò senza vantaggi sintattici.

E anche se avessi una buona ragione per farlo, perché farlo con un modulo? Perché registrare la tua istanza di classe in sys.modules? Penso che far apparire le cose che non sono è disapprovato in python.

A meno che non si stia occultando il codice di proposito, non vedo perché si farebbe tutto questo.

+2

questo è sicuramente utile in alcuni casi, quando si desidera ridurre al minimo il tempo di importazione, ad esempio. Ma è sempre borderline e rende le cose più complicate (in particolare il debugging). I ganci di importazione sono difficili da ottenere in ogni situazione. Eviterei loro quanto più possibile le librerie "core" che sono destinate ad essere utilizzate al di fuori del loro utilizzo principale. –

+0

+1 per il commento di David. Le importazioni pigre aggiungono un ulteriore livello di complessità allo stato di qualsiasi modulo. È vero che potrebbe salvare qualche istante la scrittura delle istruzioni di importazione, ma quel tempo andrà perso nel debug. Incidentalmente molti IDE moderni hanno la capacità di gestire le importazioni. Dai un'occhiata a pydev su Eclipse. –

+3

Per cose come i wrapper API REST, in cui il nome della funzione diventa l'URI, ad esempio, è perfettamente utile. Denominare ciascuna funzione è sciocca. E il fatto che il nome di ogni funzione sia una stringa fa sì che il codice dell'utente sia più difficile, non più facile da leggere. –

0

di rispondere alla domanda di utilizzo di una classe di impersonare un modulo:

Sì, la funzionalità non è casuale. È presente fin dall'inizio della serie 2.x e funziona ancora nella serie 3.x.

di rispondere alla domanda di pigro carico:

Ci sono diversi modi per farlo, e ognuno sta per essere un po 'misterioso. Usare un sosia di moduli è un buon metodo.

Problemi correlati