[Python学习日记-38] Python 中的函数的名称空间

news2024/10/6 4:43:10

[Python学习日记-38] Python 中的函数的名称空间

简介

名称空间

作用域查找顺序

简介

        在前面学习函数的时候我们发现,函数内部也有一个内存空间是用于存储函数自己的一些变量的,及时这个变量名与外部的变量名一样是也没关系,Python 会优先调用内部的变量,后面我们也进一步学习了作用域,解释为每个变量和函数都有自己的作用域,其实变量和函数的作用域的不用就是我们这次要说的名称空间决定的,下面我们一起来看看名称空间到底是怎么一回事吧。

名称空间

        名称空间(Name Space),顾名思义就是存放名字的地方,那它到底是存什么东西的名字呢?那我们举例说明一下:若变量 x=1,1存放于内存中,那名字 x 存放在哪里呢?没错,名称空间正是存放名字 x 与1绑定关系的地方。

        Python 里面有4种名称空间,每个地方都有自己的名称空间,互不干扰,不同空间中的两个相同名字的变量之间没有任何联系。

        Python 中的名称空间有:LEGB

  • locals:函数内部的名称空间,一般包括函数的局部变量以及形式参数(形参)
  • enclosing function:在嵌套函数中外部函数的名称空间,例如,fun2 嵌套在 fun1 里,对 fun2 来说,fun1 的名字空间就是 enclosing。
  • globals:当前的模块空间,模块就是一些 py 文件。也就是说,globals() 类似全局变量。
  • __builtins__:内置模块空间,也就是内置变量或者内置函数的名称空间,使用 print(dir(__builtins__)) 可查看包含的值,如下图所示

        不同变量的作用域不同就是由这个变量所在的名称空间决定的。作用域即范围有:

  • 全局范围:全局存活,全局有效
  • 局部范围:临时存活,局部有效

        我们可以使用以下方法来查看不同作用域的名称空间,代码如下

# 全局范围
print(globals())

# 局部范围
print(locals())

代码输出如下:

        在同一层级的情况下,全局变量和局部变量并无差别,那我们来创建一个函数,在函数内部看看会怎么样吧,代码如下

a = "this is gloabls."

def is_local():
    b = "this is locals."
    print(locals())

print(globals())
is_local()

代码输出如下:

作用域查找顺序

        当程序引用某个变量的名字时,就会从当前名字空间开始搜索。搜索顺序规则便是:LEGB。即 locals -> enclosing function -> globals -> __builtins__。会进行一层一层的查找,找到了之后,便停止搜索,如果最后没有找到,则会抛出在 NameError 的异常。为了验证这一过程请看下面的代码

level = "L0"
n = 22

def func():
    level = "L1"
    n = 33
    print(locals())

    def outer():
        level = "L2"
        n = 44
        print("outer:",locals(),n)

        def inner():
            level = "L3"
            print("inner:",locals(),n)  # 此处打印的 n 会是多少呢?
        inner()
    outer()
func()

代码输出如下:

        从输出可知,当本层的名称空间当中有 n 时会优先查找本层的,像 L1 和 L2 中的输出都是如此,但是当本层没有 n 时,它将会去外层查找,像 L3 就是如此,它所输出的 n 就是 L2 中的44。如此类推,如果这个时候把 L2 中的 n 注释了,那么 L2 和 L3 都会输出 L1 中的 n,如下代码所示

level = "L0"
n = 22

def func():
    level = "L1"
    n = 33
    print(locals())

    def outer():
        level = "L2"
        # n = 44
        print("outer:",locals(),n)

        def inner():
            level = "L3"
            print("inner:",locals(),n)  # 此处打印的 n 会是多少呢?
        inner()
    outer()
func()

代码输出如下:

        如我们所料,L2 和 L3 都输出了 L1 的 n,即33。 但是在这里都只是嵌套函数内部的查找,还没有涉及到全局的,即  locals -> enclosing function,这个时候我们如下也也把 L1 的 n 也注释掉了会不会就直接显示全局里面的 n 呢?来看看下面的代码

