python中的局部变量、全局变量问题的思考(对比于c语言)

 

今天在运行python时遇到了局部变量和全局变量的问题,令我很迷惑。

首先,我在学习python之前先学习了c语言,所以c语言的一些东西影响了我对这个问题的思考。

在c语言中

局部变量和全局变量的区别就在于作用域的范围大小。在c语言中,我们认为定义在函数内部循环体(for语句、while语句)和if语句内部的变量为局部变量,除此之外定义的变量称之为全局变量。

78b2e0a72d824fa4a03147514ce2efa6.png

在if语句内部定义变量,在if语句外面输出

在上图中,我在if语句内部定义了一个n整数变量,在if语句外面输出,编辑器会给予我报警提示。

6462a096989643feabee6cb5e79abdf2.png

同理,换成函数或循环体是一样的。

在python中

我想这两种语言在这个方面应该保持一致吧?结果问题出现了。

8318540b79234a36adddd2b8036e8c97.png

同样的程序换成了python却出现了结果,答案为2。这是为何呢?

经过查阅资料,我发现网上很多都说不应该输出值,应该报错。

比如:Python Python if条件语句中的变量作用域|极客教程

f52114e88c5647459f56b0b929ca5e58.png

上面显示在if外边输出会报错,但实际运行并不会。

所以我重新思考了一番:认为python的局部变量并不同于c语言。仅仅是在def(也就是函数)内部定义变量才是局部变量(当然不使用global关键字),在函数外部定义是全局变量。

像我在本节开头提到的那个程序,先在if内部定义了一个n,然后自加,接着在if外部输出,这种定义的统统按照全局变量处理。所以才会在结果中输出2。

同样,我也找到了一些相同看法的人。例如这位阿常呓语博主:python3中 for 循环中循环变量的作用域问题_python for循环变量作用域-CSDN博客

在python中,当你在函数外部定义变量时,认为是同一级别的作用域,统一按照全局变量处理。

重新审视python的全局变量与局部变量

在得到上述结论后,来重新审视一下全局变量和局部变量。这里引用了上文提到的阿常呓语博主的文章中的一些例子。

例子一

num = 10000000
print(f"module num:{num}")

def visit_num():
    print(f"visit num:{num}")

if __name__ == '__main__':
    visit_num()
    print(f"main num:{num}")

结果:

module num:10000000
visit num:10000000
main num:10000000

解释:全局变量的作用范围是整个文件。所以输出都是一样的。

例子二

num = 10000000
print(f"module num:{num}")

def visit_num():
    num = 0
    print(f"visit num:{num}")

if __name__ == '__main__':
    visit_num()
    print(f"main num:{num}")

结果:

module num:10000000
visit num:0
main num:10000000

解释:首先定义的num是在函数外部,所以是全局变量。然后定义了visit_num函数,内部定义了相同的变量num为0。最后调用函数,输出num。

这里要注意:只要是在函数内部定义的变量统统认为是局部变量。(除了global声明,例子四提到)所以内部定义的num虽然和外部的变量同名,但是两者并不是一回事。所以visit num为0,调用结束后局部变量就结束了它的生命。此时只有一个num变量,就是全局的num。所以最后的main num为10000000

例子三

如果我将例子二中函数内部的num=0和print(f"visit num:{num}")两行交换顺序会怎样呢?

num = 10000000
print(f"module num:{num}")

def visit_num():
    print(f"visit num:{num}")
    num=0

if __name__ == '__main__':
    visit_num()
    print(f"main num:{num}")

结果:报错

解释:在例子二中已经说过,只要是在函数内部定义的变量都是局部变量。所以调用visit_num函数时系统会首先检查这个函数中有没有定义num变量(这个检索是整个函数范围的,而不仅仅是此行之前的),如果没有那就输出全局的num变量,如果有就输出局部的num变量。显然,这个函数内部声明了局部的num变量了,但是在print语句之前我并不知道num变量是多少,所以会报错。换句话说,就是num“事后诸葛亮“了。

所以从这里可以得出一个结论,如果要声明局部变量,必须在函数开头(至少在输出之前,“开始检索”之前)就声明,否则就会报错。

