基于以下示例,我为什么可以从类中打印 var xyz,因为我一直认为该类存储在其自己的命名空间中。
xyz = 123
>>> class test:
... def __init__(self):
... pass
... def example(self):
... print xyz
...
>>> test().example()
123
谢谢
基于以下示例,我为什么可以从类中打印 var xyz,因为我一直认为该类存储在其自己的命名空间中。
xyz = 123
>>> class test:
... def __init__(self):
... pass
... def example(self):
... print xyz
...
>>> test().example()
123
谢谢
类不存储在它们自己的命名空间中,而是定义它们自己的命名空间,即在一个类中定义的变量是它的本地变量,不能直接在它之外访问。但是,如果需要,一个类可以从全局范围访问变量。
Python 使用LEGB规则来查找变量的值:
L:本地范围
E:封闭范围
G : 全局范围
B : 内置
LEGB示例:
z = 3
def enclosing():
y = 2
def local_func():
x = 1
print x #fetch this from local scope
print y #fetch this from enclosing scope
print z #fetch this from global scope
print sum #fetch this from builtins
local_func()
enclosing()
输出:
1
2
3
<built-in function sum>
因此,在您的情况下,xyz
在本地和封闭范围中都找不到,因此使用全局范围来获取值。
类不存储在它们自己的命名空间中。它们存储在定义它们的命名空间中;在您的情况下,这是解释器会话的全局命名空间。
类中的方法仍然可以引用同一命名空间中的名称。
也许您在类定义时对范围感到困惑。类体像函数一样执行;该函数的本地命名空间然后形成结果类的属性。但是,您仍然可以从外部范围获得名称,但是:
foo = 'bar'
class Spam(object):
baz = foo # works, foo can be referenced
def ham(self):
xyz = foo # works, foo is a global and can be referenced
xyz = baz # does **not** work, baz is part of the class now.
xyz = self.baz or Spam.baz # these do work
该类位于名称空间中,但这不是重点。您的问题更多是关于变量/成员的可访问性。类的成员被封装,这意味着访问是通过类。
xyz 在全局命名空间中。这意味着该变量可以在整个过程中访问,而无需通过类。这是要避免的事情。类很容易创建(在定义它们和实例化它们时)。
命名空间更容易理解为简单地添加到该命名空间中包含的类的名称。以这种方式思考,更多的仍然是以类为中心,这是 OOP 的主要目标。