level = "L0"
n = 22

def func():
    level = "L1"
    # n = 33
    print(locals(),n)

    def outer():
        level = "L2"
        # n = 44
        print("outer:",locals(),n)

        def inner():
            level = "L3"
            print("inner:",locals(),n)
        inner()
    outer()
func()

代码输出如下:

        这个过程就是 locals -> enclosing function -> globals 了,有的同学就会问到,那什么时候才会用到 __builtins__ 呢?这个就要涉及到内置函数了,在这里我们就用 dir() 为例,看下面的代码

level = "L0"
print(dir())
dir = 22
print(globals())

def func():
    level = "L1"
    print(locals(),dir)

    def outer():
        level = "L2"
        print("outer:",locals(),dir)

        def inner():
            level = "L3"
            print("inner:",locals(),dir)
        inner()
    outer()
func()

代码输出如下:

        从上面的代码中,我们发现我们把原来的 dir() 函数进行了重定向,在 globals() 里面变成了变量 dir = 22,这个时候后面的函数调用 dir 的时候全部都变成了22,这个时候就体现了 globals -> __builtins__了,弄清楚了这个优先级关系,在后面的开发当中就不会因为嵌套函数多起来之后手忙脚乱了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2191097.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CGLib动态代理和JDK动态代理Demo、ASM技术尝鲜

本文主要介绍CGLib和JDK动态代理的使用,不对源码进行深入分析。代码可直接复制使用。 类型 机制 回调方式 适用场景 效率 JDK动态代理 委托机制。代理类和目标类都实现了同样的接口。InvocationHandler持有目标类。代理类委托InvocationHandler去调用目标类原…

令牌主动失效机制范例(利用redis)注释分析

介绍该机制 令牌生成 在需要限流的场景中,系统会根据一定的速率生成令牌,存储在 Redis 中。可以设定每秒生成的令牌数量。 令牌获取 当用户请求时,系统会从 Redis 中获取令牌。可以使用原子性操作(如 DECR)来确保令牌…

SHAP分析