例子四

在函数内部修改全局变量。

前面我们说过,函数内部定义的变量均为局部变量,但是有一个例外。如果函数内部使用了global关键字,那么这时修改的变量就是全局变量了。

num = 10000000
print(f"module num:{num}")

def visit_num():
    global num
    num=0
    print(f"visit num:{num}")

if __name__ == '__main__':
    visit_num()
    print(f"main num:{num}")

结果:

module num:10000000
visit num:0
main num:0

额外:也有人说列表中的循环变量是一个例外情况,其实不然。下面的这个问答可以解决此问题,

python的for循环变量为何不设置为局部变量?_编程语言-CSDN问答
 

a = 1
b = [1,2,3,4,5]
for a in b:
      c = 0
print(a)

这个其实在开始就说过了,python的全局变量和c不同。

分析这个代码:首先a为全局变量赋值为1,for a in b的理解是将b中的每一个值依次赋值给a,所以相当于每次赋值都修改了a这个全局变量,所以最后输出的a值为5. 

个人理解,如有错误,还请不吝赐教。

 

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

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

相关文章

进网许可认证、交换路由设备检测项目更新25年1月起

实施时间 2025年1月1日起实施 涉及设备范围 核心路由器、边缘路由器、以太网交换机、三层交换机、宽带网络接入服务器(BNAS) 新增检测依据 GBT41266-2022网络关键设备安全检测方法交换机设备 GBT41267-2022网络关键设备安全技术要求交换机设备 GB/…

文件,IO流

目录 一 java 1. IO流 1)输入输出(以程序的视角判断 ) 1.1 IO流的分类 1)字符流效率高于字节流 1.2 流和文件的关系 2. inputstream--字节输入流 2.1 fileinputstream 2.1.1常用方法: 1)单个字符…

pymssql-2.1.4.dev5-cp37-cp37m-win_amd64.whl 安装

pip install pymssql 安装pymssql出现下面的问题 error: Microsoft Visual C 14.0 is required. Get it with “Microsoft Visual C Build Tools”: http://landinghub.visualstudio.com/visual-cpp-build-tools 因为要使用python连接sqlserver数据库,需要pymssq…

vue中验证码的实现方式

在写登录页的时候有的系统会让你也进行一下验证码绘制,那么验证码如何实现的呢?我在写登录页的时候通过将登录框,验证码分开页面来写,最后将它们变成标签来导入到我的样式页面中,这样写不仅方便,更容易修改…

致远互联OA使用问题及解决方法记录(个人)

1、更换设备登录账号出现绑定要求 解决:后台管理员账号——M3安全管理——安全设置——删除绑定 2、审批消息错误回退 解决:协同工作——一已办事项——取回——重新审批/流程监督里撤回/流程索道节点回退 3、签章图片在表单上显示过大 解决&#x…

《计算机组成及汇编语言原理》阅读笔记:p9-p27

《计算机组成及汇编语言原理》学习第 2 天,p9-p27 总结,总计 19 页。 一、技术总结 1.quantum physics(量子物理学) (1)quantum(量子) quantum的本意是:c. the smallest amount of sth(量子)。 In physics, a quantum is the minimum am…

java_章节作业

