Python-почему эта переменная класса не определена в методе?
у меня есть приложение python, которое выглядит следующим образом:
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]
Я получаю ошибку:
NameError: global name 'currentid' is not defined
в строках "открыть" и "on_close", где я печатаю, что я открываю/закрываю соединение. Я определил его в классе, почему он не в рамках. Кроме того, я читал, что использование глобальных переменных плохо, но я не вижу способа обойти это. Кто-нибудь может указать, что мне делать? Спасибо.
3 ответов
у вас нет неявного доступа к атрибутам внутри методов в Python.
голое имя, как currentid в строку:
del connections[currentid]
всегда ищет имя в локальной области функций, затем в каждой области функций, прежде чем пытаться использовать глобальную область модуля (а затем смотрит на встроенные модули в качестве последнего средства). currentid - это атрибут класса, который не будет найден ни в одной из этих областей.
чтобы найти атрибут в Python, вы всегда необходимо указать объект, в котором нужно искать. Хотя протокол поиска означает, что объект не обязательно должен иметь сам атрибут; поиск атрибута будет возвращаться к классу указанного вами объекта (и базовым классам, если задействовано наследование).
так что это сработает:
del connections[self.currentid]
однако я не думаю, что остальная часть вашего кода делает то, что вы думаете. Эта строка в open метод:
currentid = global_counter
нет  вашего . Это дает SocketHandler класс  атрибут currentid; это так же, как def open(self): блок создает open атрибут (хранение функции) на объекте класса, а не на каждом отдельном экземпляре.
чтение self.currentid на on_close метод не сможет найти currentid атрибут в объекте self, так Python будет смотреть на класс self что это SocketHandler. Этот объект!--56-->тут есть currentid значение, поэтому результат чтения self.currentid будет 0, независимо от того, выполняли ли вы ранее open на SocketHandler.
если вы намеревались хранить currentid как переменная экземпляра в каждом SocketHandler, то в строке open должно быть:
self.currentid = global_counter
это присваивает currentid атрибут объекта, на который ссылается self. Вы бы также необходимо изменить все остальные ссылки на currentid в ваших методах self.currentid.
currentid является атрибутом экземпляра, поэтому используйте self.currentid вместо currentid:
def on_close(self):
        global connections
        print "WebSocket " + str(self.currentid) + " closed"
        del connections[self.currentid]
