Python类中的变量作用域
在一个类里声明一个变量(在函数外面):这个变量可以被类里的所有函数访问(基本上就是一个公共变量)。
在一个类里声明一个变量,放在某个函数里面:只有这个函数能访问这个变量(它只在这个函数的范围内可用)。
在一个类的函数里用 self.(变量名)
声明一个变量:这个变量可以被类里的所有函数访问(这和 global (变量名)
有什么不同呢?)。
而且因为没有私有或保护的概念,所以一切都是公共的,类内部能访问的东西,类外部也能访问。
还有其他需要注意的细节吗?我是不是基本上都明白了?
4 个回答
虽然这个问题已经有人回答了,但我想对你的问题再补充一些评论:
在一个类中声明一个变量(在函数外部):所有类中的函数都可以访问这个变量(基本上是一个公共变量)。
这就像一个静态变量,可以通过类名来调用。这个变量对所有函数都是可用的,任何函数都可以修改它和打印它。
在一个类的函数内部声明一个变量:只有那个函数可以访问这个变量(它在那个函数的作用域内):
如果变量是没有用self
声明的,那么它只能在那个函数内部使用,就像一个局部变量。不过,如果用self
来声明,比如self.var = 'somevalue'
,那么这个变量可以通过任何对象访问,但不能通过类名访问。
在一个类的函数内部用
self.(变量名)
声明一个变量:所有类中的函数都可以访问这个变量(这和global (变量名)
有什么不同呢?)
请参考上面的回答。
而且因为没有私有或保护的概念,所以所有东西都是公共的,因此从类内部可以访问的所有内容也可以从类外部访问。
没错,但我们可以用单下划线来告诉大家这个变量是私有的,不过从技术上讲,这并不能真正让它变成私有的。
在类的最上面声明一个变量,就像是在声明一个静态变量或者类变量。如果用self来声明,那就是在声明一个实例变量。类变量可以通过类名来修改,比如说 Class.x = 5
,这样所有的实例都会受到这个改变的影响。而实例变量是属于某个特定实例的,只有那个实例才能修改它。
你可以通过下划线来实现一定程度的访问控制。具体可以参考 Python教程中的私有变量。按照惯例,以一个下划线开头的变量,比如 _foo
,表示它是API的非公开部分;而以两个下划线开头的变量,比如 __foo
,它的名字会被“改名”,变成 _classname__foo
。
因为你提问中的内容不是特别清楚,我决定用一个简单的例子来解释一下。这个例子还包括了一些你在列表中没有提到的内容,比如 __something
这样的变量。
class Test:
a = None
b = None
def __init__(self, a):
print self.a
self.a = a
self._x = 123
self.__y = 123
b = 'meow'
一开始,a
和 b
只是为这个类定义的变量 - 你可以通过 Test.a
和 Test.b
来访问它们,而这些变量并不属于任何特定的实例。
当你创建这个类的一个实例时(这时会执行 __init__
方法):
print self.a
找不到实例变量,因此返回的是类变量。self.a = a
:这时创建了一个新的实例变量a
。这个新的变量会覆盖类变量,所以现在self.a
指向的是实例变量;如果你想访问类变量,就需要用Test.a
。- 给
self._x
赋值会创建一个新的实例变量。这个变量被认为是“不是公共接口的一部分”(也就是受保护的),但从技术上讲,它的行为没有什么不同。 - 给
self.__y
赋值会创建一个名为_Test__y
的新实例变量,也就是说,它的名字被“改名”了,所以除非你使用这个改名后的名字,否则无法从类外部访问它。这可以用来表示“私有”变量。 - 给
b
赋值会创建一个局部变量。这个变量只能在__init__
函数内部使用,无法在实例、类或全局范围内访问。