python的作用域问题

article/2025/11/6 21:08:21

命名空间

python中的namespace (命名空间)是映射到对象的名称。

命名空间的几个常见示例: abs() 函数、内置异常等的内置函数集合;模块中的全局名称;函数调用中的局部名称。对象的属性集合也算是一种命名空间。关于命名空间的一个重要知识点是,不同命名空间中的名称之间绝对没有关系;例如,两个不同的模块都可以定义 maximize 函数,且不会造成混淆。用户使用函数时必须要在函数名前面附加上模块名。

点号之后的名称是属性。例如,表达式 z.real 中,real 是对象 z 的属性。严格来说,对模块中名称的引用是属性引用:表达式 modname.funcname 中,modname 是模块对象,funcname 是模块的属性。模块属性和模块中定义的全局名称之间存在直接的映射:它们共享相同的命名空间。

命名空间是在不同时刻创建的,且拥有不同的生命周期。内置名称的命名空间是在 Python 解释器启动时创建的,永远不会被删除。模块的全局命名空间在读取模块定义时创建;通常,模块的命名空间也会持续到解释器退出。

函数的本地命名空间在调用该函数时创建,并在函数返回或抛出不在函数内部处理的错误时被删除。 (实际上,用“遗忘”来描述实际发生的情况会更好一些。) 当然,每次递归调用都会有自己的本地命名空间)

作用域

作用域是命名空间可直接访问的 Python 程序的文本区域。 “可直接访问” 的意思是,对名称的非限定引用会在命名空间中查找名称。

python的作用域有以下几种:

作用域虽然是静态确定的,但会被动态使用。执行期间的任何时刻,都会有 3 或 4 个命名空间可被直接访问的嵌套作用域:

  • 最内层作用域,包含局部名称,并首先在其中进行搜索

  • 封闭函数的作用域,包含非局部名称和非全局名称,从最近的封闭作用域开始搜索

  • 倒数第二个作用域,包含当前模块的全局名称

  • 最外层的作用域,包含内置名称的命名空间,最后搜索

如果把名称声明为全局变量,则所有引用和赋值将直接指向包含该模块的全局名称的中间作用域。重新绑定在最内层作用域以外找到的变量,使用 nonlocal 语句把该变量声明为非局部变量。未声明为非局部变量的变量是只读的,(写入只读变量会在最内层作用域中创建一个新的局部变量,而同名的外部变量保持不变。)

通常,当前局部作用域将(按字面文本)引用当前函数的局部名称。在函数之外,局部作用域引用与全局作用域一致的命名空间:模块的命名空间。 类定义在局部命名空间内再放置另一个命名空间。

Python 有一个特殊规定。**如果不存在生效的 global 或 nonlocal 语句,则对名称的赋值总是会进入最内层作用域。**赋值不会复制数据,只是将名称绑定到对象。删除也是如此:语句 del x 从局部作用域引用的命名空间中移除对 x 的绑定。所有引入新名称的操作都是使用局部作用域:尤其是 import 语句和函数定义会在局部作用域中绑定模块或函数名称。

global 语句用于表明特定变量在全局作用域里,并应在全局作用域中重新绑定nonlocal 语句表明特定变量在外层作用域中,并应在外层作用域中重新绑定。

下例演示了如何引用不同作用域和名称空间,以及 global 和 nonlocal 对变量绑定的影响:

def scope_test():def do_local():spam = "local spam"def do_nonlocal():nonlocal spamspam = "nonlocal spam"def do_global():global spamspam = "global spam"spam = "test spam"do_local()print("After local assignment:", spam)do_nonlocal()print("After nonlocal assignment:", spam)do_global()print("After global assignment:", spam)scope_test()
print("In global scope:", spam)

结果输出如下:

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

注意,局部 赋值(这是默认状态)不会改变 scope_test 对 spam 的绑定。 nonlocal 赋值会改变 scope_test 对 spam 的绑定,而 global 赋值会改变模块层级的绑定。而且,global 赋值前没有 spam 的绑定。

参考官方文档:https://docs.python.org/zh-cn/3/tutorial/classes.html#python-scopes-and-namespaces

上面的内容有些晦涩难懂,其实理解下来就是,python中的命名空间可以映射到python中定义的对象,而作用域是某个命名空间对应的可直接访问的Python 程序的文本区域。对于某个命名空间,它一般对应一个作用域,在这个作用域中可以直接访问包含的对象。

