2012-11-30 10 views
6

Reorganizuję mój kod i dlatego tworzę nowe przestrzenie nazw. Zmieniam klasy "statyczne" (klasy z @staticmethod w każdej metodzie) dla modułów. To jest droga, prawda?Dobre praktyki dzielenia zasobów między modułami?

Problem polega na tym, że mam wątpliwości, w jaki sposób udostępniać zasoby między tymi modułami.

Załóżmy, że mam moduł, z którego robiłem wszystkie połączenia z bazą danych, i oczywiście wszystkie klasy/metody dzieliły zmienną, która zapisała kursor DB (używam SQLite). Teraz, w różnych modułach, muszą również udostępniać kursor.

Graphical representation of dependences

Więc moje pomysły:

  • Zadeklaruj zmienną globalną w każdym module. Ale globale są złe, jedz dzieci i kradną nasze posady. Więc nie wiem, czy to jest droga.

    '''Sub Module 1''' 
    
    global database_cursor 
    
  • importu „ojcem” database_module z oryginalnym database_cursor i używać coś takiego:

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

Ten drugi wygląda dobrze w tym przypadku, ale myślę, że w wielu przypadkach doprowadzi do rekurencyjnego importu, co, jak sądzę, jest czymś, czego należy unikać.

+0

Myślę, że możesz być [nadmiernie nerwowy] (http://en.wikipedia.org/wiki/Overengineering). Jeśli funkcje wymagają kursora, po prostu dodaj parametr 'cursor' do funkcji i gotowe. Kod wywołujący całą funkcję utworzy pojedynczą zmienną lokalną zawierającą kursor i przekazującą go do wszystkich funkcji. Powiedziałbym też, że wystarczy jeden moduł do zarządzania bazą danych. Jeśli okaże się, że potrzebujesz więcej organizacji, lepiej użyj czegoś takiego jak 'SQLAlchemy'. – Bakuriu

+0

Nie sądzę, że to już koniec prac inżynieryjnych. Całkowicie legalne jest udostępnianie takich danych jak połączenia z bazami danych, aby uniknąć niepotrzebnej reinicjalizacji. Uważam jednak, że mądrze jest przyjrzeć się łączeniu połączeń w tym zakresie. W przeciwnym razie prawdopodobnie wystąpią problemy z połączeniem, które jest nadal używane z poprzedniego połączenia. – RickyA

Odpowiedz

7

Twoja druga metoda jest drogą do zrobienia. Python import ma charakter singletonowy. Gdy moduł jest importowany wiele razy, jest wykonywany tylko za pierwszym razem. Kolejne importowania pobierają instancję obiektu modułu z globali. Więcej informacji na ten temat: 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") 

Jeśli wykonujemy bar.py otrzymujemy:

>>> 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> 

W twoim przypadku możesz odnieść się do numeru database_module z dowolnego miejsca i zostanie on zainicjalizowany tylko raz, dzięki czemu skutecznie udostępni połączenie.

Powiązane problemy