Python - 为什么这个类变量没有在方法中定义?

标签 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
        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

在“open”和“on_close”行上,我打印我正在打开/关闭连接。我在类中定义了它,为什么它不在范围内。另外,我读到过使用全局变量是不好的,但我看不出解决这个问题的方法。有人可以指出我应该做什么吗?谢谢。

最佳答案

在 Python 中,您无法隐式访问方法内部的属性。

行中的 currentid 之类的裸名:

del connections[currentid]

总是在局部函数作用域中查找一个名称,然后在每个封闭函数作用域中查找,然后再尝试全局模块作用域(然后将内置函数作为最后的手段)。 currentid 是一个类属性,不会在任何这些范围内找到。

要在 Python 中查找属性,您总是需要指定要查找的对象。尽管查找协议(protocol)意味着对象本身不一定具有属性;属性查找将回退到您指定的对象的类(以及基类,如果涉及继承)。

所以这会起作用:

del connections[self.currentid]

但是,我认为您的其余代码也没有按照您的想法行事。 open 方法中的这一行:

currentid = global_counter

没有设置 SocketHandler 对象的 currentid 属性。分配给一个裸名总是分配给一个局部变量,除非你明确声明它global(你似乎意识到了这一点,因为你已经使用了 global 关键字)。所以在open方法中,currentid是一个局部函数变量;它的值在 open 方法结束时丢失。

事实上,您的 SocketHandler 对象根本没有 currentid 属性(除非您没有向我们展示更多代码)。将 currentid = 0 放在类 block 中并不会为所有 SocketHandler 实例提供 currentid 属性。它给SocketHandler自身一个属性currentid;这就像 def open(self): block 在类对象上创建一个 open 属性(存储一个函数),而不是在每个单独的实例上。

on_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 - 为什么这个类变量没有在方法中定义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12790114/

相关文章:

python - 如何查找图像中的子图像数量

Makefile 中的变量

variables - 如何将 Terraform 配置器 "local-exec"输出存储在本地变量中并使用 "remote-exec"中的变量值

ruby - block 外部可访问的局部变量

python - 使用 pandas 正则表达式验证数据帧 header

python - os.system 中的变量

python - Python中类的顶级属性存储在哪里

javascript - javascript中的作用域表现得很奇怪

python - "No Module named ' _portaudio' : Unable to find solution

batch-file - 如何仅在命令是单行文本时获取命令的输出?