一段python程序执行期间都有 3 或 4 个命名空间及可被直接访问的嵌套作用域:
比如对于上述的那个例子中,包含全局作用域、scope_test对应的作用域、do_local对应的作用域,对于do_local在其内层绑定spam,do_nonlocal由于其内部指定了nonlocal ,表明特定变量在外层作用域中,故在绑定spam时会去上一层作用域寻找并绑定,而do_global由于其内部指定了global,表明特定变量在全局作用域里,会在全局作用域中绑定,此时全局作用域中并包含该对象,此时会在全局作用域中创建该对象,并绑定。

4种作用域

L (Local) 局部作用域
E (Enclosing) 闭包函数外的函数中
G (Global) 全局作用域
B (Built-in) 内建作用域 以 L –> E –> G –>B 的规则查找,即:在局部找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再者去内建中找。

根据 Python 访问局部变量和全局变量的规则:当搜索一个变量的时候,Python 先从局部作用域开始搜索,如果在局部作用域没有找到那个变量,那样 Python 就会像上面的介绍的作用域范围逐层寻找,如果找不到则抛出 UnboundLocalError 异常。

虽然在内部能够找到外部的变量,但是未声明为非局部变量的变量是只读的,(写入只读变量会在最内层作用域中创建一个新的局部变量,而同名的外部变量保持不变。),所以此时nonlocal以及global关键字的用处来了,只有声明某个变量在全局作用域或者外层作用域,才能够对这个变量进行修改。
在这里插入图片描述

参考:
https://zhuanlan.zhihu.com/p/111284408
https://docs.python.org/zh-cn/3/tutorial/classes.html#python-scopes-and-namespaces


http://chatgpt.dhexx.cn/article/L9vb8q8J.shtml

相关文章

实用解决Python作用域问题

前言:一直以来对Python的作用域问题有很多的疑惑,看了很多大牛的讲解之后有所收获,所以就记录下来 1、块级作用域 想想此时运行下面的程序会有输出吗?执行会成功吗? 1 2 3 4 5 6 7 8 9 10 11 12 #块级作用域 if 1…

python变量的作用域

作用域又可以被称为命名空间,指变量起作用的范围。Python变量作用域可以分为四种,分别为局部作用域、嵌套作用域、全局作用域、内置作用域。 作用域英文简写局部作用域LocalL嵌套作用域EnclosedE全局作用域GlobalG内置作用域Built-inB 四种作用域中变量…

linux-虚拟化管理工具

一、虚拟化管理工具 1.虚拟机的安装 用图形方式进行虚拟机的安装 安装镜像 设置虚拟机名字和占用内存大小 2.虚拟机的脚本安装 vim /bin/vm_create.sh 建立在/sbin目录底下,方便以后使用 #!/bin/bash ##幻数,脚本中命令…

常用虚拟机软件推荐

很多时候,由于工作的需要,都需要在不同的系统环境中进行调试开发,要么自己有多台电脑,安装不同的系统,要么给电脑装多系统。但这些都不是很现实,前者要资金,后者想进行系统切换也够费劲的了&…

理解全虚拟、半虚拟以及硬件辅助的虚拟化

接触过的一些搞了几年云计算的童鞋,也没明白常见的几种虚拟机技术方案的异同,比如只是记住了半虚拟要在虚拟机装驱动而全虚拟不需要,也不知道有时候为什么需要打开BIOS里的VT项。本人呢,在看了各种讲解虚拟化的书籍之后&#xff0…

虚拟化(二):虚拟化及vmware workstation产品使用

虚拟化(一):虚拟化及vmware产品介绍 vmware workstation的最新版本是10.0.2。相信大家也都使用过,其中的简单的虚拟机的创建,删除等,都很简单,这里就不再详细说明了,下面我将简单介绍…

什么是虚拟化?

什么是虚拟化? “虚拟化“这个词只要是接触过计算机和网络的,或多或少都有听过。什么虚拟机、存储虚拟化、网络虚拟化、网络功能虚拟化(NFV)、虚拟资源池……今天从什么是虚拟化讲起。 什么是虚拟化 由于虚拟化在各种企业的技术…

虚拟化管理工具的安装与使用

