1. 首页
  2. 技术文章

9、Python命名空间和范围

Python中的名称是什么?

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

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

例如,当我们执行赋值操作时a = 22是一个存储在内存中的对象,并且一个是我们与之关联的名称。我们可以通过内置函数 获取某个对象的地址(在RAM中)id()。让我们看看如何使用它。

# Note: You may get different values for the id

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

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

输出

id(2)= 9302208
id(a)= 9302208

在这里,两者都引用相同的对象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))

输出

id(a)= 9302208
id(a)= 9302240
id(3)= 9302240
id(b)= 9302208
id(2)= 9302208

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

变量的内存图
Python中变量的内存图

最初,2创建一个对象并命名一个与之关联,当我们这样做时a = a+1,将3创建一个新对象,现在一个 与该对象关联。

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

此外,在b = 2执行时,新名称b与上一个对象关联2

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

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

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

def printHello():
    print("Hello")


a = printHello

a()

输出

Hello

同名 a 可以引用一个函数,我们可以使用该名称来调用该函数。


Python中的命名空间是什么?

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

简而言之,名称空间是名称的集合。

在Python中,您可以将名称空间想象为已定义的每个名称到对应对象的映射。

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

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

这就是为什么内置的功能(例如id()print()等始终可以从程序的任何部分提供给我们的原因。每个模块都创建自己的全局名称空间。

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

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

Python编程中的嵌套命名空间
Python中不同名称空间的图

Python变量范围

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

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

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

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

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

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


Python范围和命名空间的示例

def outer_function():
    b = 20
    def inner_func():
        c = 30

a = 10

在这里,变量 一个在全局名称空间中。多变的b是的本地命名空间outer_function()C位于的嵌套本地名称空间中inner_function()

当我们进去时inner_function()C 对我们来说是本地的 b 是非本地的, 一个是全球性的 我们可以读取以及分配新值给C 但只能读 b 和 一个 来自inner_function()

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

但是,如果我们声明 一个 作为全球性的,所有的参考和分配都归于全球性 一个。同样,如果我们想重新绑定变量b,必须将其声明为非本地。以下示例将进一步阐明这一点。

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 = 30
a = 20
a = 10

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

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)

程序的输出是。

a = 30
a = 30
a = 30 

在这里,所有参考和分配都针对全球 一个由于使用关键字global

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站不拥有所有权,不承担相关法律责任。如发现有侵权/违规的内容, 联系QQ1841324605,本站将立刻清除。

发表评论

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

联系我们

服务热线:130-0886-1890

QR code