Servus,
Ich bin noch recht neu in der Python-Programmierung, und habe im Internet nicht dies bezüglich gelesen.
Aus Batch kenne ich es das ich mit dem Befehl set eine Variable setzen kann die sich zb. in einer if-Abfrage ändern lässt.
In Python ist das ja mit normalen Variablen meines Wissens nach nicht möglich.
Gibts trotzdem ne Möglichkeit veränderebare Variablen zu nutzen?
LG
set-Äquivalent in Python
Wie kommst du darauf, dass das nicht moeglich ist?
Code: Alles auswählen
variable = "wert"
if variable == "etwas":
print("variable war etwas")
variable = "etwas"
if variable == "etwas":
print("variable war etwas")
- __blackjack__
- User
- Beiträge: 14076
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Leon33: Nichtveränderbare Variablen wären ja Konstanten. Genau *die* hat Python nicht als Sprachkonstrukt — alle Variablen sind veränderbar, im Sinne von man kann nacheinander unterschiedliche Werte an jeden Namen binden — sondern Konstanten sind per Namenskonvention (KOMPLETT_GROSS) Variablen die man nicht ändert, auch wenn man das theoretisch (und auch praktisch) machen könnte.
Ich vermute mal Du hast ein Problem mit Namensräumen, dass Du einen Wert an einen Namen ausserhalb eine Namensraums an einen anderen Wert binden willst. Dann müsstest Du mal konkret zeigen wo das Problem ist. Und gleich als Info vorweg: Wenn Du globale Variablen haben willst, wird die Antwort sein Nein, Du willst keine globalen Variablen haben, weil das niemand will, der nachvollziehbare, verständliche, wartbare, erweiterbare Programme, oder kurz einfach Programme schreiben will.
Ich vermute mal Du hast ein Problem mit Namensräumen, dass Du einen Wert an einen Namen ausserhalb eine Namensraums an einen anderen Wert binden willst. Dann müsstest Du mal konkret zeigen wo das Problem ist. Und gleich als Info vorweg: Wenn Du globale Variablen haben willst, wird die Antwort sein Nein, Du willst keine globalen Variablen haben, weil das niemand will, der nachvollziehbare, verständliche, wartbare, erweiterbare Programme, oder kurz einfach Programme schreiben will.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Ich habe nichts verstanden xD__blackjack__ hat geschrieben: Samstag 15. Oktober 2022, 20:14 @Leon33: Nichtveränderbare Variablen wären ja Konstanten. Genau *die* hat Python nicht als Sprachkonstrukt — alle Variablen sind veränderbar, im Sinne von man kann nacheinander unterschiedliche Werte an jeden Namen binden — sondern Konstanten sind per Namenskonvention (KOMPLETT_GROSS) Variablen die man nicht ändert, auch wenn man das theoretisch (und auch praktisch) machen könnte.
Ich vermute mal Du hast ein Problem mit Namensräumen, dass Du einen Wert an einen Namen ausserhalb eine Namensraums an einen anderen Wert binden willst. Dann müsstest Du mal konkret zeigen wo das Problem ist. Und gleich als Info vorweg: Wenn Du globale Variablen haben willst, wird die Antwort sein Nein, Du willst keine globalen Variablen haben, weil das niemand will, der nachvollziehbare, verständliche, wartbare, erweiterbare Programme, oder kurz einfach Programme schreiben will.![]()
Kannst du das evtl. nochmal verständlicher Erklären?
In meinem Fall geht es darum, ich möchte den Status einer Verbindung zu einem NAS mit einer if-Abfrage abfragen. Wenn diese Abfrage mit True beantwortet wird. Soll in eine Variable der Wert "online" eingetragen werden damit ich diese im Weiteren Fall verwenden kann. Sollte die Verbindung zur NAS nicht vorhanden sein, dann soll in die Variable "offline" eingetragen werden, so das ich in weiteren Schritten meines Programme bestimmte Aktionen davon abhängig machen kann ob die NAS verbunden ist oder nicht.Leon33 hat geschrieben: Samstag 15. Oktober 2022, 21:55Ich habe nichts verstanden xD__blackjack__ hat geschrieben: Samstag 15. Oktober 2022, 20:14 @Leon33: Nichtveränderbare Variablen wären ja Konstanten. Genau *die* hat Python nicht als Sprachkonstrukt — alle Variablen sind veränderbar, im Sinne von man kann nacheinander unterschiedliche Werte an jeden Namen binden — sondern Konstanten sind per Namenskonvention (KOMPLETT_GROSS) Variablen die man nicht ändert, auch wenn man das theoretisch (und auch praktisch) machen könnte.
Ich vermute mal Du hast ein Problem mit Namensräumen, dass Du einen Wert an einen Namen ausserhalb eine Namensraums an einen anderen Wert binden willst. Dann müsstest Du mal konkret zeigen wo das Problem ist. Und gleich als Info vorweg: Wenn Du globale Variablen haben willst, wird die Antwort sein Nein, Du willst keine globalen Variablen haben, weil das niemand will, der nachvollziehbare, verständliche, wartbare, erweiterbare Programme, oder kurz einfach Programme schreiben will.![]()
Kannst du das evtl. nochmal verständlicher Erklären?
- __blackjack__
- User
- Beiträge: 14076
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@Leon33: Du behauptest Python hätte nicht das was Du willst, sondern nur „normale Variablen“. Das was Du beschreibst sind aber normale Variablen. Verbindungen von Namen zu Werten, die man im Laufe des Programms neu zuweisen kann. Wenn das nicht geht, dann heisst das nicht Variable sondern Konstante. *Das* hat Python *nicht*, sondern nur Variablen. Darum gibt es eine Namenskonvention für Konstanten: den Namen KOMPLETT_GROSS schreiben. Das ist zwar eine Variable, aber es sind sich alle einig, das man die nicht ändert, auch wenn man das könnte. Das ist der Unterschied zwischen Variablen, die man ändern kann, und Konstanten, die man nicht ändern ”kann”. Da letztlich alle Namen in Python in der Hinsicht aber gleich behandelt werden, ist die Frage was für Dich der Unterschied zwischen „Variablen“ und „normalen Variablen“ ist. Das macht keinen Sinn.
(Kleiner Einschub: Es ist gut, dass Du Batch-Programmierung erwähnt hast, denn jemand der von einer funktionalen Programmiersprache kommt, und nichts anderes kennt, könnte tatsächlich der Meinung sein, dass man einer Variablen nur genau einmal einen Wert zuweisen kann, und das später nicht ändern kann.)
Und im zweiten Absatz habe ich dann einfach mal geraten, dass Dein Problem nicht ist, dass Du einem Namen keinen Wert zuweisen kannst, sondern das der Name dem Du einen Wert zuweisen willst, nicht in dem Namensraum existiert wo Du das tun willst, also beispielsweise in einer Funktion einem Namen ausserhalb der Funktion etwas zuweisen, insbesondere auf Modulebene. Das geht nicht so einfach, und das ist auch gut so, denn das will man nicht. Solltest Du der Meinung sein das machen zu wollen: Nein das will man nicht.
Das was Du beschreibst, klingt nach:
Und das geht problemlos. Wenn das bei Dir nicht geht, musst Du schon etwas genauer werden was genau bei Dir nicht geht.
Python hat übrigens einen bedingten Ausdruck, so dass sich das ``if``/``else``-Konstrukt auch in *einer* Zuweisung formulieren lässt:
Falls der Status über mehrere Funktionen hinweg benötigt wird: Dafür gibt es Argumente und Rückgabewerte. So wie `is_nas_online()` das Ergebnis zurück gibt und nicht einfach irgendwo magisch an einem überall verfügbaren Namen bindet, und `print()` das was man ausgeben will, als Argument übergeben muss, und das nicht irgendeine magische global verfügbare ausgibt, macht man das auch in eigenen Funktionen.
Falls Du von Batch mit SETLOCAL/ENDLOCAL, und Wertrückgabe über Referenzen, oder noch schlimmer globale Variablen kommst, und die Abschnitte zu Funktionen im Tutorial in der Python-Dokumentation noch nicht durchgearbeitet hast, dann solltest Du das am besten jetzt mal machen, bevor Du weiter programmierst und versuchst Konzepte aus der Batch-Programmierung Python zu erwarten. Falls Dir gar SETLOCAL/ENDLOCAL nichts sagen, dann musst Du definitiv umdenken in Python.
(Kleiner Einschub: Es ist gut, dass Du Batch-Programmierung erwähnt hast, denn jemand der von einer funktionalen Programmiersprache kommt, und nichts anderes kennt, könnte tatsächlich der Meinung sein, dass man einer Variablen nur genau einmal einen Wert zuweisen kann, und das später nicht ändern kann.)
Und im zweiten Absatz habe ich dann einfach mal geraten, dass Dein Problem nicht ist, dass Du einem Namen keinen Wert zuweisen kannst, sondern das der Name dem Du einen Wert zuweisen willst, nicht in dem Namensraum existiert wo Du das tun willst, also beispielsweise in einer Funktion einem Namen ausserhalb der Funktion etwas zuweisen, insbesondere auf Modulebene. Das geht nicht so einfach, und das ist auch gut so, denn das will man nicht. Solltest Du der Meinung sein das machen zu wollen: Nein das will man nicht.
Das was Du beschreibst, klingt nach:
Code: Alles auswählen
status = "unbekannt"
print(status) # Gibt "unbekannt" aus.
if is_nas_online():
status = "online"
else:
status = "offline"
print(status) # Gibt je nach Status "online" oder "offline" aus.
Python hat übrigens einen bedingten Ausdruck, so dass sich das ``if``/``else``-Konstrukt auch in *einer* Zuweisung formulieren lässt:
Code: Alles auswählen
status = "unbekannt"
print(status) # Gibt "unbekannt" aus.
status = "online" if is_nas_online() else "offline"
print(status) # Gibt je nach Status "online" oder "offline" aus.
Falls Du von Batch mit SETLOCAL/ENDLOCAL, und Wertrückgabe über Referenzen, oder noch schlimmer globale Variablen kommst, und die Abschnitte zu Funktionen im Tutorial in der Python-Dokumentation noch nicht durchgearbeitet hast, dann solltest Du das am besten jetzt mal machen, bevor Du weiter programmierst und versuchst Konzepte aus der Batch-Programmierung Python zu erwarten. Falls Dir gar SETLOCAL/ENDLOCAL nichts sagen, dann musst Du definitiv umdenken in Python.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Ergänzend: Python kennt Boleans. Bevor du also "online" und "offline" als Zeichenkette verwendest, solltest du die auch verwenden.
Statt:
ginge daher auch (ohne den Status "unbekannt"):
Statt:
Code: Alles auswählen
status = "unbekannt"
print(status) # Gibt "unbekannt" aus.
if is_nas_online():
status = "online"
else:
status = "offline"
print(status) # Gibt je nach Status "online" oder "offline" aus.
Code: Alles auswählen
is_nas_online = check_is_nas_online()
- __blackjack__
- User
- Beiträge: 14076
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Vielleicht mal als Vergleich eine Batch-Version von dem Code aus meinem letzten Beitrag, also versucht nachzubauen was Python macht:
Batch hat halt nicht wirklich Funktionen, sondern eher benannte Code-Abschnitte die man mit CALL aufrufen kann. CALL ist eine Anweisung und kein Ausdruck, darum kann man nur einen Aufruf machen und muss sich das Ergebnis explizit in einer Variable merken um damit dann in den folgenden Anweisungen weiter arbeiten zu können.
Bei den benannten Code-Abschnitten in Batch-Skripten hat man die Option mit SETLOCAL und ENDLOCAL einen lokalen Namensraum zu erstellen. Das ist in Python nicht optional, sondern das passiert automatisch in jeder Funktion, das macht letztlich Funktionen ja auch aus, das sie eine in sich geschlossene Einheit sind wo man Werte als Argumente rein steckt, und Ergebnisse als Rückgabewerte bekommt, und was *in* der Funktion passiert, keinen Einfluss auf Namen ausserhalb der Funktion hat. Und *da* *vermute* ich Dein Problem. Python:
Verhält sich wie:
Und *nicht* wie:
Weil Python echte Funktionen hat. In Batch muss man sich die immer explizit selbst programmieren aus Sprungmarke, CALL, SETLOCAL, und ENDLOCAL. Die letzten drei sind ja auch erst sehr spät hinzugekommen. Unter DOS gab es das noch nicht, da gab es nur Sprungmarken und GOTO, und CALL war ausschliesslich zum Aufruf von anderen BAT-Dateien da, bevor das dann unter Windows' CMD.EXE zu einer Art GOSUB erweitert wurde und Sprungmarken als eine Art interner Batch-Skripte behandelt werden können.
Einen Rückgabewert muss man sich in Batch selber basteln, in dem man den Namen einer Ergebnisvariablen beim Aufruf übergibt und das Ergebnis davon nach dem ENDLOCAL setzt, damit das im Namensraum des Aufrufers passiert. Das funktioniert so wie ich das geschrieben habe, weil die Ersetzung von Variablen passiert bevor die Anweisungen ausgeführt werden. Darum kann das SET nach dem ENDLOCAL trotzdem noch auf die lokalen Variablen zugreifen, die vor dem ENDLOCAL existieren, nach dessen Ausführung aber nicht mehr.
Code: Alles auswählen
:main
setlocal
set status="unknown"
echo %status%
call :is_nas_online __result_a__
if %__result_a__% equ 0 (
set status="offline"
) else
set status="online"
)
echo %status%
endlocal
goto :eof
:is_nas_online
setlocal
set /a __return_value__=%random% %% 2
endlocal & set %~1=%__return_value__%
goto :eof
Bei den benannten Code-Abschnitten in Batch-Skripten hat man die Option mit SETLOCAL und ENDLOCAL einen lokalen Namensraum zu erstellen. Das ist in Python nicht optional, sondern das passiert automatisch in jeder Funktion, das macht letztlich Funktionen ja auch aus, das sie eine in sich geschlossene Einheit sind wo man Werte als Argumente rein steckt, und Ergebnisse als Rückgabewerte bekommt, und was *in* der Funktion passiert, keinen Einfluss auf Namen ausserhalb der Funktion hat. Und *da* *vermute* ich Dein Problem. Python:
Code: Alles auswählen
def some_function():
answer = 23
def main():
answer = 42
some_function()
print(answer) # Gibt 42 aus.
if __name__ == "__main__":
main()
Code: Alles auswählen
main:
set answer=42
call :some_function
:: Gibt 42 aus.
echo %answer%
goto :eof
:some_function
setlocal
set answer=23
endlocal
goto :eof
Code: Alles auswählen
main:
set answer=42
call :some_function
:: Gibt 23 aus.
echo %answer%
goto :eof
:some_function
set answer=23
goto :eof
Einen Rückgabewert muss man sich in Batch selber basteln, in dem man den Namen einer Ergebnisvariablen beim Aufruf übergibt und das Ergebnis davon nach dem ENDLOCAL setzt, damit das im Namensraum des Aufrufers passiert. Das funktioniert so wie ich das geschrieben habe, weil die Ersetzung von Variablen passiert bevor die Anweisungen ausgeführt werden. Darum kann das SET nach dem ENDLOCAL trotzdem noch auf die lokalen Variablen zugreifen, die vor dem ENDLOCAL existieren, nach dessen Ausführung aber nicht mehr.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari