Seite 1 von 1

Konstanten / globale Variablen überschreiben

Verfasst: Sonntag 20. März 2022, 19:16
von dirk1312
Hallo,

ich bin mir nicht sicher, was genau diese Variablen sind, Konstanten oder globale Variablen. Und zwar will ich auf dem Raspberry Pi ein Skript aktuell so umbauen, dass es seine Konfiguration aus einer Yaml-Datei liest und nicht mehr hart kodiert in dem Skript steht.

Hier ein verallgemeinerter Skript-Ausschnitt:

Code: Alles auswählen

import yaml

CONFIG_1 = ''
CONFIG_2 = ''

def init_config():
    configs = read_yaml('config/cfg.yml')
    CONFIG_1 = configs['config_1']
    CONFIG_2 = configs['config_2']

def read_yaml(yaml_file):
    with open(yaml_file) as cfg:
        return yaml.safe_load(cfg)

def do_something():
    # I'm using the CONFIG_1 and CONFIG_2 variable but it's empty

def main(prompt):
    try:
        init_script()
	do_something()
    except KeyboardInterrupt:
        pass
    finally:
        logging.info('Finishing script')
Wenn ich den Debugger durchlaufen lasse, dann sind in der Prozedur do_something die variable CONFIG_1 und CONFIG_2 leer. Obwohl die Werte richtig in configs stehen.

Was muss ich denn machen, um die Werte nicht in alle Prozeduren als Parameter geben muss, sondern sie in solche "globalen" (die skriptweit verfügbar sind) Variablen / Konstanten schreiben kann?

Vielen Dank und viele Grüße

Re: Konstanten / globale Variablen überschreiben

Verfasst: Sonntag 20. März 2022, 20:11
von sparrow
Konstanten heißen so, weil sie konstant sind - also nie geändert werden.
Globale Variablen sind böse, die benutzt man nicht.

Lies deine Konfiguration in eine Datenstruktur und übergebe die an die Funktionen, die sie brauchen.

Re: Konstanten / globale Variablen überschreiben

Verfasst: Sonntag 20. März 2022, 21:14
von dirk1312
Danke für deine Antwort.

Dann sind das tatsächlich Konstanten, danke. Dann werde ich es so machen, wie von dir beschrieben.

Re: Konstanten / globale Variablen überschreiben

Verfasst: Sonntag 20. März 2022, 21:23
von sparrow
Das was du hast, sind aber keine Konstanten. Denn sie werden ja im Programm verändert. Das wäre also der klassische Fall einer globalen Variable.

Re: Konstanten / globale Variablen überschreiben

Verfasst: Sonntag 20. März 2022, 21:37
von dirk1312
Ich bin jetzt doch noch auf ein Problem gestoßen. Wie löse ich denn folgendes:

In meinem Skript nutze ich mqtt. Wenn die Verbindung zum Broker hergestellt wurde, dann wird eine on_connect-Prozedur aufgerufen, um sich für ein best. Topic zu subscriben. Diese überschreibe ich in dem mqtt-Topic wie folgt:

Code: Alles auswählen

client.on_connect = on_connect

def on_connect(client, userdata, flags, rc):
    client.subscribe('my/mqtt/topic', 0)
Die Parameter, die daran übergeben werden bestimmte ich nicht selbst, sondern werden durch die client.on_connect-Prozedur bestimmt.

Kann ich dort ebenfalls die Konfigurationen aus der Konfigurationsdatei hineinbekommen? Ich möchte das Topic konfigurierbar machen. Dafür würde natürlich auch eine Konstante Sinn machen, aber ich stelle meinen Code in GitHub ein und, falls dieses jemand benutzen will, dann soll es so einfach wie möglich über die Konfigurations-Yml anpassbar sein, ohne im Code etwas ändern zu müssen.

Re: Konstanten / globale Variablen überschreiben

Verfasst: Sonntag 20. März 2022, 21:54
von __deets__
Das funktioniert auf verschiedene Arten. Eine ist functools.partial, aber noch üblicher wäre hier die Methode einer Klasse, die via reingereichter Konfiguration einfach das topic kennt, und sich entsprechend damit anmeldet.

Re: Konstanten / globale Variablen überschreiben

