Hi !
Ich habe 3 Python files nennen wir sie a.py, b.py und db.py
db.py ist eine einfache wrapper klasse für den Zugriff auf MySQL. b.py included db.py um mittels einer Instanz der Klasse Datenbankoperationen durchzuführen. Selbiges macht auch a.py aber a.py included zusätzlich noch b.py um einige Funktionen daraus zu nutzen.
Wenn ich aber b.py in a.py include habe ich dort schon mal zwei Instanzen von der db Klasse obwohl eine reichen würde.
Hoffe es ist einigermaßen klar was ich meine. Nun zu meinem Problem: Irgendwie scheint mir das nicht sonderlich elegant. Wie würde man einen zentralen Zugriffspunkt auf die db sauber implementieren ?
Danke!
Mehrfaches includen einer Datenbankklasse
Entweder ohne Klasse, oder mit einer Factory-Funktion, die bei den gleichen Verbindungsdaten auch das selbe Objekt zurückgibt. Je nachdem wie komplex es werden soll, oder wie einfach es bleiben darf.
Die einfachste Variante wäre es, das Modul als "Singleton" zu benutzen.
Die einfachste Variante wäre es, das Modul als "Singleton" zu benutzen.
Ok ich glaub ich muss noch etwas über Softwaretechnik lesen um Möglichkeit 2 umzusetzen
Aber Wenn ich keine Klasse verwenden würde, hätte ich die Möglichkeit entweder bei jedem Datenbankaufruf eine neue Verbindung zu öffnen und wieder zu schließen (sehr langsam bei vielen Aufrufen vermute ich mal) oder ich öffne die Verbindung einmal am Anfang und stelle diese global zu Verfügung. Aber dann habe ich wieder das Problem beim includen von b.py in a.py (die ja beide eine globale db Verbindung bereitstellen) oder ?

Ich weiss nicht ob ich das Problem richtig verstehe: Wenn Du `db` sowohl in `a` als auch in `b` importierst, dann gibt es nur *ein* `db`-Modul-Objekt und nicht zwei. Wenn Du also in `db` *eine* Datenbankverbindung verwaltest, gibt es auch nur eine im ganzen Programm.
Wirklich minimal liesse sich das so lösen:
Wirklich minimal liesse sich das so lösen:
Code: Alles auswählen
import db # Das "echte" Datenbankmodul.
connection = None
def connect(params):
global connection
connection = db.connect(params)
return connection
def final_close():
connection.close()
Hmm...
Ich versuchs nochmal genauer zu erklären:
db.py
b.py
a.py
die Funktion g() (und weitere) in b.py nutzt jetzt das globale db Objekt in b.py
In a.py gibt es Funktionen (wie f1() ) die eine db Verbindung brauchen daher auch hier ein db Objekt. Es werden aber weiterhin Funktionen aus dem includierten b.py aufgerufen. In dem Moment wo ich aber b.py in a.py includiere habe ich doch 2 Objekte (auch noch gleichen namens) ?
Das Problem ist eben, dass ich in beiden files ein db Objekt brauche (denn beide files sollen auch unabhängig vom anderen lauffähig sein) aber ich Probleme bekomme wenn ich die eine in die andere Datei includiere.
Ich hoffe es ist so klarer was mein Problem ist - sorry falls die bisherigen Lösingsansätze schon auf dieses Problem passen - dann habe ich das noch nicht verstanden...
Danke!
Ich versuchs nochmal genauer zu erklären:
db.py
Code: Alles auswählen
import MySQLdb
class mSQL:
def __init__(self, host, user, passwd, db):
def connect(self):
def getQuery(self, query):
def disconnect(self):
Code: Alles auswählen
import db.py
db = mSQL.mSQL(host,user,passw,name)
db.connect()
def g:
...
db.disconnect()
a.py
Code: Alles auswählen
import db.py
import b.py
db = mSQL.mSQL(host,user,passw,name)
db.connect()
def f1:
...
f1()
b.g()
db.disconnect()
die Funktion g() (und weitere) in b.py nutzt jetzt das globale db Objekt in b.py
In a.py gibt es Funktionen (wie f1() ) die eine db Verbindung brauchen daher auch hier ein db Objekt. Es werden aber weiterhin Funktionen aus dem includierten b.py aufgerufen. In dem Moment wo ich aber b.py in a.py includiere habe ich doch 2 Objekte (auch noch gleichen namens) ?
Das Problem ist eben, dass ich in beiden files ein db Objekt brauche (denn beide files sollen auch unabhängig vom anderen lauffähig sein) aber ich Probleme bekomme wenn ich die eine in die andere Datei includiere.
Ich hoffe es ist so klarer was mein Problem ist - sorry falls die bisherigen Lösingsansätze schon auf dieses Problem passen - dann habe ich das noch nicht verstanden...
Danke!
Ich glaube Du verstehst ``import`` falsch. Das schaut nach, ob das Modul schon geladen wurde, falls ja wird einfach das schon geladene Modulobjekt an den entsprechenden Namen im importierenden Modul gebunden, ansonsten wird es einmal geladen und der Code auf Modulebene wird ausgeführt.
``import`` ist kein ``#include`` wie in C, das den Quelltext des anderen Moduls an der Stelle einsetzt wo es steht. Bei Deinen Beispielen gehe ich mal davon aus, dass Du nicht ``mSQL.mSQL(…)`` sondern ``db.mSQL(…)`` in den Modulen `a` und `b` meinst. Du hast nach dem Ablauf von `a` zwei Datenbank-Objekte, eines das in `a` über den Namen `db` erreichbar ist, und ein anderes das `b.db` heisst.
``import`` ist kein ``#include`` wie in C, das den Quelltext des anderen Moduls an der Stelle einsetzt wo es steht. Bei Deinen Beispielen gehe ich mal davon aus, dass Du nicht ``mSQL.mSQL(…)`` sondern ``db.mSQL(…)`` in den Modulen `a` und `b` meinst. Du hast nach dem Ablauf von `a` zwei Datenbank-Objekte, eines das in `a` über den Namen `db` erreichbar ist, und ein anderes das `b.db` heisst.