我有一个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
在“打开”和“打开/关闭”行中,我在其中打印我正在打开/关闭连接。我在类中定义了它,为什么它不在范围内。另外,我已经读到使用全局变量是不好的,但是我看不到解决这个问题的方法。有人能指出我该怎么做吗?谢谢。
currentid
应该是self.currentid
,因为它是一个类变量。currentid
是实例属性,因此使用self.currentid
而不是currentid
:在Python中,不能隐式访问方法内部的属性。
一个像
currentid
这样的空名字:在尝试全局模块作用域之前,始终在本地函数作用域中查找一个名称,然后在每个封闭函数作用域中查找一个名称(然后在最后一种方法中查看内置函数)。
currentid
是一个类属性,在这些作用域中都找不到。要在Python中查找属性,需要指定要查找的对象。尽管查找协议意味着对象不一定需要属性本身;但属性查找将返回到指定对象的类(如果涉及继承,则返回基类)。
所以这是可行的:
但是,我认为您的代码的其余部分也没有做您认为它是什么。
open
方法中的此行:不设置
SocketHandler
对象的currentid
属性。赋值给裸名总是赋值给局部变量,除非您显式声明它global
(您似乎意识到了这一点,因为您使用了global
关键字)。所以在open
方法中,currentid
是一个局部函数变量;它的值在open
方法的末尾丢失。事实上,您的
SocketHandler
对象根本没有currentid
属性(除非有更多代码您没有向我们显示)。把currentid = 0
放在类块中并不能给所有的SocketHandler
实例一个currentid
属性。它给SocketHandler
类本身一个属性currentid
;这就像def open(self):
块在类对象上创建open
属性(存储函数)一样,而不是在每个单独的实例上。读取
on_close
方法中的self.currentid
将无法在对象self
中找到currentid
属性,因此Python将查看self
的类,即SocketHandler
。那个对象确实有一个currentid
值,所以读取self.currentid
的结果将是0
,不管您以前是否在该SocketHandler
上运行过open
。如果要将
currentid
作为实例变量存储在每个SocketHandler
中,那么open
中的行将需要:这将分配给由
self
引用的对象的currentid
属性。然后还需要将方法中对currentid
的所有其他引用更改为self.currentid
。相关问题 更多 >
编程相关推荐