Guten Morgen,
ich hatte mal gelesen, das globale Variablen zu vermeiden sind.
Wenn man aber einen Datensatz in einer Class oder Def erhebt und diesen im Programm permanent zur Verfügung stellen muss und es keine sicherheitsrelevanten Daten sind, was spricht dagegen?
Bisher habe ich aus Class und Def immer mit Rückgabewert gearbeitet..
Ich komme aber aktuell in Phasen wo globale Variablen mir praktischer erscheinen.
Oder schätze ich hier etwas falsch ein.
Globale Variablen können doch eigentlich nur zur Gefahr werden, wenn in einer anderen Funktion eine Variable erstellt wird die den selben Namen hat.
Also eindeutige Benennung der Variablen... Beispiel
global glob_variable
Gruß Ralf
Globale Variablen ja/nein
- DeaD_EyE
- User
- Beiträge: 1371
- Registriert: Sonntag 19. September 2010, 13:45
- Wohnort: Hagen
- Kontaktdaten:
Ja und nein.kiaralle hat geschrieben: Mittwoch 5. August 2026, 07:16 Globale Variablen können doch eigentlich nur zur Gefahr werden, wenn in einer anderen Funktion eine Variable erstellt wird die den selben Namen hat.
Also eindeutige Benennung der Variablen... Beispiel
global glob_variable
Nein, wenn es sich um Objekte handelt, die unveränderbar sind. Das sind z.B. int, str, bytes, tuple.
Ja, wenn man Methoden veränderbarer Objekte aufruft wie z.B. append(element) bei einer Liste. Dann wird das Objekt modifiziert (nicht neu zugewiesen).
Wenn man global nicht nutzt, kann man dem globalen Namen kein neues Objekt zuweisen, kann aber das Objekt verändern, wenn es veränderbar (mutable) ist.
Es ist z.B. in Ordnung, wenn man Konstanten im Programm hat, auf die man lesend zugreift. Viele nutzen Klassen oder Enum für sowas.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Mein Gedanke war der, das ich dem User über ein Setupmenu eine Auswahl treffen lasse.
Motor und Geber, jeweils getrennt aus zwei SQLite-Tabellen.
An anderen Stellen benötige ich verschiedene Werte für Berechnungen aus diesen beiden Tabellen.
Ich merke mir die ID der beiden Datensätze global und kann somit im ganzen Programm sofor darauf zugreifen und in den Tabellen bestimmte Daten ziehen.
Wenn ich nicht global Variablen verwende, wüsste ich zu viel hin und her springen.
Ich glaube ich teste das mal so aus, geh in den Garten und mir fällt danach wieder was einfacheres ein.
Jedenfalls lerne ich wieder etwas.
Motor und Geber, jeweils getrennt aus zwei SQLite-Tabellen.
An anderen Stellen benötige ich verschiedene Werte für Berechnungen aus diesen beiden Tabellen.
Ich merke mir die ID der beiden Datensätze global und kann somit im ganzen Programm sofor darauf zugreifen und in den Tabellen bestimmte Daten ziehen.
Wenn ich nicht global Variablen verwende, wüsste ich zu viel hin und her springen.
Ich glaube ich teste das mal so aus, geh in den Garten und mir fällt danach wieder was einfacheres ein.
Jedenfalls lerne ich wieder etwas.
Das ist nicht robust, wenn man das allgemein betrachtet. Du arbeitest vermutlich mit einem User. Was ist wenn dass das Backend für eine Webanwendung wird und mehrere User eine Auswahl treffen?
Man kann Werte von Klassenattributen lesen, es muss nicht immer eine Methode sein, die per return etwas zurück gibt.
Ich würde es nicht mit globalen Variablen lösen. Zielführender wäre es, wenn du dir eine Möglichkeit erarbeitest, wie es "richtig" geht. Anhand der Auswahl würde ich vermutlich ein Objekt erstellen, dass die Auswahl enthält und das kann man dann herumreichen, lesen und vorallem kann man damit auch die Eingabewerte vallidieren.
Hast du ein Beispiel?
Man kann Werte von Klassenattributen lesen, es muss nicht immer eine Methode sein, die per return etwas zurück gibt.
Ich würde es nicht mit globalen Variablen lösen. Zielführender wäre es, wenn du dir eine Möglichkeit erarbeitest, wie es "richtig" geht. Anhand der Auswahl würde ich vermutlich ein Objekt erstellen, dass die Auswahl enthält und das kann man dann herumreichen, lesen und vorallem kann man damit auch die Eingabewerte vallidieren.
Hast du ein Beispiel?
"When I got the music, I got a place to go" [Rancid, 1993]
- noisefloor
- User
- Beiträge: 4336
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Grundsätzlich: nein
Da hat auch nichts (und so rein gar nichts) mit "sicherheitsrelevant" zu tun. Du kommst in Python sowieso jederzeit an alles dran, egal ob lokal, global oder Attribute oder ... Globalen Variablen machen den Zustand des Programms einfach unübersichtlich, weil globalen Variablen im Prinzip jederzeit und überall geändert werden können.
Es gibt Anwendungsfälle, wo globale Variablen Sinn machen - klingt bei dir aber nicht so. Abgesehen von der Beschreibung an sich ist die Aussage "wo globale Variablen mir praktischer erscheinen." ein Indiz dafür, dass deine Programmstruktur wahrscheinlich verbessert werden könnte.
Gruß, noisefloor
Da hat auch nichts (und so rein gar nichts) mit "sicherheitsrelevant" zu tun. Du kommst in Python sowieso jederzeit an alles dran, egal ob lokal, global oder Attribute oder ... Globalen Variablen machen den Zustand des Programms einfach unübersichtlich, weil globalen Variablen im Prinzip jederzeit und überall geändert werden können.
Es gibt Anwendungsfälle, wo globale Variablen Sinn machen - klingt bei dir aber nicht so. Abgesehen von der Beschreibung an sich ist die Aussage "wo globale Variablen mir praktischer erscheinen." ein Indiz dafür, dass deine Programmstruktur wahrscheinlich verbessert werden könnte.
Gruß, noisefloor
Dann mal Butter bei de Fisch
ich suche mir über die einzelnen Schritte den Motor und den Geber aus den zwei Tabelen aus der DB servo.
Tabelle motor = Motorhersteller, Motortyp, Motorpole
Tabelle geber = Hersteller, Model
Das funktioniet alles wunderbar über tkinter.
Ich erhalte eine ID vom Datensatz.
Die möchte ich weiter frei und jederzeit im Code verwenden.
Nur wo speichere ich die beiden IDs (Geber und Motor) ab?
Das mach ich jetzt aktuell über die globale Variaben motor_db_id und geber_id und lese ab und zu aus den zwei Tabellen.
Diese auslesen werde ich in diese Class Datenbank integrieren. Ist nicht das Problem.
Ich gehe in drei Jahren in Rente und möchte ein Prüfsystem für meine Kollegen hinterlassen.
Die beiden ID sollen jetzt zum Bleistift hier in diese Class Hiperface einfließen.
Dann benötige ich keine der vielen Variablen und ich könnte aus der DB die verschiedenen Parameter der verschiedenen Geber ziehen.
Da stehen aktuell nur Testparameter drinnen die ich als "feste Variablen" da zur Verfügung stelle..
ich suche mir über die einzelnen Schritte den Motor und den Geber aus den zwei Tabelen aus der DB servo.
Tabelle motor = Motorhersteller, Motortyp, Motorpole
Tabelle geber = Hersteller, Model
Das funktioniet alles wunderbar über tkinter.
Ich erhalte eine ID vom Datensatz.
Die möchte ich weiter frei und jederzeit im Code verwenden.
Nur wo speichere ich die beiden IDs (Geber und Motor) ab?
Das mach ich jetzt aktuell über die globale Variaben motor_db_id und geber_id und lese ab und zu aus den zwei Tabellen.
Diese auslesen werde ich in diese Class Datenbank integrieren. Ist nicht das Problem.
Ich gehe in drei Jahren in Rente und möchte ein Prüfsystem für meine Kollegen hinterlassen.
Code: Alles auswählen
class Datenbank(object):
def __init__(self, motorhersteller_combo, motorhersteller_var, motortyp_combo, motortyp_var,
motorpolpaar_combo, motorpolpaar_var, geberhersteller_combo, geberhersteller_var,
gebertyp_combo, gebertyp_var,
geberdaten, conect_progress):
self.motorhersteller_combo = motorhersteller_combo
self.motorhersteller_var = motorhersteller_var
self.motortyp_combo = motortyp_combo
self.motortyp_var = motortyp_var
self.motorpolpaar_combo = motorpolpaar_combo
self.motorpolpaar_var = motorpolpaar_var
self.geberhersteller_combo = geberhersteller_combo
self.geberhersteller_var = geberhersteller_var
self.gebertyp_combo = gebertyp_combo
self.gebertyp_var = gebertyp_var
self.geberdaten = geberdaten
self.conect_progress = conect_progress
def motorhersteller_sqlite(self):
try:
db_abfrage.execute("SELECT DISTINCT hersteller FROM motor")
self.motorhersteller_combo['values'] = db_abfrage.fetchall()
except verbindung.DatabaseError as error:
print(error)
def motortyp_sqlite(self):
try:
db_abfrage.execute('SELECT typ FROM motor WHERE hersteller = ?' , (self.motorhersteller_var.get(),))
self.motortyp_combo['values'] = db_abfrage.fetchall()
except verbindung.DatabaseError as error:
print(error)
def motorpolpaar_sqlite(self):
try:
db_abfrage.execute('SELECT id,pole FROM motor WHERE typ = ?' , (self.motortyp_var.get(),))
abfrage=db_abfrage.fetchall()
self.motorpolpaar_combo['values'] = abfrage[0][1]
#print(db_abfrage)
global motor_db_id
motor_db_id = abfrage[0][0]
except verbindung.DatabaseError as error:
print(error)
#Geberauswahl
def geberhersteller_sqlite(self):
self.geberdaten.delete("1.0", END)
try:
db_abfrage.execute("SELECT DISTINCT hersteller FROM geber")
self.geberhersteller_combo['values'] = db_abfrage.fetchall()
except verbindung.DatabaseError as error:
print(error)
def gebertyp_sqlite(self):
if self.geberhersteller_var.get() == "Sick":
self.gebertyp_combo['values'] = "Hiperface-Auto"
self.geberdaten.insert('1.0', "Es wird nach einem Geber an \nSchnittstelle X gesucht und automatisch eingestellt")
data = bytearray.fromhex("FF52")
data.append(ChecksumXor8.calc(data))
try:
data = endat_data.send(data)
response = endat_data.receive(7)
if response.hex()[2:4] == "50" or ChecksumXor8.calc(response) != 0:
error = sick_error.error(response.hex()[4:6])
print(error)
else:
model_id = response[3:4].hex()
try:
db_abfrage.execute('SELECT * FROM geber WHERE model_id =?', (model_id,))
abfrage = db_abfrage.fetchall()
self.geberdaten.delete("1.0", END)
except verbindung.DatabaseError as error:
print(error)
except Exception as e1:
print ("error communicating...: " + str(e1))
else:
try:
db_abfrage.execute('SELECT model FROM geber WHERE hersteller = ?' , (self.geberhersteller_var.get(),))
self.gebertyp_combo['values'] = db_abfrage.fetchall()
db_abfrage.execute('SELECT * FROM geber WHERE hersteller = ?' , (self.geberhersteller_var.get(),))
abfrage = db_abfrage.fetchall()
except verbindung.DatabaseError as error:
print(error)
datenkopf=["Typ:", "Datenverbindung:", "Model-ID:", "Sin-Cos / U:", "Singleturn:", "Multiturn:", "Speicher", "Hersteller:","Z-Spur:","DB-id:"]
#datensatz=datenkopf[0],abfrage[0][1],"\n\r",datenkopf[1],abfrage[0][2]
datensatz = "{} {} \n{} {} \n{} {} \n{} {} \n{} {} \n{} {} \n{} {} \n{} {} \n{} {} \n{} {}".format(datenkopf[0], abfrage[0][1],
datenkopf[1] , abfrage[0][2], datenkopf[2] ,abfrage[0][3],
datenkopf[3] ,abfrage[0][4], datenkopf[4] ,abfrage[0][5],
datenkopf[5] ,abfrage[0][6], datenkopf[6] ,abfrage[0][7],
datenkopf[7] ,abfrage[0][8], datenkopf[8] ,abfrage[0][9],
datenkopf[9] ,abfrage[0][0]
)
global geber_db_id
geber_db_id = abfrage[0][0]
self.geberdaten.insert('1.0',datensatz) # Daten werden im Fenster Geberinfo angezeigt.
Die beiden ID sollen jetzt zum Bleistift hier in diese Class Hiperface einfließen.
Dann benötige ich keine der vielen Variablen und ich könnte aus der DB die verschiedenen Parameter der verschiedenen Geber ziehen.
Da stehen aktuell nur Testparameter drinnen die ich als "feste Variablen" da zur Verfügung stelle..
Code: Alles auswählen
class Hiperface(object):
def __init__(self,polpaar,singleturn,multiturn, conect_progress, positions_value):
self.polpaar = polpaar
self.singleturn = singleturn
self.multiturn = multiturn
self.conect_progress = conect_progress
self.positions_value = positions_value
def position(self):
data = bytearray.fromhex("FF42")
data.append(ChecksumXor8.calc(data))
try:
data = endat_data.send(data)
response = endat_data.receive(7)
if response.hex()[2:4] == "50" or ChecksumXor8.calc(response) != 0:
error = sick_error.error(response.hex()[4:6])
print(error)
self.conect_progress.stop()
else:
realposition = int.from_bytes(response[2:6],'big',signed=True)
#Prüfen start
self.conect_progress.start()
self.positions_value["text"] = realposition
schrittzahl_umdrehung_faktor = math.modf(realposition / self.multiturn)
mech_winkel = round((360 / 1) * (schrittzahl_umdrehung_faktor[0]) )
inkrement_teilung = round(self.multiturn / self.polpaar,2)
offset_winkel = round(360/inkrement_teilung * realposition%360,2)
#mech_winkel = round(360/max_inkrement * realposition,2)
# Prüfen ende
self.positions_value.after(100, self.position)
return realposition , mech_winkel, offset_winkel
except Exception as e1:
print ("error communicating...: " + str(e1))
self.positions_value.after(10, self.position)
def resetposition(self):
setposition ="00000000"
data = bytearray.fromhex("FF 43" + setposition + "55")
data.append(ChecksumXor8.calc(data))
try:
data = endat_data.send(data)
time.sleep(0.01)
response = endat_data.receive(7)
if response.hex()[2:4] == "50" or ChecksumXor8.calc(response) != 0:
error = "Fehler : " + sick_error.error("0f")
print(error)
else:
info = "Phasenlage neu gesetzt "
return info
except Exception as e1:
print ("error communicating...: " + str(e1))
Wenn ich aber die class Datenbank als Anlaufstelle für alles nehme, dann weiß diese class über den aktuellen Motor und Geber bescheid und kann mit einfachen Return immer die Antworten geben.
Oder vergisst die class nach dem Verlassen die Daten?
Könnte gehen. Ich bastel und denke.
War nämlich gerade im Garten
Oder vergisst die class nach dem Verlassen die Daten?
Könnte gehen. Ich bastel und denke.
War nämlich gerade im Garten
- noisefloor
- User
- Beiträge: 4336
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
genau genommen weiß die Klasse gar nichts, die ist nur die Grundlage. Die Daten sind in der jeweiligen Instanz der Klassen und ja, man beliebig viele Instanzen haben, die alle verschiedene Daten haben. Instanzen sind ja normalerweise an ein Objekt mit einem einmaligen Namen im aktuellen Namensraum gebunden. Und solange der Namensraum existiert (i.d.R. so lange das Skript läuft oder interaktive Interpreter, in dem die Klasse instanziert wurde) existieren die Daten.
Das sind (fortgeschrittene) Grundlagen, die man beim Umgang mit Klassen kennen sollte. Ggf. möchtest du nochmal dazu die passende Sektion im Python-Tutorial lesen.
Gruß, noisefloor
genau genommen weiß die Klasse gar nichts, die ist nur die Grundlage. Die Daten sind in der jeweiligen Instanz der Klassen und ja, man beliebig viele Instanzen haben, die alle verschiedene Daten haben. Instanzen sind ja normalerweise an ein Objekt mit einem einmaligen Namen im aktuellen Namensraum gebunden. Und solange der Namensraum existiert (i.d.R. so lange das Skript läuft oder interaktive Interpreter, in dem die Klasse instanziert wurde) existieren die Daten.
Das sind (fortgeschrittene) Grundlagen, die man beim Umgang mit Klassen kennen sollte. Ggf. möchtest du nochmal dazu die passende Sektion im Python-Tutorial lesen.
Gruß, noisefloor
