变量,命名空间和类

时间:2013-09-13 18:08:23

标签: python

基于以下示例,为什么我可以在类中打印var xyz,因为我一直认为该类存储在自己的命名空间中。

xyz = 123
>>> class test:
...    def __init__(self):
...        pass
...    def example(self):
...        print xyz
...
>>> test().example()
123

由于

3 个答案:

答案 0 :(得分:3)

类不存储在它们自己的命名空间中,而是定义它们自己的命名空间,即在类中定义的变量是本地的,并且不能直接在它之外访问。但是,如果需要,类可以从全局范围访问变量。

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,因此全局范围用于获取值。

与范围相关:

Why am I getting an UnboundLocalError when the variable has a value?

What are the rules for local and global variables in Python?

答案 1 :(得分:1)

类不存储在自己的命名空间中。它们存储在定义它们的命名空间中;在您的情况下,这是解释器会话的全局命名空间。

类中的方法仍然可以引用同一名称空间中的名称。

也许您在课程定义时与范围混淆了。类 body 的执行就像它是一个函数一样;然后,该函数的本地名称空间形成结果类的属性。您仍然可以从那里获取外部范围的名称,但是:

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

答案 2 :(得分:0)

该类位于命名空间中,但除此之外。您的问题更多是关于变量/成员的可访问性。该类的成员是封装的,这意味着访问是通过类。

xyz位于全局命名空间中。这意味着变量可以在不通过类的情况下访问。这是要避免的事情。类很容易创建(在定义它们和实例化它们时)。

命名空间更容易理解,因为它只是预先包含在该命名空间中包含的类的名称。考虑到这种方式,更多的是以课程为中心,这是OOP的主要目标。