7.2.5 类的命名空间
下面两条语句大致等价:
def foo(x): return x * x
foo = lambda x: x * x
它们都创建一个返回参数平方的函数,并将这个函数关联到变量foo。可以在全局(模块)作用域内定义名称foo,也可以在函数或方法内定义。定义类时情况亦如此:在class语句中定义的代码都是在一个特殊的命名空间(类的命名空间)内执行的,而类的所有成员都可访问这个命名空间。类定义其实就是要执行的代码段,并非所有的Python程序员都知道这一点,但知道这一点很有帮助。例如,在类定义中,并非只能包含def语句。
>>> class C:
... print('Class C being defined...')
...
Class C being defined...
>>>
这有点傻,但请看下面的代码:
class MemberCounter:
members = 0
def init(self):
MemberCounter.members += 1
>>> m1 = MemberCounter()
>>> m1.init()
>>> MemberCounter.members
1
>>> m2 = MemberCounter()
>>> m2.init()
>>> MemberCounter.members
2
上述代码在类作用域内定义了一个变量,所有的成员(实例)都可访问它,这里使用它来计算类实例的数量。注意到这里使用了init来初始化所有实例,第9章将把这个初始化过程自动化,也就是将init转换为合适的构造函数。
每个实例都可访问这个类作用域内的变量,就像方法一样。
>>> m1.members
2
>>> m2.members
2
如果你在一个实例中给属性members赋值,结果将如何呢?
>>> m1.members = 'Two'
>>> m1.members
'Two'
>>> m2.members
2
新值被写入m1的一个属性中,这个属性遮住了类级变量。这类似于第6章的旁注“遮盖的问题”所讨论的,函数中局部变量和全局变量之间的关系。
领取专属 10元无门槛券
私享最新 技术干货