2012-11-30 7 views
6

Sto riorganizzando il mio codice e quindi creando nuovi spazi dei nomi. Sto cambiando le classi "statiche" (classi con @staticmethod in ogni metodo) per i moduli. Questa è la strada da percorrere, vero?Buone pratiche che condividono le risorse tra i moduli?

Il problema è che ho dei dubbi su come condividere le risorse tra questi moduli.

Diciamo che avevo un modulo da cui stavo facendo tutte le connessioni al database, e ovviamente tutte le classi/metodi condividevano la variabile che memorizzava il cursore DB (sto usando SQLite). Ora, in diversi moduli, devono anche condividere il cursore.

Graphical representation of dependences

Quindi, le mie idee:

  • dichiarare la variabile globale in ogni modulo. Ma i globali sono malvagi, mangiano bambini e rubano il nostro lavoro. Quindi non so se questa è la strada da percorrere.

    '''Sub Module 1''' 
    
    global database_cursor 
    
  • Importa il database_module "padre" con la database_cursor originale e usare qualcosa di simile:

    '''Sub Module 1''' 
    
    db_cursor = database_module.database_cursor 
    

Questo secondo guarda bene in questo caso, ma credo che in molti casi porterà alle importazioni ricorsive, che immagino sia qualcosa da evitare.

+0

Penso che potresti essere [overengineering] (http://en.wikipedia.org/wiki/Overengineering). Se le funzioni necessitano di un cursore per lavorare basta aggiungere un parametro 'cursor' alle funzioni e il gioco è fatto. Il codice che chiama tutte le funzioni creerà una singola variabile locale contenente il cursore e lo passerà a tutte le funzioni. Inoltre, direi che un singolo modulo per la gestione del database è sufficiente. Se trovi che hai bisogno di più organizzazione, allora stai meglio usando qualcosa come "SQLAlchemy". – Bakuriu

+0

Non penso che sia finita l'ingegneria. È perfettamente lecito condividere cose come le connessioni al database per evitare un'inutile reinizializzazione. Tuttavia penso che sia saggio esaminare il pool di connessioni per questo. In caso contrario si avranno probabilmente problemi con la connessione ancora in uso da una precedente chiamata. – RickyA

risposta

7

Il tuo secondo metodo è la strada da percorrere. Le importazioni Python sono singleton per natura. Quando un modulo viene importato più volte, viene eseguito solo la prima volta. Le importazioni successive recuperano l'istanza dell'oggetto modulo dalle globali. Maggiori informazioni su questo here.

shared.py:

class Shared: 
    def __init__(self): 
     print("Init shared") 

    def do_stuff(self, from_mod): 
     print("Do stuff from {0}. I am instance {1}".format(from_mod, self)) 

shared = Shared() 

foo.py

import shared 

shared.shared.do_stuff("foo") 

bar.py

import foo 
import shared 

shared.shared.do_stuff("bar") 

Se eseguiamo bar.py otteniamo:

>>> Init shared 
>>> Do stuff from foo. I am instance <shared.Shared instance at 0x10046df38> 
>>> Do stuff from bar. I am instance <shared.Shared instance at 0x10046df38> 

Quindi nel tuo caso puoi fare riferimento a database_module da qualsiasi luogo tu voglia e viene inizializzato solo una volta, quindi in modo efficace condividendo la tua connessione.