我有一个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”在那里我打印,我打开/关闭的连接线。 我在类中定义它,它为什么不在范围内。 另外,我已阅读,使用全局变量是不好的,但我没有看到解决的办法。 有人能指出我应该怎么办呢? 谢谢。
你不必里面的方法来属性隐式访问,在Python。
裸露的名称,如currentid
在该行:
del connections[currentid]
看起来总是一个名字在当地的功能范围,然后在每个封闭功能范围,试图在全球范围模块之前(然后看着内置插件作为最后的手段)。 currentid
是一类属性,它不会以任何那些示波器中找到。
要查找在Python中,你总是需要指定要在其中寻找一个对象的属性。 尽管查找协议意味着该对象不必具有该属性本身; 属性查找将回落到类,你指定的对象(与基类,如果继承参与)。
因此,这会工作:
del connections[self.currentid]
不过,我不认为你的代码的其余部分是做什么的,你想,不是。 这条线在open
方法:
currentid = global_counter
不设置currentid
你的属性SocketHandler
对象。 分配到裸名总是分配给一个局部变量,除非你明确声明它global
(你似乎是意识到了这一点,因为你已经使用了global
关键字)。 因此,在open
方法, currentid
是本地函数的变量; 它的值是在的端部丢失open
方法。
事实上,你SocketHandler
对象没有一个currentid
所有属性(除非有更多的代码,你还没有告诉我们)。 把currentid = 0
类中的块不给所有SocketHandler
实例一个currentid
属性。 它给SocketHandler
类本身的属性currentid
; 这仅仅是作为def open(self):
块创建一个open
的类对象上的属性(存储功能),而不是每个单独的实例。
阅读self.currentid
在on_close
方法无法找到currentid
的对象属性self
,所以Python会看类的self
是SocketHandler
。 这个对象确实有currentid
值,所以阅读的结果self.currentid
将是0
,你是否先前曾执行过open
上SocketHandler
。
如果你的意思是存储currentid
为每一个实例变量SocketHandler
,然后在该行open
将需要:
self.currentid = global_counter
这个分配给currentid
通过引用的对象的属性self
。 你也那么需要改变所有其它引用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]