Marakujaa
Anmeldungsdatum: 19. März 2023
Beiträge: 19
|
Hallo, Ich hab da mal ne frage;
Ab und an schreibe ich aus Spaß am Frust mal das ein oder andere sinnfreie Programm. Was genau, das tut jetzt erstmal weniger zur sache.. Nu bin ich heut mal auf was anderes gestoßen, eas irgendwie total aus der reihe fällt. Exception:
UnboundLocalError: referenced before assignment Nun, an sich nix besondere. Vergessen eine Variable zu belegen.. Das Denkste dir! 😲 Sowohl ist die betreffende Variable belegt als auch richtig geschrieben. Die betreffende Variable ist global verfügbar, weshalb die betreffende Funktion in der sie aufgerufen wird (wird später mehrfach in verschiedenen Funktionen, Klassen, externen Skripts die auf das Skript zugreifen genutzt. Wen das Programm erstmal soweit ist.) Ich hab die Variable via Copy&Paste da hin kopiert wo sie hin gehört und sicher gestellt, dass sie richtig belegt ist, was ich mir mit einem Testprint (nach ersten auftreten der Exception) hab bestätigen lassen. Soweit alles Korrekt! Doch akzeptiert Python (3.10.V063L31?) diese verdammte Variable nicht. Und {[seltsamerweise]}(!!) auch {[an dieser einen stelle nicht]}($@u3r31) ÜBERALL anders schon (hyääää?) Ich war schon fast ein Vogelei am Braten. Da hab ich sie aus Frust umbenannt uns es Funktionierte.. (Ja! war korrekt geschrieben) :dasLUSTIGEkopfkraftEMOJYvonDAMALSwelchesHIERfehltUNDichNICHTsuchenMÖCHTE: Um zum Kern zurück zu kommen; Was löst solch ein verhalten in Python aus? MFuLG PS: Und ähm, könnte mir mal bitte jemand diesen ForumEditor erklären! Ich bekomm diesen Text ums verrecken nicht richtig Formatiert.. Da braucht man ja bald eine Manpage 😀 Zweizeilen = eine Zeile, eine Zeile = ohne Zeile 3 Zeilen = mal keine Wirkung, mal 2 Zeilen, mal eine Zeile; ja wat denn jezze ~~
4-1899999999 Zeilen = eine Zeile; HÄÄÄÄ? und was macht das ding da! Da brat mir einer nen Esel oder den Bürgermeister von Wesel. *hatNUNaugenkrebs
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 28316
|
Hallo, anstatt dein Problem wortreich in etwas schlecht lesbarem Volltextprosa zu beschreiben wäre es deutlich sinnvoller, wenn du den relevanten Code sowie den vollen Stacktrace der Python Fehlermeldung hier posten würdest. Das Problem ist höchstwahrscheinlich, dass du einen Denkfehler im Gültigkeitsscope von Variablen in Python hast und / oder global falsch verwendest (wobei die Nutzung von global in Python in 99% der Fälle sowieso falsch ist, weil nicht nötig aka schlecht programmiert). Gruß, noisefloor
|
Marakujaa
(Themenstarter)
Anmeldungsdatum: 19. März 2023
Beiträge: 19
|
Guten Morgen, Das Problem hat sich durch umbenennen der Variable zwischenzeitlich behoben. Es geht viel mehr um follgende Situation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 | ## WICHTIGE INFO
# Beispielcode
class datenschreiber():
def check_exists(var): # Funktioniert
from os.path import exists
if exists(var):
return True
else:
return False
def write():
# Würde den Rahmen sprängen
# und hat nix mit dem Problem zu tun!
pass
def funktion1():
global beliebige_variable
beliebige_variable = '/home'
if datenschreiber.check_exists(beliebige_variable): # funktioniert
print(beliebige_variable) # funktioniert
# usw
# Wir gehen davon aus, dass alles True ist
# Im falle meines Programmes ist das so und kann keinesfalls anders sein!
# Unter gar keinen Umständen!
def funktion2():
# Beispielcode
# Wie der letzlich ausschaut ist egal, das Problem bleibt das gleiche
# vollkommen egal wie der code ausschaut!
print(beliebige_variable) # Exception!! = UnboundLocalError (local variable 'beliebige_variable' referenced before assignment)
# Kann bekannterweise ja nicht sein.. Wissen wir alle.
# Trat bei mir in meinem Programm allerdings GENAU SO auf.
# Warum?
def funktion3():
print(beliebige_variable) # funktioniert
funktion1()
funktion3() # gehört so
funktion2()
|
Kann ja eigentlich nicht sein, dass dies NICHT funktioniert..
Die frage ist also, wie kann es sein, dass es erst funktioniert und plöotzlich nicht mehr?
(bleibend) Benenne ich die Variable um, ist das Problem verschwunden.
Verwende ich hingegen den ursprünglichen namen ist das Problem wieder da. Das ist was ich meine..
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 28316
|
Hallo, die Klasse datenschreiber ist komplett falsch angelegt so. Da fehlt eigentlich alles inkl. der Verständnis, wie man Klassen in Python nutzt. Z.B. warum sind die Funktionen nicht über self. als Methoden der Klasse deklariert? Gibt es keine init Methode? Gibt es keine Attribute? Und die Klammern () hinter dem Klassennamen sind falsch. Im späteren Verlauf des Codes greifst du auch direkt auf die Klasse (die eigentlich keine ist) zu statt eine Instanz der Klasse anzulegen. Wie schon vermutet wird in deinem Code auch global falsch verwendet, im Sinne von das es überhaupt verwendet wird ist hier falsch. Dann passiert nämlich genau das, was dir passiert: der Zustand des Programms ist schwer bis nicht mehr nachvollziehbar. Funktionen kann man Argumente übergeben und Funktionen können Werte zurück geben. Das ist der bessere / richtige Weg, nicht ein globaler Scope einer Variablen. Wenn mehrere Funktionen das brauchen kann man sich auch in eine Klasse packen und den benötigen Wert als Attribut der Klasse ablegen. os.path ist übrigens veraltet, Stand der Dinge ist das pathlib Modul.
Gruß, noisefloor
|
Marakujaa
(Themenstarter)
Anmeldungsdatum: 19. März 2023
Beiträge: 19
|
Der datenschreiber wie ich ihn bisher nutze.
Bereitet keine weiteren Probleme.. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175 | class dw: # Funktioniert so
# Jup, ist mir klar.. Klassen sind aktuell so ein Thema bei mir.
# Derzeit noch am Lernen.
def init(): # Beim Programstart anwählen damit die VARs eingelesen werden.
global a, ab, an, w, wb, r, rb # zur externen verwendung ala dw.write('/pfad/zur.datei', an, 'String, int oder Binär'). Vereinfacht.
global ok_R, ok_W, ok_X, ok_RW, ok_RWX, exist, filedir, FILE, DIR # ebenso
## Funktionen
# Schreiben
a = 'a' # Erweitern : Normal
ab = 'ab' # Erweitern : Binär
an = 'append_newline' # Erweitern : Neue Zeile
w = 'w' # Schreiben : Normal
wb = 'wb' # Schreiben : Binär
# Lesen
r = 'r' # Lesen : Normal
rb = 'rb' # Lesen : Binär
# Checks
ok_R = 'ok_R'
ok_W = 'ok_W'
ok_X = 'ok_X'
ok_RW = 'ok_RW'
ok_RWX = 'OK_RWX'
exist = 'exists'
filedir = 'filedir'
# Funktion und Ausgabe/Rückgabe
FILE = 'FILE'
DIR = 'DIR'
dw_nowarning = False
return 'AKTIV'
def check(pfad, io):
from os import access, R_OK, W_OK, X_OK
from os.path import exists, isfile, isdir, dirname
try:
# Rechteprüfung
if ((io == ok_R or ok_W == io) or (io == ok_X or ok_RW == io)) or io == ok_RWX:
if not exists(pfad):
raise FileNotFoundError
else:
if io == ok_R:
io = access(pfad, R_OK)
elif io == ok_W:
io = access(pfad, W_OK)
elif io == ok_X:
io = access(pfad, X_OK)
elif io == ok_RW:
io = access(pfad, R_OK | W_OK)
elif io == ok_RWX:
io = access(pfad, R_OK | W_OK | X_OK)
else:
raise RuntimeError
# Ordner oder Datei
elif (io == FILE or DIR == io) or io == filedir:
if io == filedir:
if isfile(pfad):
io = FILE
elif isdir(pfad):
io = DIR
else:
raise RuntimeError
elif FILE:
io = isfile(pfad)
elif DIR:
io = isdir(pfad)
else:
raise RuntimeError
# Existiert?
elif io == exist:
io = exists(pfad)
else:
raise ValueError
except RuntimeError as excep:
print('dw.check(XXXX, XXXX)\nKritical error in python3! Programm ends here!'); exit()
except ValueError as excep:
print('dw.check(XXXX, io)\nUnsupport Value in "io" for checking files: ' + io + '\nCorrect values are: "ok_R", "ok_W", "ok_X", "ok_RW", "ok_RWX"\n')
except FileNotFoundError as excep:
print('dw.check(pfad, XXXX)\nNo such file or directory\n' + pfad + '\n')
else:
return io
return False
def makedir(pfad):
from os import mkdir
try:
mkdir(pfad)
except (FileExistsError, PermissionError) as excep:
print('dw.makedir(pfad)\n' + pfad + '\n' + excep.args[1] + '\n'); return False
else:
return True
def write(pfad, io, data):
from os.path import exists
# Bei misserfolg: Immer return False, letzer eintrag.
try: # Hauptoperation
if (io == r) or (io == rb): # Falsche Funktion
raise ValueError
elif ((io == w or wb == io) or (io == a or ab == io)) or (io == an): # Richtige Funktion
try: # Für ausgabe der internen Warnung
if (io == an) and (not exists(pfad)):
raise UserWarning('\nNew line, at the beginning, is removed.\n')
elif (io == a) and (not exists(pfad)):
raise UserWarning('\n')
elif (io == an) and exists(pfad):
io = a; data = '\n' + data
except UserWarning as excep:
if not dw_nowarning:
print('dw.write(XXXX, io)\nNo such file or directory\nI set write mode to "write" instead "append".' + excep.args[0] + pfad + '\n')
io = a
pfad = open(pfad, io)
io = pfad.write(data)
pfad.close()
else:
raise ValueError
# Bei Fehlern:
except (FileNotFoundError, IsADirectoryError, PermissionError) as excep:
print('dw.write(pfad, XXXX)\n' + pfad + '\n' + excep.args[1] + '\n')
except TypeError as excep:
print('dw.write', end='')
try: # Mehrfach Umwandlung
try: # Normal
print('(pfad, XXxx)\n' + pfad.name + '\n' + excep.args[0] + '\n')
except: # Umwandlung für die Funktion AN
raise TypeError(excep)
except: # Umgewandelt
try:
# Fehler für die Funktion AN
print('(pfad, XXXX)\n' + pfad + '\n' + excep.args[0] + '\n')
except TypeError: # Fehler, wenn kein Pfad angegeben ist.
print('(pfad, xxXX)\nNo path specified!\n')
except ValueError as excep:
print('dw.write(XXXX, io)\nUnsupport Value in "io" for writing files:', io + '\nCorrect values are: "w", "wb, "a", "ab"\n')
else: # Bei erfolg: return True
return True
return False
def read(pfad, io):
# Bei misserfolg: Immer Return False, letzer eintrag.
try: # Hauptoperation
if ((io == w or wb == io) or (io == a or ab == io)) or (io == an): # Falsche Funktion
raise ValueError
elif (io == r) or (io == rb): # Richtige Funktion
pfad = open(pfad, io)
io = pfad.read()
pfad.close()
else:
raise ValueError
# Bei Fehlern:
except (FileNotFoundError, IsADirectoryError, PermissionError) as excep:
print('dw.read(pfad, XXXX)\n' + pfad + '\n' + excep.args[1] + '\n')
except ValueError as excep:
print('dw.read(XXXX, io)\nUnsupport Value in "io" for reading files:\n' + io + '\nCorrect values are: r, rb\n')
else: # Bei Erfolg: Rückgabe mit gelesenem wert.
return io
return False
def delete(pfad):
from os.path import isfile, isdir
from os import remove, rmdir
try:
if isfile(pfad):
remove(pfad)
elif isdir(pfad):
rmdir(pfad)
else:
raise FileExistsError
except (FileExistsError, PermissionError) as excep:
print('dw.delete(pfad)\n' + pfad + '\n' + excep.args[1] + '\n')
else:
return True
return False
|
Was das mein eigentliches Problem betriff;
Die Klasse in der das Problem auftrat (hier nicht aufgeführt) war nicht korrekt geschrieben..
Zwischenzeitlich funktioniert es. Anbei;
Die Programme die ich schreibe sind für den eigenen gebrauch..
Es ist nicht geplant diese zu veröffentlichen.. Meißt gehts da nur um kleinere dinge, wie beispielsweise eine Konfigurationsdatei fortlaufen anzupassen, sofern eine änderung auftriff.
Thunar und größenänderungen sind so so ein fall.
Jenachdem wie ich den rechner benutze hab ich dan laufend eine andere Größe. Beende ich Thunar wird die größe der letzten Thunar Instanz in einer Konfigurationsdatei gespeichert.
Die kleinen Skripte die ich geschrieben habe sorgend also z.B. dafür, dass die größe beim nächsten start einer Thunar Instanz wieder eine voreingestellte größe entspricht. Das Programm in dem dieser Datenschreiber eingesetzt wird verwendet dafür eine zusammenstellung von verschiedenen Skripten die durch einen Hauptprozess verwaltet und ausgeführt werden. So wird der Datenschreiber nur ein mal benötigt und alle weiteren Skripte greifen auf diesen Periodisch zu (sofern erforderlich). Wie und wann das geschieht entscheidet das Hauptprogramm, ohne dabei Threads zu nutzen.
Die jeweiligen Module werden dazu nacheinander in einer fest voreingestellten reihenfolge ausgeführt.
Sind jetzt nicht gerade skripte die viel Rechenleistung benötigen und währe sicherlich auch mit einem Shellskript zu realisieren. Allerdings möchte ich die gelegenheit nutzen mich etwas mit Python vertraut zu machen..
Auch da das Programm fortlaufend von mir erweitert wird..
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 28316
|
Hallo, die Klasse ist genau so falsch - das ist keine richtige Klasse. Und das global in der init Funktion ist katastrophal falsch. Und das ist noch viel mehr falsch, z.B. das Importe an den Anfang einer Datei gehören. Und keine nackten try... except verwenden. Bevor du daran noch irgendwas weiter programmierst solltest du dringend zwei Schritte zurück gehen, dir nochmal den Abschnitt zu Klassen im Grundlagentutorial von Python durchlesen und durcharbeiten. Und wenn du das dann verstanden hast den Code neu schreiben. Ist auch nichts schlimmes, gehört zum Lernen dazu. Und dann direkt den Rest auch besser machen, wie das pathlib Modul statt os.path benutzen. Den aktueller Code ist eine Sackgasse, selbst wenn du das Programm rein für die alleine benutzt. Gruß, noisefloor
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17432
|
| class datenschreiber():
def check_exists(var): # Funktioniert
from os.path import exists
if exists(var):
return True
else:
return False
|
Ich kann ja kein Python, aber wenn das Umbenennen der Variablen den Code heilt, dann ist der 1. Verdacht, dass unzulässige Zeichen im Namen sind - danach sieht es bei var nicht aus - und der 2. Verdacht ist, dass der Name ein reserviertes Schlüsselwort ist. Vielleicht kannst Du den 2. Verdacht prüfen. Übrigens kann man den Code wahrscheinlich verkürzen zu: | class datenschreiber():
def check_exists (var1): # Funktioniert
from os.path import exists
return exists (var1)
|
Als Nichtpythoniker bin ich da aber nicht sicher. ☺
|
Marakujaa
(Themenstarter)
Anmeldungsdatum: 19. März 2023
Beiträge: 19
|
Also.. Ich hab mich jetzt nochmal etwas in die Klassen eingelesen und den Datenschreiber mit ein wenig herumprobieren etwas umgeschrieben. 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184 | class datenschreiber:
def __init__(self):
while True:
try:
if globals_dw == 'AKTIV':
break
else:
raise NameError
except NameError:
self.__globals_init_dw()
def __globals_init_dw(self):
global a, ab, an, w, wb, r, rb
global ok_R, ok_W, ok_X, ok_RW, ok_RWX, exist, filedir, FILE, DIR
global nowarning_dw, globals_dw
## Funktionen
# Schreiben
a = 'a' # Erweitern : Normal
ab = 'ab' # Erweitern : Binär
an = 'append_newline' # Erweitern : Neue Zeile
w = 'w' # Schreiben : Normal
wb = 'wb' # Schreiben : Binär
# Lesen
r = 'r' # Lesen : Normal
rb = 'rb' # Lesen : Binär
# Checks (Nur Prüfen)
ok_R = 'ok_R' # Leserechte
ok_W = 'ok_W' # Schreibrechte
ok_X = 'ok_X' # Ausführen
ok_RW = 'ok_RW' # Lese-/Schreibrechte
ok_RWX = 'ok_RWX' # Alle Rechte
exist = 'exists' # Selbsterklären...
filedir = 'filedir'
# Funktion und Ausgabe/Rückgabe
FILE = 'FILE'
DIR = 'DIR'
## Konfiguration
nowarning_dw = False # Standartmäßig Aktiv (False ist Aktiv!)
## Für init
globals_dw = 'AKTIV'
return
# Exceptions Ausgaben kann man mit 'nowarning_dw = True/False ab/an stellen. (Terminal)
def __internal_exception_dw(self, name, excep, data):
if nowarning_dw:
return
else:
print('FEHLER:\n' + 'dw.' + name + '\n' + excep + '\n' + data + '\n')
return
# Prüft einen beliebigen Pfad.
def check(self, pfad, io):
from os import access, R_OK, W_OK, X_OK
from os.path import exists, isfile, isdir, dirname
try:
# Rechteprüfung auf Datei/Ordner auf div. Zugriffsrechte
if ((io == ok_R or ok_W == io) or (io == ok_X or ok_RW == io)) or io == ok_RWX:
if not exists(pfad):
raise FileNotFoundError
else:
if io == ok_R:
io = access(pfad, R_OK)
elif io == ok_W:
io = access(pfad, W_OK)
elif io == ok_X:
io = access(pfad, X_OK)
elif io == ok_RW:
io = access(pfad, R_OK | W_OK)
elif io == ok_RWX:
io = access(pfad, R_OK | W_OK | X_OK)
else:
raise RuntimeError
# ist es eine Datei/Ordner (True/False oder FILE/DIR, was man braucht.)
elif (io == FILE or DIR == io) or io == filedir:
if io == filedir:
if isfile(pfad):
io = FILE
elif isdir(pfad):
io = DIR
else:
raise RuntimeError
elif FILE:
io = isfile(pfad)
elif DIR:
io = isdir(pfad)
else:
raise RuntimeError
# Existiert der Pfad überhaupt? (True/False)
elif io == exist:
io = exists(pfad)
# Unbekannte Funktion. Gibt einen Fehler aus. :D
else:
raise ValueError
except FileNotFoundError as excep:
self.__internal_exception_dw('check(pfad, io)', excep.args[1], pfad)
except ValueError as excep:
self.__internal_exception_dw('check(pfad, io)', 'Value Error', 'MODE: ' + io)
except RuntimeError as excep:
self.__internal_exception_dw('check(pfad, io)', 'Runtime Error', pfad); exit()
else:
return io
return False
# Ordner erstellen
def makedir(self, pfad):
from os import mkdir
try:
mkdir(pfad)
except (FileExistsError, PermissionError) as excep:
self.__internal_exception_dw('makedir(pfad)' ,excep.args[1], pfad)
else:
return True
return False
# Dateien Schreiben
def write(self, pfad, io, data):
from os.path import exists
try:
if (io == r) or (io == rb): # Falsche Funktion
raise ValueError
elif ((io == w or wb == io) or (io == a or ab == io)) or (io == an): # Richtige Funktion
if ((io == an) or (a == io)) and (not exists(pfad)): ## Für ((appena_newline) oder (append)) und (File existiert NICHT)
io = a
elif (io == an) and exists(pfad): # für append wen file existiert
io = a; data = '\n' + data
datei = open(pfad, io)
datei.write(data)
datei.close()
else:
raise ValueError
except (FileNotFoundError, IsADirectoryError, PermissionError) as excep:
self.__internal_exception_dw('write(pfad, io, data)', excep.args[1], pfad)
except TypeError as excep:
self.__internal_exception_dw('write(pfad, io, data)', excep.args[0], 'MODE: ' + io + '\n' + pfad)
except ValueError:
self.__internal_exception_dw('write(pfad, io, data)', 'Value Error', 'MODE: ' + io)
else:
return True
return False
# Dateien Lesen
def read(self, pfad, io):
try:
if ((io == w or wb == io) or (io == a or ab == io)) or (io == an): # Falsche Funktion
raise ValueError
elif (io == r) or (io == rb): # Richtige Funktion
pfad = open(pfad, io)
io = pfad.read()
pfad.close()
else:
raise ValueError
except (FileNotFoundError, IsADirectoryError, PermissionError) as excep:
self.__internal_exception_dw('read(pfad, io)', excep.args[1], pfad)
except ValueError as excep:
self.__internal_exception_dw('read(pfad, io)', excep.args[1], pfad))
else:
return io
return False
# Datei/Ordner Löschen (Wählt automatisch, anhand des Pfades)
def delete(self, pfad):
from os.path import isfile, isdir
from os import remove, rmdir
try:
if isfile(pfad):
remove(pfad)
elif isdir(pfad):
rmdir(pfad)
else:
raise FileExistsError
except (FileExistsError, PermissionError) as excep:
self.__internal_exception_dw('delete(pfad)', excep.args[1], pfad))
else:
return True
return False
datenschreiber() # Initzeile 1
dw = datenschreiber() # Initzeile 2
|
@user_unknown
Den Code den Du da von mir hast war ein Beispielcode.
Der eigentliche Datenschreiber (neu) ist dieses (Vergleichsweise) Monster hier im Codeblock.
Da ist die verkürzung mit drin. Der fehler auf den ich da zuletzt gestoßen bin, entstand nicht im Datenschreiber.
Es ging um eine Variable die an einer anderen stelle im Code durch eine Funktion vordefiniert war, als Global festgelegt war (da sie an verschiedenen stellen im Skript verwendet werden sollte. Das übergeb der betreffenden Variable ließ sich zu jener zeit nicht anders verwirklichen, da ich die Klassen in Python teilweise bzw ganz falsch verwendet habe). Übung macht den Meister..
Ich bin kein Meister, also muss ich durch Hinfallen und wieder Aufstehen Lernen wie es fnuktioniert.
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 28316
|
Hallo, das ist immer noch furchtbar falsch. globals_dw muss an der Stelle doch zu einem NameError führen, weil es dort nicht definiert sein kann, jedenfalls nicht zu dem Zeitpunkt. Und global in einer Klasse verwenden ist in 99,99% der Fälle falsch, so auch hier. Das möchtest du alles zu Attributen der Klasse mache. Zeile 183 im letzten Post ist sinnlos, weil die erzeugte Instanz an nichts gebunden wird, d.h. die ist direkt wieder weg. Methodennamen mit zwei Unterstrichen __ beginnen zu lassen ist nicht nötig, weil du ziemlich sicher keine Namenskonflikte hast. Die Importe stehen immer noch an der falschen Stelle. Eingerückt wird bei Python per Konvention mit 4 Leerzeichen, nicht mit 8. Gruß, noiseflor
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17432
|
Marakujaa schrieb: @user_unknown
Den Code den Du da von mir hast war ein Beispielcode.
Tja.
Eine gute Idee ist es, den Code, der nicht funktioniert, so radikal einzukürzen, dass nur das absolut notwendige Minimum noch drin ist, um den Fehler zu reproduzieren, aber eben genug, dass man sich das in die REPL oder den Editor kopieren kann, und bei sich den Fehler reproduziert. Reproduziert man den Fehler nicht liegt es wohl an eingebetteten Bibliotheken, unterschiedlichen Versionen oder dem Aufruf des Programms. Sehr oft findet man auf die Weise seinen Fehler selbst, denn man kürzt Dinge weg, die für den Fehler nicht bedeutsam sind - denkt man - und dann ist der Fehler plötzlich weg und man stellt fest, dass die Annahme, was gesichert ist, falsch war. Oder man kann den Fehler stärker eingrenzen als ursprünglich gedacht und lernt dabei etwas wichtiges, um ihn zu beseitigen.
|
Marakujaa
(Themenstarter)
Anmeldungsdatum: 19. März 2023
Beiträge: 19
|
noisefloor Schrieb:
Eingerückt wird bei Python per Konvention mit 4 Leerzeichen, nicht mit 8.
Das liegt hier am Codeblock der Tabs mit 8 anstatt 4 Zeilen einrückt. Ich hab den Code so wie er da steht aus dem Editor eingefügt. Also ein Problem des Forum-Editors! –- –- –- –- –-
noisefloor Meinte:
globals_dw muss an der Stelle doch zu einem NameError führen
Tut es auch. Die Exception wird abgefangen, was dann __globals_init_dw aufruft um die globalen Variablen zu laden und es anschließend erneut zu versuchen, was dann auch funktioniert. –- –- –- –- –-
noisefloor Ermahnte:
Zeile 183 im letzten Post ist sinnlos, weil die erzeugte Instanz an nichts gebunden wird, d.h. die ist direkt wieder weg.
Zeile 183 ist tatsächlich überflüssig. Seltsamerweise hat es zuletzt ohne diese nicht funktioniert, was verwirrend ist. –- –- –- –- –-
noisefloor Fragte(???):
Das möchtest du alles zu Attributen der Klasse mache.
Was für Attribute?
'_datenschreiber__globals_init_dw'
'_datenschreiber__internal_exception_dw'
'check'
'delete'
'makedir'
'read'
'write'
und
'__class__'
'__delattr__'
'__dict__'
'__dir__'
'__doc__'
'__eq__'
'__format__'
'__ge__'
'__getattribute__'
'__gt__'
'__hash__'
'__init__'
'__init_subclass__'
'__le__'
'__lt__'
'__module__'
'__ne__'
'__new__'
'__reduce__'
'__reduce_ex__'
'__repr__'
'__setattr__'
'__sizeof__'
'__str__'
'__subclasshook__'
'__weakref__'
oder was genau meinst du? –- –- –- –- –-
noisefloor Wies darauf hin:
Methodennamen mit zwei Unterstrichen __ beginnen zu lassen ist nicht nötig, weil du ziemlich sicher keine Namenskonflikte hast.
Das ist richtig. Damit möchte ich bewirken, dass diese Methoden des Datenschreibers (vorerst) extern nicht aufrufbar sind. –- –- –- –- –- EDIT: Vernünftig Formatiert, überflüssiges entfernt. Generell etwas überarbeitet. Augenkrebs muss nicht sein.
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 28316
|
Hallo,
Also ein Problem des Forum-Editors!
Nope, weil eingerückt wird per Konvention mit 4 Leerzeichen, nicht mit Tabs. Funktioniert zwar, gilt aber als schlechter Stil. Du solltest deinen Editor so einstellen, dass beim Schreiben von Python-Code beim Druck auf die Tab-Taste vier Leerzeichen eingefügt werden.
Was für Attribute?
Wenn du das (noch) nicht weißt: drei Schritte zurück und den Abschnitt zu Klassen im offiziellen Python-Tutorial durcharbeiten. Du kannst keine Klasse schreiben, ohne verstanden zu haben, was Attribute und Methoden einer Klasse sind. Das sind absolute Grundlagen dafür. Link 🇬🇧
Tut es auch. Die Exception wird abgefangen, was dann __globals_init_dw aufruft um die globalen Variablen zu laden und es anschließend erneut zu versuchen, was dann auch funktioniert.
Mal abgesehen davon, dass der Code so sowieso falsch ist: dann solltest du dir vielleicht mal Gedanken über die Logik deines Programmflusses machen und das ganze umdrehen?
Das ist richtig. Damit möchte ich bewirken, dass diese Methoden des Datenschreibers (vorerst) extern nicht aufrufbar sind.
Verständnisfehler deinerseits: es gibt in Python keine privaten Attribute oder Methoden. _Alles_ ist von extern aufrufbar, egal ob ohne, mit einem oder mit zwei führenden Unterstrichen. Bei zwei führenden Unterstrichen ändert sich nur das "wie" das Aufrufs. Gruß, noisefloor
|
Marakujaa
(Themenstarter)
Anmeldungsdatum: 19. März 2023
Beiträge: 19
|
Nope, weil eingerückt wird per Konvention mit 4 Leerzeichen, nicht mit Tabs. Funktioniert zwar, gilt aber als schlechter Stil.
Du solltest deinen Editor so einstellen, dass beim Schreiben von Python-Code beim Druck auf die Tab-Taste vier Leerzeichen eingefügt werden.
Ob schlechter Stil hin oder her.. Mit leerzeichen bekomme ich durchgehend Probleme mit der Einrückung und andauernd teilweise hunderte zeilen neu einzurücken, hab ich ganz schlicht und ergreifend keine lust mehr drauf. Frag nicht wie ich das schaffe, ich weiß es selbst nicht.
Wenn du das (noch) nicht weißt: drei Schritte zurück und den Abschnitt zu Klassen im offiziellen Python-Tutorial durcharbeiten.
Du kannst keine Klasse schreiben, ohne verstanden zu haben, was Attribute und Methoden einer Klasse sind. Das sind absolute Grundlagen dafür. Link 🇬🇧
Was ist denn daran Falsch?
Dies sind Variablen, welche global gesetzt werden, damit sie global überhaupt erstmal auffindbar sind oder denkst Du diese Variablen werden ausschließlich nur im Datenschreiber verwendet. Falls ja, dann irrst Du dich. Damit:
| dw.write('/ein/beliebiger/pfad', wb, b'beliebige Daten')
|
Funtioniert müssen diese Variablen auch global verfügbar sein. Andernfals erhalte ich einen Traceback. | class test:
def vars(self):
test1 = 'test'
t = test()
print(test1)
|
| Traceback (most recent call last):
File "//home/marakujaa/python/tests/test6.py", line 9, in <module>
print(test1)
NameError: name 'test1' is not defined. Did you mean: 'test'?
|
Im grunde ist es egal wie Du versuchst 'test1' aufzurufen, es führt jedesmal zu einem NameError oder einem ArtibutError.
Es gibt derzeit zwei mir bekannte möglichkeiten das Problem zu lösen; 1.)
| test1 = 'test1'
class test:
def prints(self):
print(test1)
t = test(); t.prints()
|
## Ausgabe entspricht:
test1
test2
oder
2.)
| class test:
def vars(self):
global test1
test1 = 'test'
t = test()
print(test1)
|
Möchte ich nun test1 noch in der klasse/funktion verändern und die veränderung soll global verfügbar sein, da der darin enthaltene Wert von der klasse selbst oder einer anderen funktion zu einem späteren Zeitpunkt verwendet wird, muss ich das ganze entweder so; | test1 = 'test1'
class test:
def vars(wert):
global test1
test1 = wert
def prints(self):
print(test1)
t = test(); t.prints(); t.vars('test2'); t.prints()
|
oder so; | class test:
def vars(self, wert):
global test1
test1 = wert
t = test()
print(test1)
t.vars('test2')
|
schreiben. Andernfalls ist der wert nähmlich entweder weg oder nicht verfügbar. Global wird hier also verwendet um die Variable 'test1' global verfügbar zu machen. Nicht wirklich anders verhält es sich mit dem Datenschreiber. Global wird hier dazu genutzt um die variablen des datenschreibers wie z.B. 'a', 'ab', 'w', 'wb', usw, dem globalen Namensraum zuzuweisen um sicher zu stellen, dass diese Variablen auch gloabl und nicht 'nur' im Datenschreiber verfügbar sind. | dw.write('/pfad/zur.datei', wb, b'Das sind die daten.')
# Darum gehts: ^^
|
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 12527
|
Marakujaa schrieb:
Mit leerzeichen bekomme ich durchgehend Probleme mit der Einrückung und andauernd teilweise hunderte zeilen neu einzurücken, hab ich ganz schlicht und ergreifend keine lust mehr drauf. Frag nicht wie ich das schaffe, ich weiß es selbst nicht.
Es gibt Programme, die die passende Einrückung automatisch erzeugen. Ansonsten sollten das alle modernen Editoren und selbst vim hinbekommen. Edit: hatte das Zitat vergessen.
|
noisefloor
Ehemaliger
Anmeldungsdatum: 6. Juni 2006
Beiträge: 28316
|
Hallo, du scheiterst programmiertechnisch gerade krass an der selber, weil du dich auf nichts einlässt und unbedingt das umsetzen willst, wie _du_ es für richtig hältst. Oder anders: du programmierst gegen die Sprache, weil du die Grundkonzepte schlicht nicht akzeptierst bzw. lernen willst. Kann man machen, geht aber selbst mittelfristig nicht gut. Darum hast du auch Probleme, siehe Ausgangspost. Gruß, noisefloor
|