虚拟化管理工具的安装与使用 Libvirt是一个软件的集合,包括API库,后台运行程序(Libvirtd)和命令行工具(virsh)。 Libvirt主要有下面3个功能: 1 虚拟机管理:以虚拟机为对象,Libvirt提供了定义,删除&#x…

开源虚拟化工具VirtualBox安装部署

什么是Virtualbox VirtualBox是一款由Oracle开发和维护的免费开源虚拟化软件,用于在一台计算机上创建和管理多个虚拟机。它允许用户在单个物理计算机上运行多个操作系统,例如Windows、Linux、macOS等。VirtualBox提供了一个虚拟化环境,使用户…

虚拟机的虚拟化如何开启?

大家可以在任务管理器-性能中,查看“虚拟化”是【已启用】还是【已禁用】。如果是禁用了,可以接着往下看我们如何开启虚拟化。 1、关闭电脑的快速启动 控制面板-电源选项-选择电源按钮的功能-更改当前不可用的设置;把关机设置中的【所有都取…

kvm虚拟化管理工具

kvm虚拟化管理工具 一、什么是云计算?二、云计算的基础KVM虚拟化三、安装kvm虚拟化管理工具四、virsh虚拟机的日常操作(开关,挂起虚拟机,导配置文件,磁盘增容,转化磁盘格式等)五、快照管理六、KVM虚拟机的克…

有哪些虚拟化和容器化工具推荐? - 易智编译EaseEditing

以下是几个常用的虚拟化和容器化工具推荐: VMware vSphere: VMware vSphere 是一套完整的虚拟化平台,包括虚拟化服务器、虚拟化存储和虚拟化网络。 它提供了高性能的虚拟机管理和资源调度功能,适用于企业级的虚拟化部署。 Docke…

KVM虚拟化工具简介及安装

文章目录 1. KVM简介2. 安装前提3. KVM安装4. KVM启用5. 虚拟机安装和设置 1. KVM简介 Kernel-based Virtual Machine的简称,是一个开源的系统虚拟化模块,自Linux2.6.20之后集成在Linux的各个主要发行版本中。它使用Linux自身的调度器进行管理&#xff…

虚拟化工具介绍 (资源)

2019独角兽企业重金招聘Python工程师标准>>> 常见的虚拟化产品:docker、Hyper-V、VMware、VirtualBox、XenServer、Kvm、Qemu、OpenVZ、Xen、CloudStack、Openstack、云计算、云其他。 常见的虚拟化 技术 :ESXI、XEN、KVM、HP-V、Docker、Virtual-BOX, 使用最广泛…

AppScan 10中文版

教程: 1、下载解压缩,得到获得AppScan10中文版原程序; 2、首先双击“AppScan_Setup_10.0.0.exe”开始安装,选择简体中文; 3、勾选“我接受许可协议中的全部条款”,然后继续安装; 4、选择软件安…

安全测试工具APPScan下载安装及简单使用

一、安装 百度随便找了个网址下的,解压后如图:AppScan_Std_9.0.3.7_Eval_Win.exe是安装程序,LicenseProvider.dll是替换文件。安装包600多MB建议硬盘留存避免重复下载。 安装简单,注意修改下安装路径,另外会弹出提示是…

AppScan

AppScan是用于web项目的安全测试工具,扫描网站所有url(自动手动),自动测试是否存在各种类型的漏洞。 使用步骤 选择记录 就会弹出appscan自带的浏览器,在其中输入账号密码,appscan就会自动记录 点击下一步…

Appscan测试工具简介

具用途? IBM公司的web扫描工具,对网站等WEB应用进行自动化的应用安全扫描和测试。 如何工作? 探索(Explore):在探索阶段,Appscan试图遍历网站中所有可用的链接,并建立一个层次结构。它发出请求,并根据响…

AppScan9.0

IBM近日发布了最新的Web 安全扫描器Appscan 9.0 ,个人认为是目前商业扫描器中做的最好的,新的版本中增加了许多有用有的新特性,包括如下: .NET 服务器的 glass box 扫描 除了 Java 服务器之外,现在还可以在 .NET 服务…

appscan如何扫描移动应用APP

众所周知,appscan是一款企业级应用安全漏洞扫描神器,appscan怎么扫描移动应用(也就是我们常说的APP)。在此记录一下 Appscan扫描web应用时一般采用自动探索扫描和手动探索扫描两种方式,具体操作可以详见我CSDN另外一篇…