iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python基础教程之名称空间以及作用域
  • 552
分享到

Python基础教程之名称空间以及作用域

2024-04-02 19:04:59 552人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录前言名称空间什么是名称空间名称空间的意义名称空间的查找顺序局部名称空间详解嵌套函数中的查找顺序关于嵌套函数的使用作用域什么是作用域global语句nonlocal语句题目题目小结

前言

所谓“基础不狠,人站不稳”,对于任何一种编程语言来说基础往往都是重中之重,以python为例,其中的两大分水岭就是函数编程面向对象,而今天所要巩固的知识点后续会多次使用,那就是名称空间和作用域

名称空间

什么是名称空间

Python中名称空间是用存储对象和名字绑定关系的地方,那么问题来了,什么是对象,什么是名字,什么是绑定关系?

1)在目前,我们对于对象的认知可以暂时只停留在人云亦云的“Python中一切都是对象”基础上,函数是对象、类是对象、变量,模块、所有一切都是对象,有这样的认知就可以了,后续有机会将继续补充;

2)名字,很简单,每一次我们对模块、变量、函数、类的定义都需要取名字,而这些名字都会放在名称空间之中;

3)Python对于名字和数据之间给出了绑定关系,举个例子,当我们在定义a = 6时,Python就自动将变量a这个名字与6这个对象给出了绑定关系,我们可以使用del语句将绑定关系解除。

明白了名称空间是用于存储对象和名字绑定关系的地方,那么接下来就可以细致了解一下名称空间可以分为哪几类了:

1)内置名称空间 —— 用于存放各种内置函数(built-in functions)、内置模块(built-in modules),例如abs()就是内置函数,内置名称空间可以在Python任何一处使用;

2)全局名称空间 —— 全局名称空间中的名字可以在同一个模块中任意处使用;

3)局部名称空间 —— 局部名称空间中的名字仅仅只能够在函数内部使用。

名称空间的意义

名称空间最大的作用就是防止名字重复造成的引用不当,我们可以在全局名称空间中定义一个a = 6同时也可以在局部名称空间中定义一个a = 7,这两者之间是不会产生任何冲突的,这就是名称空间最大的作用,防止名字重复造成的引用不当。

名称空间的查找顺序

知道了名称空间的意义,那么肯定会有读者意识到,我在全局定义一个a = 6,在局部定义一个a = 7,那么接下来调用a这个名字的时候,Python究竟会从哪个空间开始寻找a所对应的对象呢?

我只能说,这位读者你很上道,我们将以实例解答这个问题;

a = 6              # 在全局名称空间中定义一个a
b = 8            # 在全局名称空间中定义一个b,为了测验调用函数时能否找到全局中的b
def test():
    a = 7        # 在局部名称空间中定义一个a
    return a,b
print(test())
print(a)    

(7,8)
6

从以上我们的测验中,调用函数test时输出的a将会是7,而当直接使用print(a)时输出的a将会是6。

所以我们可以大胆的下结论:

1)当调用函数的时候,函数寻找名字的顺序将会是 局部名称空间—>全局名称空间—>内置名称空间;

2)当没有调用函数,直接使用名字的时候查找顺序就是 全局名称空间 —>内置名称空间;

3)只要在某个名称空间(局部也好、全局也罢)中找到了对应的名字,就停止寻找;

4)在不同名称空间中定义相同名字是可行的,后续定义的并不会将原先覆盖掉。

局部名称空间详解

在局部名称空间中有一个非常神奇的事情,因为函数是可以相互嵌套的,在一个函数中嵌套另外一个函数是很正常的现象:

def test_1():           # 定义一个函数
    def test_2():       # 在test_1中定义一个嵌套函数
        print('球球好心人给个赞吧')
# 这是最简单的函数嵌套,
# 但也是最不规范的函数嵌套,
# 因为如果不改进的话,则无法使用嵌套的test_2函数

以上就是最简单形式的函数嵌套,那么问题接踵而至,上文中说过局部命中空间是在函数中产生的,那么如果我在一个函数中定义一个嵌套函数,是不是意味着我在局部名称空间中创建了一个局部名称空间?

对头!

但是在术语上我们会称test_2为最内部名称空间,而test_1则是被我们称为附属函数名称空间;

我们可以如此反复俄罗斯套娃:

def test_1():           # 定义一个函数
    def test_2():       # 在test_1中定义一个嵌套函数
        def test_3():   # 在内嵌函数test_2中再定义一个嵌套函数
            # 省略一万层....
            print('球球好心人给个赞吧')
        print('球球好心人给个赞吧')

嵌套函数中的查找顺序

在前文中已经介绍过了关于嵌套函数所产生的附属函数名称空间、内部名称空间,那么如果在附属函数名称空间和内部名称空间都定义一个相同名字,那么查找顺序是如何呢?

