Python-为什么在方法中没有定义这个类变量?
我有一个python应用程序,如下所示:Python-为什么在方法中没有定义这个类变量?,python,variables,scope,Python,Variables,Scope,我有一个python应用程序,如下所示: global_counter = 0 connections = {} class SocketHandler(): currentid = 0 def open(self): global global_counter global connections currentid = global_counter global_counter += 1 con
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
在我打印的“打开”和“打开/关闭”行中,我正在打开/关闭连接。我在类中定义了它,为什么它不在范围中。另外,我读到过使用全局变量是不好的,但我看不到解决这个问题的方法。有人能指出我该做什么吗?谢谢。
currentid
应该是self.currentid
,因为它是一个类变量。currentid
应该是self.currentid
,因为它是一个类变量。currentid
是实例属性,所以使用self.currentid
,而不是currentid
:
def on_close(self):
global connections
print "WebSocket " + str(self.currentid) + " closed"
del connections[self.currentid]
currentid
是实例属性,因此使用self.currentid
而不是currentid
:
def on_close(self):
global connections
print "WebSocket " + str(self.currentid) + " closed"
del connections[self.currentid]
在Python中,您没有对方法内部属性的隐式访问权 行中的一个简单名称,如
currentid
:
del connections[currentid]
在尝试全局模块作用域之前,始终先在本地函数作用域中查找名称,然后在每个封闭函数作用域中查找名称(最后再查找内置函数)currentid
是一个类属性,在这些作用域中找不到它
要在Python中查找属性,您总是需要指定要查找的对象。尽管查找协议意味着对象本身不必具有属性;属性查找将退回到指定对象的类(以及基类,如果涉及继承)
因此,这将起作用:
del connections[self.currentid]
但是,我认为您的代码的其余部分也不是您所认为的那样。open
方法中的此行:
currentid = global_counter
不设置SocketHandler
对象的currentid
属性。分配给裸名称总是分配给局部变量,除非您明确声明它为global
(您似乎知道这一点,因为您使用了global
关键字)。因此在open
方法中,currentid
是一个局部函数变量;它的值在open
方法的末尾丢失
事实上,您的SocketHandler
对象根本没有currentid
属性(除非您还有更多代码没有显示给我们)。将currentid=0
放在类块中不会为所有SocketHandler
实例提供currentid
属性。它为SocketHandler
类本身提供了一个属性currentid
;这就像def open(self):
块在类对象上创建open
属性(存储函数),而不是在每个实例上
在on\u close
方法中读取self.currentid
将无法在对象self
中找到currentid
属性,因此Python将查看self
类,它是SocketHandler
。该对象确实有一个currentid
值,因此读取self.currentid
的结果将是0
,无论您以前是否在该SocketHandler
上运行过open
如果要将currentid
作为实例变量存储在每个SocketHandler
中,则open
中的行需要是:
self.currentid = global_counter
这将分配给
self
引用的对象的currentid
属性。然后,您还需要将方法中对currentid
的所有其他引用更改为self.currentid在Python中,您没有对方法内部属性的隐式访问权
行中的一个简单名称,如currentid
:
del connections[currentid]
在尝试全局模块作用域之前,始终先在本地函数作用域中查找名称,然后在每个封闭函数作用域中查找名称(最后再查找内置函数)currentid
是一个类属性,在这些作用域中找不到它
要在Python中查找属性,您总是需要指定要查找的对象。尽管查找协议意味着对象本身不必具有属性;属性查找将退回到指定对象的类(以及基类,如果涉及继承)
因此,这将起作用:
del connections[self.currentid]
但是,我认为您的代码的其余部分也不是您所认为的那样。open
方法中的此行:
currentid = global_counter
不设置SocketHandler
对象的currentid
属性。分配给裸名称总是分配给局部变量,除非您明确声明它为global
(您似乎知道这一点,因为您使用了global
关键字)。因此在open
方法中,currentid
是一个局部函数变量;它的值在open
方法的末尾丢失
事实上,您的SocketHandler
对象根本没有currentid
属性(除非您还有更多代码没有显示给我们)。将currentid=0
放在类块中不会为所有SocketHandler
实例提供currentid
属性。它为SocketHandler
类本身提供了一个属性currentid
;这就像def open(self):
块在类对象上创建open
属性(存储函数),而不是在每个实例上
在on\u close
方法中读取self.currentid
将无法在对象self
中找到currentid
属性,因此Python将查看self
类,它是SocketHandler
。该对象确实有一个currentid
值,因此读取self.currentid
的结果将为