SHAP分析(SHapley Additive exPlanations)是一种基于博弈论的解释机器学习模型输出的方法。它提供了一种统一的方式来解释模型的预测结果,量化每个特征对模型预测的贡献,能够为复杂的机器学习模型(如随机森林、梯度提升…

C语言基础(8)之操作符(2)(详解)

目录 1. 操作符汇总表 2. 关系操作符 3. 条件操作符 4. 逗号表达式 5. 下标引用、函数调用和结构成员 5.1 下标引用 5.2 函数调用操作符 5.3 结构成员 6. 操作符的属性 6.1 操作符的优先级 大家好呀!上篇文章中我们详细讲解了操作符的前半部分&#xff0c…

【成长day】SuperPointSuperGlue(01): Superpoint论文算法学习与对应源码解析

两年前自己在实习公司做过superpoint相关的工作,当时是负责利用superpoint代替slam前端的特征点部分,来达到把特征点相关的处理放到推理计算平台上减轻CPU压力并且精度无损的目的,最终也是成功完成了这部分工作。但是当时没有留下任何的记录&…

YOLOv8 基于MGD的知识蒸馏

YOLOv8 基于MGD的知识蒸馏 接着上一篇我们介绍了YOLOv8的剪枝方案和代码,本篇文章将剪枝后的模型作为学生模型,剪枝前的模型作为教师模型对剪枝模型进行蒸馏,从而进一步提到轻量模型的性能。 Channel-wise Distillation (CWD) 问题和方法 …

IDM下载器如何下载网盘文件 IDM下载器支持哪些网盘

不用开通会员,也能高速下载网盘文件。使用IDM下载加速器,直接从服务器高速下载文件,轻松突破网盘限速。掌握IDM下载网盘文件的技巧,不仅可以节省会员费用,还可以大幅提高下载效率。有关IDM下载器如何下载网盘文件&…

【Linux:线程控制】

目录 线程的创建与等待: ​编辑 代码中tid是什么? 如何看待线程函数传参? ​编辑 ​编辑创建多线程:​编辑 终止多线程: 线程分离: 线程的创建与等待: void *threadrun(void *args) {int …

QT 中如何保存matlab 能打开的.mat数据矩阵!

Windows 上安装并使用 MATIO 库来保存 MATLAB 格式的 .mat 文件,需要进行以下步骤: 1. 下载并安装 CMake MATIO 使用 CMake 构建项目,因此你需要先安装 CMake。 前往 CMake 官网下载适用于 Windows 的安装程序并安装。 2. 下载 MATIO 库源…

Unity基础-矩阵-坐标转换结果的个人理解+数学公式说明

想做一些渲染效果做到头大,根本很多空白,完全无法实现,只能先暂停一下,重新学习矩阵 目录 Unity基础-数学矩阵 1.我们利用最简单的“转换矩阵”, 2.然后,视图坐标又是如何 3.最后就是剪裁坐标 3.1 - 其…

硬件设计-利用环路设计优化PLL的输出性能

目录 前言 问题描述 问题分析步骤 杂散源头排查 245.76M 参考相噪: 30.72M VCXO的相噪性能测试如下: 解决方案 前言 LMK04832是TI 新发布的低抖动双环去抖模拟时钟, 其最高输出频率可以到达3250MHz, 输出抖动极低,3200MHz…

MySQL 中的数据库锁和表锁

在 MySQL 数据库中,为了保证数据的一致性和完整性,会使用各种类型的锁。其中,数据库锁和表锁是比较常见的两种锁类型。 一、数据库锁和表锁的概念 (一)数据库锁 数据库锁是对整个数据库进行锁定,限制对数…

尝试从 http://pypi.doubanio.com/simple 这个索引源安装 webdriver 时出现了问题

问题如下: WARNING: The repository located at pypi.doubanio.com is not a trusted or secure host and is being ignored. If this repository is available via HTTPS we recommend you use HTTPS instead, otherwise you may silence this warning and allow …

ElasticSearch备考 -- 异步检索

一、题目 通过异步方式查询earthquakes索引下Magnitude大于5的数据 二、思考 正常的查询大家可能会用的多一点,这种异步查询为了可以数据量量比较大的查询在后台执行,不用同步等待结果,待执行完成在获取结果。 三、解题 Step 1、准备基础数…

【深度强化学习基础】(一)基本概念

【深度强化学习基础】(一)基本概念 一、概率论基础知识二、强化学习领域术语三、强化学习中两个随机性的来源:四、rewards以及returns五、Value Functions1.Action-Value Function Q π ( s , a ) Q_\pi(s,a) Qπ​(s,a)1.State-Value Funct…

Yolov8改进WIoU,SIoU,EIoU,α-IoU

1,IOU原理部分 IoU(Intersection over Union)是一种在计算机视觉领域常用的性能评估指标,尤其在目标检测和图像分割任务中。它通过计算预测边界框(预测框)与真实边界框(真实框)之间的交集面积与并集面积之比来衡量预测的准确性。IoU的值越接近1,表示预测框与真实框的重…

Error while loading conda entry point: conda-libmamba-solver

问题 解决方法 conda install --solverclassic conda-forge::conda-libmamba-solver conda-forge::libmamba conda-forge::libmambapy conda-forge::libarchive

C0015.Clion中开发C++时,连接Mysql数据库方法

安装mysql数据库 CMakeLists.txt中配置mysql数据库 # 先指定mysql数据库的安装位置 include_directories("C:/Program Files/MySQL/MySQL Server 8.0/include") link_directories("C:/Program Files/MySQL/MySQL Server 8.0/lib") link_libraries(libmysq…

Python | 使用Seaborn绘制KDE核密度估计曲线

核密度估计(KDE)图,一种可视化技术,提供连续变量概率密度的详细视图。在本文中,我们将使用Iris Dataset和KDE Plot来可视化数据集。 什么是KDE图? KDE图,全称核密度估计图(Kernel Density Est…

智慧农业案例 (二)- 智能化灌溉系统

橙蜂智能公司致力于提供先进的人工智能和物联网解决方案,帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、领域知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能&…