b = 10                    # 在全局定义一个b
def test_1():           # 定义一个函数
    def test_2():       # 在test_1中定义一个嵌套函数
        a = 6           # 在内部名称空间中定义一个a
        return a,b
    a = 7                # 在附属名称空间中定义一个a
    b = 8               # 在附属名称空间中定义一个b
​​​​​​​print(test_1())            # 调用函数

如果真的如上文中这样写的话,那么将不会输出任何结果哦,因为我们只调用了test_1,而作为嵌套的内部函数test_2没有被使用到,想要使用嵌套函数的话,就只能通过将嵌套函数作为返回值,返回出去

所以将代码修改一下

b = 10                    # 在全局定义一个b
def test_1():           # 定义一个函数
    def test_2():       # 在test_1中定义一个嵌套函数
        a = 6           # 在内部名称空间中定义一个a
        return a,b
    a = 7                # 在附属名称空间中定义一个a
    b = 8               # 在附属名称空间中定义一个b
    return test_2
print(test_1()())        # 调用函数

10
(6,8)

按照修改后,我们所得到的结果将会是6,当我们调用嵌套函数的时候,嵌套函数会从自身的局部空间中开始寻找是否有该名称

就像调用嵌套函数test_2一般,它从自己的局部名称空间开始寻找,找到了a = 6后就停止寻找

所以我们又可以下结论了:

1)当调用嵌套函数的时候,它的查找顺序是 内部名称空间—>附属函数名称空间—>全局名称空间—>内置名称空间;

2)找到对应的名字后就会停止寻找。

关于嵌套函数的使用

b = 10                    
def test_1():           
    def test_2():       
        a = 6           
        return a,b
    a = 7                
    b = 8               
    return test_2
print(test_1()())                # 仔细看一下调用函数的过程

为什么调用函数过程中需要写两个括号test_1()(),而不是直接test_1()呢?

我们仔细看一下test_1函数的返回值,test_1的返回值是一个函数对象test_2,所以我们如果调用函数的话只写一个括号将会得到一个函数对象,也就是test_2

来实例示范一下;

b = 10                    
def test_1():           
    def test_2():       
        a = 6           
        return a,b
    a = 7                
    b = 8               
    return test_2
print(test_1(), type(test_1()))        # 打印输出一下结果

<function test_1..test_2 at 0x000001A8E9981F30> <class ‘function’>
以上就是打印输出的结果,代表了函数对象

可能有读者想要唱反调了,我就是想直接写一个test_1()就能够直接得到想要的结果该怎么办呢?

我只能说,这位看官你很有成为天才的潜力,因为懒才是人类进步的基石,这个需求可以实现,但是我们要这样改代码:

b = 10                    
def test_1():           
    def test_2():       
        a = 6           
        return a,b
    a = 7                
    b = 8               
    return test_2()
print(test_1())                # 调用函数

(6,8)

我们的确得到了想要的结果,仔细想一下为什么呢?

还是因为返回值,函数test_1的返回值是test_2(),也就是说返回的结果是函数test_2运行后的结果,又开始俄罗斯套娃了,我拿到的返回值是另外一个函数的返回值!?

我只能说没错,是这样的。

但是用这个方法需要注意一点,那就是内嵌函数必须是无参数的!

b = 10                    
def test_1():           
    def test_2(c):           # 随便定义一个参数
        a = 6           
        return a,b
    a = 7                
    b = 8               
    return test_2()
print(test_1())                # 调用函数

TypeError: test_1..test_2() missing 1 required positional argument: ‘c’
这将会报错,给出的错误是函数test_2()缺失一个名为’c’的位置参数
所以想要使用这种方法还是需要注意下的,
但是换另外一种思路,如果内嵌函数需要参数,那么我返回的时候先把参数定义不行么?
这种方法的确是可行的,
但是如果这样的话那不如直接使用默认参数,在定义的时候直接将参数c定义好

以上就是关于俄罗斯套娃的名称空间的讲解,接下来我们要介绍一下作用域了,如果能够将名称空间中的知识点李姐,那么作用域也不过尔尔。

作用域

什么是作用域

作用域是根据名称空间所产生的,意思就是名字的作用范围;

在上文之中我们其实已经或多或少涉及到了作用域了。

b = 10                            # 这个全局变量的作用域就是该模块中的全部范围        
def test_1():           
    def test_2():       
        a = 6           
        return a,b                # 正因为全局变量的作用于是全部范围,才能够返回b
    a = 7                
    b = 8               
    return test_2
print(test_1()())

或多或少读者对于这个作用域已经有些许了解,

我直接将结论摆出:

内置名称空间 —— 其作用域是Python中的所有模块,能够在所有的模块中使用;
全局名称空间 —— 其作用域是该模块的所有范围,能够在模块内随意使用;
局部名称空间 —— 其作用域仅仅在于该函数内部,只能够在函数内部使用。

可能正是因为作用域的不同,所以查找顺序也会不同,作用域越大的名称空间反而查找的优先级越低,

正如上文中的,即使全局和局部中都有a这个名字,调用函数的时候也会先从局部开始。

global语句

不同的名称空间可以定义相同的名字,这样不会有任何冲突,可这也意味着,当我们在局部名称空间的时候是无法修改全局中的名字绑定关系,于是Python提供了一个方法去解决这个问题:

a = 10               # 定义一个全局语句

def test():
    global a        # 使用global语句,声明我是用的名字a全局名称空间中的那个a
    a = 5
    return a

print(a)            # 先打印输出一下没有调用函数前的a是什么
print(test())        # 输出一下函数中的结果
print(a)            # 看一下全局中的a是否发生了改变

10
5
5

所以我们可以知道,使用global语句后,我们使用的名字都将会是全局名称空间的

nonlocal语句

既然在局部可以修改全局名称空间中的名字绑定关系,那么在内部名称空间是否可以修改附属函数名称空间中的绑定关系呢?

答案显然是可以的,但是需要使用到nonlocal语句。

def test_1():
    def test_2():				# 在test_1里定义一个嵌套函数test_2
        a = 15

        def test_3():			# 俄罗斯套娃一波
            nonlocal a			# 使用nonlocal,声明接下来使用的a是附属名称空间的a,所以究竟是test_2中的还是test_1中的?
            a = 5
            print('调用test_3对a这个名字的绑定关系进行更改')

        test_3()
        print(f'输出附属函数名称空间中的a:{a}')

    a = 10
    test_2()
    print(f'输出最外部函数的a值:{a}')


test_1()

调用test_3对a这个名字的绑定关系进行更改
输出附属函数名称空间中的a:5
输出最外部函数的a值:10

由此我们可以知道,在调用nonlocal声明使用的a是函数test_2中的,而不是test_1中的

因此我们可以得出的结论是:

1)在使用nonlocal语句的过程中,仅仅只会向上寻找到对应名字修改一次

题目题目

还是老规矩,写一个题目对上述内容进行测试

def discount(price,rate):
    final_price = price * rate
    old_price = 6
    print('old_price的值',old_price)
    return final_price

old_price = float(input('请输入价格'))
rate = float(input('请输入折扣率'))
print(discount(old_price,rate))
print('old_price的值',old_price)

在上述代码中,假设我输入的old_price是100,rate是0.6
那么请问两个问题

print(discount(old_price,rate))中会输出的值是多少?
print('old_price的值',old_price)输出的值是多少?

小结

  1. 命名空间是一个名字(变量)和对象的映射表。
  2. 作用域是指命名空间的作用范围,或者说管辖区域。
  3. 变量的查找遵循 LEGB 原则,先从基层(最内层函数找),然后到市委(外层函数)…,再到省委(模块命名空间),最后到中央(builtin 命名空间)。
  4. 各个命名空间相互独立,创建时间和生命周期各不相同。
  5. global 用于在函数内创建和修改全局变量。
  6. nonlocal 用于在内层函数修改外层函数局部变量。
  7. 没有声明 global 和 nonlocal,尝试修改全局变量或外层函数局部变量,实际上只会在函数或者内层函数创建一个新的局部变量,同名的全局变量或者外层函数局部变量不会受影响。

能够看到这里的都是一条汉子!

总结

到此这篇关于Python基础教程之名称空间以及作用域的文章就介绍到这了,更多相关Python名称空间及作用域内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Python基础教程之名称空间以及作用域