第1题 package com.hspedu.homework;/*** author:寰愬悏瓒�* date:2024/12/19 version:1.0*/ public class Homework01 {public static void main(String[] args) {//初始化Person对象数组,有3个Person对象;Person[] persons new Person[3];…

Audiocraft智能音频和音乐生成工具部署及使用

1、概述 Facebook开源了一款名为AudioCraft的AI音频和音乐生成工具。 该工具可以直接从文本描述和参考音乐生成高质量的音频和音乐。AudioCraft包含MusicGen、AudioGen和EnCodec三个模型,分别实现音乐生成、音频生成和自定义音频模型构建。 2、项目地址 https://…

华为云计算HCIE笔记02

第二章:华为云Stack规划设计 交付总流程 准备工作:了解客户的基本现场,并且对客户的需求有基本的认知。 HLD方案BOQ报价设备采购和设备上架 2.安装部署流程 硬件架构设计 硬件设备选配 设备上架与初始化配置 准备相关资料(自动下载…

StarRocks:存算一体模式部署

目录 一、StarRocks 简介 二、StarRocks 架构 2.1 存算一体 2.2 存算分离 三、前期准备 3.1前提条件 3.2 集群规划 3.3 配置环境 3.4 准备部署文件 四、手动部署 4.1 部署FE节点 4.2 部署BE节点 4.3 部署CN节点(可选) 4.4 FE高可用…

红米Note 9 Pro5G刷小米官方系统

前言 刷机有2种方式:线刷 和 卡刷。 线刷 线刷:需要用电脑刷机工具,例如:XiaoMiFlash.exe,通过电脑和数据线对设备进行刷机。 适用场景: 系统损坏无法开机。恢复官方出厂固件。刷机失败导致软砖、硬砖的…

关于Tomcat的一些关键参数

目录 Tomcat参数总览设置位置 参数分析Tomcat内部类maxConnections属性Tomcat内部类的acceptCountTomcat有几个Acceptor线程Tomcat的工作线程池 Tomcat参数总览 package org.springframework.boot.autoconfigure.web; /** * * {link ConfigurationProperties ConfigurationP…

网络安全核心目标CIA

网络安全的核心目标是为关键资产提供机密性(Confidentiality)、可用性(Availablity)、完整性(Integrity)。作为安全基础架构中的主要的安全目标和宗旨,机密性、可用性、完整性频频出现,被简称为CIA,也被成为你AIC,只是顺序不同而已…

HIPT论文阅读

题目《Scaling Vision Transformers to Gigapixel Images via Hierarchical Self-Supervised Learning》 论文地址:[2206.02647] Scaling Vision Transformers to Gigapixel Images via Hierarchical Self-Supervised Learning 项目地址:mahmoodlab/HI…

智能挂号系统设计典范:SSM 结合 Vue 在医院的应用实现

摘要 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了医院预约挂号系统的开发全过程。通过分析医院预约挂号系统管理的不足,创建了一个计算机管理医院预约挂号系统的方案。文章介绍了医院预约挂号系统的系…

Windows11 家庭版安装配置 Docker

1. 安装WSL WSL 是什么: WSL 是一个在 Windows 上运行 Linux 环境的轻量级工具,它可以让用户在 Windows 系统中运行 Linux 工具和应用程序。Docker 为什么需要 WSL: Docker 依赖 Linux 内核功能,WSL 2 提供了一个高性能、轻量级的…

【hackmyvm】Diophante 靶场

1. 基本信息^toc 这里写目录标题 1. 基本信息^toc2. 信息收集2.1. 端口扫描2.2. 目录扫描2.3. knock 3. WordPress利用3.1. wpscan扫描3.2. smtp上传后门 4. 提权4.1. 提权leonard用户4.2. LD劫持提权root 靶机链接 https://hackmyvm.eu/machines/machine.php?vmDiophante 作者…

OB删除1.5亿数据耗费2小时

目录 回顾:mysql是怎么删除数据的? 删除方案 代码实现 执行结果 结论 本篇是实际操作 批量处理数据以及线程池线程数设置 记录学习 背景:有一张用户标签表,存储数据量达4个亿,使用OceanBase存储,由于…

Qt:QMetaObject::connectSlotsByName实现信号槽自动关联

简介 在Qt中,QMetaObject::connectSlotsByName 是一个便利的方法,它可以根据对象的对象名(objectName)自动将信号和槽连接起来。但是,要使用这个方法,必须确保: 1 控件(如按钮&…

记录仪方案_记录仪安卓主板定制_音视频记录仪PCBA定制开发

记录仪主板采用了强大的联发科MTK8768处理器,拥有出色的性能表现。它搭载了四个主频为2.0GHz的Cortex-A53核心与四个主频为1.5GHz的Cortex-A53核心,确保了高效的处理速度。此外,主板配备了4GB的RAM(可选8GB),并且内置64GB的ROM(可…