Python - Warum ist diese Klasse variable nicht definiert in der Methode?
Habe ich ein python-Anwendung, die ist wie folgt:
global_counter = 0
connections = {}
class SocketHandler():
currentid = 0
def open(self):
global global_counter
global connections
currentid = global_counter
global_counter += 1
connections[currentid] = self
print "WebSocket " + str(currentid) + " opened"
def on_close(self):
global connections
print "WebSocket " + str(currentid) + " closed"
del connections[currentid]
Ich bin immer der Fehler:
NameError: global name 'currentid' is not defined
auf den Linien von "öffnen" und "on_close", wo ich den Druck, den ich öffnen/schließen der Verbindung. Ich definierte es in der Klasse, warum ist es nicht in den Anwendungsbereich. Auch habe ich gelesen, dass die Verwendung von globalen Variablen ist schlecht, aber ich sehe nicht, einen Weg, um dieses. Kann mir jemand erklären, was ich tun soll? Danke.
Verwenden Sie selbst.currentid
InformationsquelleAutor Lylax | 2012-10-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
Du nicht haben, die impliziten Zugriff auf Attribute innerhalb Methoden in Python.
Einen bloßen Namen wie
currentid
in der Zeile:immer sucht Sie einen Namen in der lokalen Funktions-Bereich, dann in jedem umschließenden Funktions-scope, bevor Sie versuchen, die globalen Modul-Umfang (und dann sieht built-ins als letzten Ausweg).
currentid
ist ein class-Attribut, die nicht gefunden werden in jedem der genannten Bereiche.Nachschlagen ein Attribut in Python geben, die Sie immer muss ein Objekt angeben, in dem zu sehen. Wenn das lookup-Protokoll bedeutet, das Objekt muss nicht unbedingt das Attribut selbst; Attribut-lookup wird wieder die Klasse des Objekts, das Sie angegeben haben (und die base-Klassen, wenn die Vererbung beteiligt ist).
Damit das funktionieren würde:
Aber ich glaube nicht, dass der rest Ihres Codes zu tun, was Sie denken, es ist entweder. Diese Zeile in der
open
Methode:nicht die
currentid
Attribut desSocketHandler
Objekt. Die Zuordnung zu einem bloßen Namen immer weist auf eine lokale variable, es sei denn, Sie explizit zu deklarieren, esglobal
(Sie scheinen sich dessen bewusst zu sein, da hast du verwendet, dieglobal
Stichwort). So in deropen
Methodecurrentid
ist eine lokale variable, Funktion; der Wert ist, verlor am Ende dieopen
Methode.In der Tat, Ihre
SocketHandler
- Objekte haben keinecurrentid
Attribut überhaupt (es sei denn, es gibt noch mehr code, den Sie haben nicht gezeigt). Setzencurrentid = 0
im class-block nicht geben, dieSocketHandler
Instanzen einecurrentid
Attribut. Es gibt dieSocketHandler
Klasse sich ein Attributcurrentid
; dieser ist ebenso wie derdef open(self):
block erstellt eineopen
Attribut (Speicherung einer Funktion) auf das class-Objekt, nicht auf jeder einzelnen Instanz.Lesen
self.currentid
imon_close
Methode nicht zu finden, eincurrentid
Attribut im Objektself
, so Python wird der Blick auf die Klasseself
dieSocketHandler
. Das Objekt hat haben einecurrentid
Wert, so das Ergebnis des Lesensself.currentid
wird0
, ob oder nicht, Sie haben zuvor ausgeführtopen
auf, dassSocketHandler
.Wenn Sie bedeutete, zu speichern, die
currentid
als Instanz-variable in jedemSocketHandler
, dann die Zeile inopen
werden müssten:Dies weist auf die
currentid
Attribut des Objekts bezeichnetself
. Sie würde auch dann müssen alle Verweise aufcurrentid
in Ihre Methoden, umself.currentid
.InformationsquelleAutor Ben
currentid
sollteself.currentid
da es sich um eine Klassenvariable.Warum ist dies, dass viel von Ihnen positiv bewertet werden? - den code in die exampe oben brechen nun nicht mehr mit Fehler, aber brechen mit einer schweren logischen Fehler, wenn nur diese Ersetzung wird gemacht.
Was meinst du? Die einzigen anderen Variablen, die geändert wird, sind die globals.
Für wie wahrscheinlich hältst du es, dass die OP soll eine lokale variable mit dem gleichen Namen wie die Klasse, Attribut in der
open
Methode? Und dieon_close
Methode immerdel connections[0]
?Sorry, ich lese jsbueno Kommentar zu sagen, dass es ein parsing-Fehler im Skript, nicht zu einem Laufzeitfehler.
InformationsquelleAutor ronak
currentid
ist das Instanz-Attribut verwenden, soself.currentid
stattcurrentid
:InformationsquelleAutor defuz