Verfasst: Montag 21. März 2022, 08:06
von dirk1312
Vielen Dank für eure Antworten.
sparrow hat geschrieben: Sonntag 20. März 2022, 21:23 Das was du hast, sind aber keine Konstanten. Denn sie werden ja im Programm verändert. Das wäre also der klassische Fall einer globalen Variable.
Sorry, den Kommentar hatte ich übersehen. Überschrieben waren sie ja nur, weil ich bei der Überarbeitung des Skripts versucht habe, deren Werte zu ändern. Was aber nicht geklappt hat. ;)

__deets__ hat geschrieben: Sonntag 20. März 2022, 21:54 Das funktioniert auf verschiedene Arten. Eine ist functools.partial, aber noch üblicher wäre hier die Methode einer Klasse, die via reingereichter Konfiguration einfach das topic kennt, und sich entsprechend damit anmeldet.
functools.partial werde ich mir auf jeden Fall (versuchen zu) merken. In meinem Fall habe ich jetzt eine andere Lösung gefunden: In jede dieser überschriebenen Prozeduren wird ein userdata-Parameter mit reingegeben. Diese kann ich u.a. beim Initialisieren des Mqtt-Clients setzen, nachdem ich die Konfiguration ausgelesen habe. Dort hinein setze ich dann z.B. die Mqtt-Topic-Namen, die ich in den on_connect und on_message Prozeduren benötige.

Re: Konstanten / globale Variablen überschreiben

Verfasst: Montag 21. März 2022, 08:08
von dirk1312
Vielen Dank für eure Antworten.
sparrow hat geschrieben: Sonntag 20. März 2022, 21:23 Das was du hast, sind aber keine Konstanten. Denn sie werden ja im Programm verändert. Das wäre also der klassische Fall einer globalen Variable.
Sorry, den Kommentar hatte ich übersehen. Überschrieben waren sie ja nur, weil ich bei der Überarbeitung des Skripts versucht habe, deren Werte zu ändern. Was aber nicht geklappt hat. ;)

__deets__ hat geschrieben: Sonntag 20. März 2022, 21:54 Das funktioniert auf verschiedene Arten. Eine ist functools.partial, aber noch üblicher wäre hier die Methode einer Klasse, die via reingereichter Konfiguration einfach das topic kennt, und sich entsprechend damit anmeldet.
functools.partial werde ich mir auf jeden Fall (versuchen zu) merken. In meinem Fall habe ich jetzt eine andere Lösung gefunden: In jede dieser überschriebenen Prozeduren wird ein userdata-Parameter mit reingegeben. Diese kann ich u.a. beim Initialisieren des Mqtt-Clients setzen, nachdem ich die Konfiguration ausgelesen habe. Dort hinein setze ich dann z.B. die Mqtt-Topic-Namen, die ich in den on_connect und on_message Prozeduren benötige.

Objektorientiert habe ich das ganze deshalb nicht gemacht, weil es in den ganzen Raspberry Pi-Forenbeiträgen, Tutorials,... die ich gelesen habe immer hieß, man solle den Raspberry Pi-Code als Skripte ohne Klassen, etc. schreiben. Bei mir nimmt das ganze auch nicht so eine Komplexität an, dass es ohne Objektorientierung unübersichtlich würde oder ich das Gefühl hätte, da groß Dinge kapseln zu müssen, etc.

Re: Konstanten / globale Variablen überschreiben

Verfasst: Montag 21. März 2022, 08:53
von __deets__
Was auch immer du da gelesen hast, ist großer Quatsch. Der Pi Code da draußen ist nahezu immer schlecht zusammengekloppt, und deckt auch nur absolut triviale Fälle ab. OO ist keine große Sache, und schon dein Beispiel rechtfertig das durchaus.

Re: Konstanten / globale Variablen überschreiben

Verfasst: Montag 21. März 2022, 09:25
von dirk1312
Danke für die Einschätzung. Grundsätzlich ist es ja wirklich keine große Sache, daraus ein paar Klassen, etc. zu machen. Dann werde ich erstmal die Konfigurationsgeschichte fertig machen und sicherstellen, dass die noch läuft. Danach werde ich es dann in OO umwandeln.