Python的 - 为什么不是在方法定义这个类变量?(Python - Why is this cl

2019-06-18 11:18发布

我有一个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”在那里我打印,我打开/关闭的连接线。 我在类中定义它,它为什么不在范围内。 另外,我已阅读,使用全局变量是不好的,但我没有看到解决的办法。 有人能指出我应该怎么办呢? 谢谢。

Answer 1:

你不必里面的方法来属性隐式访问,在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.currentidon_close方法无法找到currentid的对象属性self ,所以Python会看类的selfSocketHandler 。 这个对象确实currentid值,所以阅读的结果self.currentid将是0 ,你是否先前曾执行过openSocketHandler

如果你的意思是存储currentid为每一个实例变量SocketHandler ,然后在该行open将需要:

self.currentid = global_counter

这个分配给currentid通过引用的对象的属性self 。 你也那么需要改变所有其它引用currentid在你的方法self.currentid



Answer 2:

currentid应该self.currentid ,因为它是一个类变量。



Answer 3:

currentid是实例属性,因此使用self.currentid代替currentid

def on_close(self):
        global connections
        print "WebSocket " + str(self.currentid) + " closed"
        del connections[self.currentid]


文章来源: Python - Why is this class variable not defined in the method?