在Python中,我应该使用“global”还是“self.”来处理类作用域变量?

21 投票
3 回答
24536 浏览
提问于 2025-04-16 13:12

这两个代码块都能正常工作。有没有什么“正确”的做法呢?

class Stuff:
    def __init__(self, x = 0):
        global globx
        globx = x
    def inc(self):
        return globx + 1

myStuff = Stuff(3)
print myStuff.inc()

这个会输出“4”

class Stuff:
    def __init__(self, x = 0):
        self.x = x
    def inc(self):
        return self.x + 1

myStuff = Stuff(3)
print myStuff.inc()

这个也会输出“4”

我还是个新手,正在一个类里处理很多变量。开始想为什么我在所有东西前面都要加上“self.”。

谢谢你的帮助!

3 个回答

1

这两者的意思差别很大。self. 表示这是一个实例变量,也就是说每个实例都有自己的这个变量。这种变量可能是最常见的,但并不是唯一的。还有类变量,它是在类层面上定义的(也就是说,当类定义被执行时就已经存在了),可以在类的方法中访问。它和静态方法的用法很相似,通常在你需要在多个实例之间共享一些东西时会用到(这种做法是完全可以的,虽然并不是解决某个问题的唯一方法)。你可能需要选择其中一种,具体取决于你在做什么。实际上,我们无法读懂你的想法,也不能告诉你哪种适合你的问题。

全局变量就另当别论了。它们是全局的——每个人都使用同一个。这几乎从来不是个好主意(原因在很多地方都有解释),但如果你只是想写个简单的脚本,需要在几个地方共享一些东西,它们是可以接受的。

10

关于“类作用域变量”,有两种方式。第一种是使用 self,这叫做实例变量,每个类的实例都有自己的一份实例变量;第二种是在类定义中定义变量,可以通过以下方式实现:

class Stuff:
  globx = 0
  def __init__(self, x = 0):
    Stuff.globx = x 
  ...

这被称为类属性,可以通过 Stuff.globx 直接访问,它属于类,而不是类的实例,就像Java中的静态变量一样。

你绝对不要对“类作用域变量”使用 global 语句,因为它并不是。用 global 声明的变量是在全局作用域中的,比如说定义类的模块的命名空间。

命名空间和相关概念在这里的Python教程中有介绍。

13

你应该使用第二种方法,这样每个实例都有一个独立的 x

如果你使用全局变量,当你有多个 Stuff 实例时,可能会发现结果很意外,因为改变一个的值会影响到其他所有的实例。

在你的 Python 代码中到处使用明确的 self 是很正常的。如果你试图用一些技巧来避免这样做,会让其他 Python 程序员读起来很困难(而且可能还会引入额外的错误)。

撰写回答