名称空间(namespaces)与作用域

引入

在python解释器中运行一行代码import this就可以看到“传说”中的python之禅,它体现了使用python进行开发的规范,而最后一句 - Namespaces are one honking great idea -- let's do more of those!就是本文的主角。

名称空间(Namespaces)

名称空间就是存放名字与对象绑定关系的地方,是对栈区的划分。定义一个变量。name = 'python',解释器会申请内存空间存放值'python',将名字name与'python'的内存地址的绑定关系存在栈区中。

有了名称空间之后就可以在栈区中存放相同的名字,在程序执行期间最多会存在三种名称空间,每种名称空间相互独立。

内置名称空间(built-in)

存放的是python解释器内置的名字,比如python中的保留字(关键字)。python解释器启动时内置名称空间就会产生,python解释器关闭,则销毁。

# 在交互式的解释器环境中输入print然后回车
>>> print
<built-in function print>

全局名称空间

只要不是函数内定义也不是内置的名字,剩下的全部都是全局名称。全局名称空间在运行python文件时产生,python文件执行完成之后销毁。

x = 1  # x是全局名称
def func():  # func是全局名称
    print(x)  # print是内置名称

局部名称空间

函数内定义的名字都会被存放在局部名称空间。局部名称空间在调用函数时产生,函数运行完毕后销毁。

def func():  # func全局名称
    x = 100  # x局部名称
    print(x)  # print内置名称 

名称空间与作用域

名称空间的加载顺序是:内置名称空间->全局名称空间->局部名称空间。

名称空间销毁顺序是:局部名称空间->全局名称空间->内置名称空间。

按照名称空间中名字的作用范围可以将三种名称空间划分为两个区域。

全局作用域---全局名称空间、内置名称空间中的名字属于全局作用域,全局作用域中的名字在整个文件执行过程中都不会被销毁,在任意位置都可以使用。

局部作用域---位于局部名称空间中的名字属于局部作用域,局部作用域中的名字在函数调用时产生,调用结束时销毁,只能在函数内使用。

作用域与名字查找优先级

名字顺序的查找需要记住一条准则:名字的查找顺序以函数阶段为准,与调用阶段没有关系。

  • 从局部作用域开始

在局部作用域查找名字,起始位置是局部作用域,现在局部名称空间中查找,找不到再去全局作用域查找,先查找全局名称空间,找不到再去内置名称空间,最后都找不到会抛出异常。

  • 从全局作用域开始

在全局作用域查找名字时,起始位置就是全局作用域,先查找全局名称空间,找不到再去内置名称空间,最后都找不到会抛出异常。

  • 名称空间的“嵌套关系”

这里的嵌套可以理解为不同的名称空间都存在同样的变量名,注意:一定要以函数定义阶段为准,并且牢记名称空间的查找顺序。

global & nonlocal

如果想要在函数内修改全局名称空间中名字的值并且该值是不可变数据类型,需要用到global关键字,如果该值是可变数据类型,则无需使用global,可以直接对原值进行修改。

x = 100
l = [1, 2]
def func():
    global x  # 声明x是全局名称空间的名字
    x = 101
    l.append(3)
func()
print(x)  # 101
print(l)  # [1, 2, 3]

对于嵌套多层的函数,可以使用nonlocal关键字对外层嵌套函数定义的名字进行声明并修改其值。nonlocal会从当前函数的外层函数一层一层去查找声明的名字,如果在最外层函数的名称空间中找不到该名字,会抛出异常。

def func():
    x = 10
    def func1():
        nonlocal x  
        x = 11
    func1()  # 修改func作用域中x的值
    print(x)  # 在func作用域中查看x的值
func()  # 11

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Protobuf: 高效数据传输的秘密武器

当涉及到网络通信和数据存储时&#xff0c;数据序列化一直都是一个重要的话题&#xff1b;特别是现在很多公司都在推行微服务&#xff0c;数据序列化更是重中之重&#xff0c;通常会选择使用 JSON 作为数据交换格式&#xff0c;且 JSON 已经成为业界的主流。但是 Google 这么大…

聊聊并发编程的12种业务场景

前言 并发编程是一项非常重要的技术&#xff0c;无论在面试&#xff0c;还是工作中出现的频率非常高。 并发编程说白了就是多线程编程&#xff0c;但多线程一定比单线程效率更高&#xff1f; 答&#xff1a;不一定&#xff0c;要看具体业务场景。 毕竟如果使用了多线程&…

fbx sdk的使用介绍

我们平时需要围绕fbx写一些小工具&#xff0c;虽说使用ascii格式的fbx可以直接进行字符串解析&#xff0c;并且网上也有一些基于ascii解析的开源库&#xff0c;但在制作一些通用的工具时&#xff0c;使用fbx sdk进行编写肯定是最好的。 1.下载fbx sdk和cmake 要用cmake生成vi…

bash简单常见用法

bash新建自定义数组 myArray() for ((i 0 ; i < 5 ; i )) do myArray[$i]"AAAA{$i}DD" done echo ${myArray[]} #输出结果是AAAA{0}DD AAAA{1}DD AAAA{2}DD AAAA{3}DD AAAA{4}DD 提取文件名成功 projects"D:/Project/Program/IDEAWorkspace/myauto/automati…

Python程序员辞职后,如何踏出自由职业的第一步,聊聊我自己的看法

大家好&#xff0c;我是兴哥。有个广州的朋友说他辞职了&#xff0c;想要自由职业该怎么开始第一步呢&#xff1f;我问他你之前的收入月薪是多少&#xff0c;他说2万出头。我不得不说&#xff0c;对于写项目的自由职业程序员&#xff0c;2万是一个极高的门槛。但既然他已经辞职…

淘宝拍立淘多码识别方案总结