本文链接: https://www.lsjlt.com/news/162053.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python基础教程之名称空间以及作用域
    目录前言名称空间什么是名称空间名称空间的意义名称空间的查找顺序局部名称空间详解嵌套函数中的查找顺序关于嵌套函数的使用作用域什么是作用域global语句nonlocal语句题目题目小结...
    99+
    2024-04-02
  • Python名称空间及作用域怎么用
    今天小编给大家分享一下Python名称空间及作用域怎么用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。名称空间什么是名称空间...
    99+
    2023-06-26
  • Python名称空间与作用域
    目录一 名称空间1.1 内建名称空间1.2 全局名称空间1.3 局部名称空间二 作用域2.1 全局作用域与局部作用域2.2 作用域与名字查找的优先级一 名称空间 名称空间即存放名字与...
    99+
    2024-04-02
  • 名称空间与作用域
    目录 名称空间(掌握) 内置名称空间 全局名称空间 局部名称空间 加载顺序 查找顺序 ...
    99+
    2023-01-31
    作用 名称 空间
  • python名称空间与作用域详情
    目录一、名称空间1.1 内置名称空间1.2 全局名称空间1.3 局部名称空间1.4 加载顺序1.5 查找顺序二、作用域2.1 全局作用域2.2 局部作用域2.4 函数对象+作用域应用...
    99+
    2024-04-02
  • Python中的命名空间、作用域以及lo
          最近一直看一本python经典教材——《Python学习手册》,因为之前都是突击学的,也没有仔细看一些经典教材,所以感觉自己的基础掌握的还不是很好,虽然网络上资源多,但我觉得还是有必要买本教材来认真的读一读,底层基础决定上层建筑...
    99+
    2023-01-31
    作用 空间 Python
  • Python名称空间与作用域实例分析
    本篇内容主要讲解“Python名称空间与作用域实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python名称空间与作用域实例分析”吧!一 名称空间名称空间即存放名字与对象映射/绑定关系的...
    99+
    2023-06-30
  • Python学习之名字,作用域,名字空间
    目录变量只是一个名字作用域和名字空间LGB规则eval和exec前言: 我们在PyFrameObject里面看到了3个独立的名字空间:f_locals、f_globals、f_bui...
    99+
    2024-04-02
  • Python学习之名字,作用域,名字空间(下)
    目录LEGB规则global表达式属性引用与名字引用属性空间小结前言: 这里再回顾一下函数的local空间,首先我们往global空间添加一个键值对相当于定义一个全局变量,那么如果往...
    99+
    2024-04-02
  • 关于Python函数对象的名称空间和作用域
    目录1.函数对象(1)函数对象的引用(2)函数可以放到序列里面(3)函数可以作为参数 , 传递给另一个函数(4)函数可以作为另一个函数的返回值2.名称空间3.作用域(1)作用域的理解...
    99+
    2023-05-17
    Python 函数 Python 函数作用域 Python 函数名称空间
  • Python 作用域和命名空间
    在介绍类之前,我首先要告诉你一些Python的作用域规则。类定义对命名空间有一些巧妙的技巧,你需要知道作用域和命名空间如何工作才能完全理解正在发生的事情。顺便说一下,关于这个主题的知识对任何高级Python程序员都很有用。 让我们从一些定...
    99+
    2023-01-31
    作用 空间 Python
  • python函数参数,名称空间,以及函数嵌套
    目录一. 函数参数–动态传参1.1动态位置接受参数,在参数位置编写*表⽰示接收任意内容1.2 动态接收关键字参数1.3无敌传参 * args, * * kwargs 一起...
    99+
    2024-04-02
  • Python函数命名空间,作用域LEGB及Global详析
    目录一、命名空间和作用域1.1 定义1.2 内建命名空间和内建作用域1.3 全局命名空间和全局作用域1.3 局部命名空间和局部作用域1.4 总结1.5 扩展LEGB二、Global关...
    99+
    2024-04-02
  • python之OpenCV的作用以及安装案例教程
    OpenCV的作用及安装 OpenCV简介 OpenCV是一个开源的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。提供了Pytho...
    99+
    2024-04-02
  • 解密Python中的作用域与名字空间
    目录楔子变量只是一个符号变量的可见性LGB 规则局部变量是静态存储的LEGB 规则global 表达式属性空间小结楔子 前面我们介绍了栈帧,在里面看到了 3 个独立的名字空间:f_l...
    99+
    2023-02-28
    Python作用域 名字空间 Python作用域 Python 名字空间
  • 知名技术作家分享Python零基础教程!
    最近这段时间,身边常常有人问:该不该学Python?如何学Python? Python包含的内容很多,加上各种标准库、拓展库,乱花渐欲迷人眼。 很多初学者都迫切希望能出现一个容易上手、言语简洁的Python教程,最好是能循序渐进,...
    99+
    2023-01-31
    基础教程 知名 作家
  • Python函数命名空间和作用域(Local与Global)
    目录1.Local作用域2.Enclosing function locals作用域3.Global全局变量4.非局部变量nonlocal5.就近原则6.函数执行顺序7.循环、判断代...
    99+
    2024-04-02
  • Python函数命名空间和作用域是什么
    这篇文章主要介绍Python函数命名空间和作用域是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1.Local作用域a = 100def func5():  &n...
    99+
    2023-06-29
  • Python命名空间与作用域深入全面详解
    目录1.命名空间2.作用域全局变量和局部变量global 和 nonlocal关键字1.命名空间 先看看官方文档的一段话: 命名空间(Namespace)是从名称到对象的映射,大部...
    99+
    2022-11-13
    Python作用域 Python命名空间
  • Python中的作用域与名字空间实例分析
    这篇文章主要介绍“Python中的作用域与名字空间实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python中的作用域与名字空间实例分析”文章能帮助大家解决问题。变量只是一个符号从解释器的角...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作