Menu Close

Python 命名空间和范围 (作用域)

如果您曾经读过“Python 之禅”(Python 解释器中的类型import this),则最后一行指出,命名空间是一个很棒的主意-让我们做更多的事情! 那么这些神秘的命名空间是什么? 让我们首先看看名字是什么。

Python 中的名称是什么?

名称(也称为标识符)只是赋予对象的名称。 Python 中的所有内容都是对象。 名称是访问基础对象的一种方式。

例如,当我们执行分配a = 2时,2是存储在内存中的对象,而a是与之关联的名称。 我们可以通过内置函数 id()获得某个对象的地址(在 RAM 中)。 让我们看看如何使用它。

例1.1.同一对象ID值



# Note: You may get different values for the id

a = 2
print('id(2) =', id(2))

print('id(a) =', id(a))

输出结果

内置函数ID的结果

在这里,两者都引用相同的对象2,因此它们具有相同的id()。 让我们做些有趣的事情。

例1.2. 不同对象的id的值

# Note: You may get different values for the id

a = 2
print('id(a) =', id(a))

a = a+1
print('id(a) =', id(a))

print('id(3) =', id(3))

b = 2
print('id(b) =', id(b))
print('id(2) =', id(2))

结果

上述步骤序列中发生了什么? 让我们用一个图来解释一下:

Python变量内存图
Python变量内存图

创建一个对象2并将其与名称a关联,当我们执行a = a+1时,将创建一个新的对象3,而现在将a与这个对象关联起来。

注意,id(a)id(3)具有相同的值。

此外,当执行b = 2时,新名称b与先前的对象2相关联。

这是有效的,因为 Python 不必创建新的重复对象。 名称绑定的这种动态特性使 Python 功能强大。 名称可以引用任何类型的对象。

>>> a = 5
>>> a = 'Hello World!'
>>> a = [1,2,3]

所有这些都是有效的,a将引用不同实例中的三种不同类型的对象。 函数也是对象,因此名称也可以引用它们。

def printHello():
print("Hello")


a = printHello

a()

结果

Hello

a可以使用相同的名称,我们可以使用该名称来调用该函数。


2. Python 中的命名空间是什么?

现在我们了解了名称是什么,我们可以继续进行命名空间的概念。

简而言之,名称空间是名称的集合。在 Python 中,您可以将名称空间想象为已定义的每个名称到对应对象的映射。

不同的名称空间可以在给定时间共存,但是完全隔离。

当我们启动 Python 解释器时,将创建一个包含所有内置名称的名称空间,并且只要该解释器运行,该名称空间就会存在。

这就是为什么内置id(),print()等函数始终可以从程序的任何部分使用的原因。 每个模块创建其自己的全局名称空间。

这些不同的名称空间是隔离的。 因此,不同模块中可能存在的相同名称不会冲突。

模块可以具有各种函数和类(classes)。 调用函数时会创建一个本地名称空间,该名称空间中定义了所有名称。 与类相似, 下图可能有助于阐明这一概念。

 

3.Python 变量范围

尽管定义了各种唯一的名称空间,但我们可能无法从程序的每个部分访问它们。 范围的概念开始起作用。

范围是程序的一部分,从那里可以直接访问名称空间而无需任何前缀。

在任何给定时刻,至少有三个嵌套作用域。

  1. 具有局部名称的当前函数的范围
  2. 具有全局名称的模块的范围
  3. 具有内置名称的最外部作用域

在函数内部进行引用时,将在本地名称空间中搜索名称,然后在全局名称空间中搜索,最后在内置名称空间中搜索。

如果另一个函数内有一个函数,则新作用域嵌套在本地作用域内。

Python Namespaces
Python Namespaces

4.Python 范围(作用域)和命名空间的示例

Python 命名空间
Python 命名空间

在这里,变量a在全局命名空间中。 变量b在outer_function()的本地名称空间中,而c在inner_function()的嵌套本地名称空间中。

当我们在inner_function()中时,c对我们来说是本地的,b是非本地的,a是全局的。 我们可以读取c并为其分配新值,但只能从inner_function()读取b和a。

如果我们尝试为b赋值,则会在本地名称空间中创建一个与非本地b不同的新变量b。 当我们为a分配一个值时,也会发生同样的事情。

但是,如果我们将b为全局变量,则所有引用和赋值都将转到全局变量。 同样,如果我们想重新绑定变量b,则必须将其声明为非本地变量。 以下示例将进一步阐明这一点。

例4.1 局部变量和全局变量

def outer_function():
    a = 20

    def inner_function():
        a = 30
        print('a =', a)

    inner_function()
    print('a =', a)

a = 10
outer_function()
print('a =', a)

结果

在此程序中,在单独的命名空间中定义了三个不同的变量a并进行了相应的访问。

在以下程序中,

例4.2  global关键词的应用

def outer_function():
    global a
    a = 20

    def inner_function():
        global a
        a = 30
        print('a =', a)

    inner_function()
    print('a =', a)

a = 10
outer_function()
print('a =', a)

结果

在这里,由于使用了关键字global,所有引用和分配都指向全局a

wer

READ  Python 包 (Package) 子包以及python包的初始化
除教程外,本网站大部分文章来自互联网,如果有内容冒犯到你,请联系我们删除!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Leave the field below empty!

Posted in Python教程

Related Posts