本文通过拆解原始问题、发散思路优化等方式&#xff0c;记录了扫一扫从单码到多码识别的技术框架改造及多码识别率优化方案。其中涉及解码SDK的能力、码处理技术链路、码转换算法、降低漏检率策略等设计与实现。 背景与挑战 多码即在同一个界面中同时存在多个条码或二维码&…

Node.js 与 WebAssembly

目录 1、简介 2、关键概念 3、生成WebAssembly模块 4、如何使用它 5、与操作系统交互 1、简介 首先&#xff0c;让我们了解为什么WebAssembly是一个很棒的工具&#xff0c;并学会自己使用它。 WebAssembly是一种类似汇编的高性能语言&#xff0c;可以从各种语言编译&…

从零开始的强化学习入门学习路线

强化学习是机器学习领域中的一个分支&#xff0c;它是指智能体通过与环境的交互来学习如何采取最佳行动以最大化奖励信号的过程。强化学习在许多领域都有广泛的应用&#xff0c;如游戏、自动驾驶和机器人控制等。如果你对强化学习感兴趣&#xff0c;下面是一个入门强化学习的学…

【分布式锁】Redisson分布式锁的使用(推荐使用)

文章目录 前言一、常见分布式锁方案对比二、分布式锁需满足四个条件三、什么是Redisson?官网和官方文档Redisson使用 四、Redisson 分布式重入锁用法Redisson 支持单点模式、主从模式、哨兵模式、集群模式自己先思考下,如果要手写一个分布式锁组件&#xff0c;怎么做&#xff…

数据备份系列:Rsync 备份实战记录(二)

一、Rsync Cron 场景使用 在对数据备份要求实时性不高的情况下&#xff0c;可优先考虑该场景&#xff0c;选择一个合适的时间&#xff0c;对数据进行定时远程增量同步。 在《数据备份系列&#xff1a;Rsync 备份详解&#xff08;一&#xff09;》中我们已经对服务搭建以及远程…

鸿蒙学习总结

控件 button 源码所在路径&#xff0c;小编也只是猜测&#xff0c;还没搞懂鸿蒙上层app到底层的玩法&#xff0c;网上也没相关资料&#xff0c;找源码真是费劲(不是简单的下载个源码的压缩包&#xff0c;而是找到里面的控件比如Button&#xff0c;或者UIAbility实现的源码&…

基于python语言dlib库和opencv库的视频眨眼检测

功能说明&#xff1a; 基于python编程语言&#xff0c;使用dlib 和opencv开发的视频眨眼检测。 环境&#xff1a; * python 3.6.8 * opencv 3.4.2.16 * dlib 19.7.0 原理&#xff1a; 1.使用opencv-python读取处理视频图像 2.使用线程机制处理人脸检测关键点 3.根…

elk生命周期删除日志

elk版本&#xff1a;7.14 一、简介 ELK日志我们一般都是按天存储&#xff0c;例如索引名为"prodlog-2023-05-08"&#xff0c;因为日志量所占的存储是非常大的&#xff0c;我们不能一直保存&#xff0c;而是要定期清理旧的&#xff0c;这里就以保留7天日志为例。 自…

UDP通信机制详解

欢迎关注博主 Mindtechnist 或加入【Linux C/C/Python社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和…

opencv_c++学习(五)

Mat类数值存储方式 上图为opencv中三通道数据的存储方式&#xff0c;反映到图像上则为空间维度为3*3&#xff0c;通道为3的图像。 Mat类的属性 Mat类的属性如上&#xff0c;在这里我们解释一下step。step是行列数与数据类型的字节数相乘的数据。 Mat类元素读取 在Mat中&…

[GFCTF 2021] day2

Baby_Web 查看源码发现 <!--源码藏在上层目录xxx.php.txt里面&#xff0c;但你怎么才能看到它呢?--> 然后抓包看中间件&#xff0c;Apache/2.4.49 (Unix) 存在目录穿越漏洞 curl http://node4.anna.nssctf.cn:28805/cgi-bin/.%2e/.%2e/.%2e/.%2e/var/www/index …

Linux LED 驱动开发实验

1、LED 灯驱动原理 Linux 下的任何外设驱动&#xff0c;最终都是要配置相应的硬件寄存器。LED 灯驱动最 终也是对 I.MX6ULL 的 IO 口进行配置&#xff0c;在 Linux 下编写驱动要符合 Linux 的驱动框架。I.MX6U-ALPHA 开发板上的 LED 连接到 I.MX6ULL 的 GPIO1_IO03 这个引脚上&…

一起Talk Android吧(第五百四十二回:无进度值ProgressBar)

文章目录 概念介绍使用资源文件实现使用默认设置修改风格使用动画资源 使用代码实现经验总结 各位看官们大家好&#xff0c;上一回中咱们说的例子是"ProgressBar总结",本章回中介绍的例子是" 无进度值ProgressBar"。闲话休提&#xff0c;言归正转&#xf…

基于磁盘的Kafka为什么这么快

基于磁盘的Kafka为什么这么快 原创 Wyman 大数据技术架构 2019-05-23 18:04 Kafka是大数据领域无处不在的消息中间件&#xff0c;目前广泛使用在企业内部的实时数据管道&#xff0c;并帮助企业构建自己的流计算应用程序。Kafka虽然是基于磁盘做的数据存储&#xff0c;但却具有…

从FPGA说起的深度学习(九)- 优化最终章

这是新的系列教程&#xff0c;在本教程中&#xff0c;我们将介绍使用 FPGA 实现深度学习的技术&#xff0c;深度学习是近年来人工智能领域的热门话题。 在本教程中&#xff0c;旨在加深对深度学习和 FPGA 的理解。 用 C/C 编写深度学习推理代码高级综合 (HLS) 将 C/C 代码转换为…