【Python】新手入门:变量的作用域是什么?有哪几种作用域?作用域的查找顺序是什么?

news2024/9/22 10:07:17

【Python】新手入门:变量的作用域是什么?有哪几种作用域?作用域的查找顺序是什么?在这里插入图片描述

🌈 个人主页:高斯小哥
🔥 高质量专栏:Matplotlib之旅:零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程👈 希望得到您的订阅和支持~
💡 创作高质量博文(平均质量分92+),分享更多关于深度学习、PyTorch、Python领域的优质内容!(希望得到您的关注~)


🌵文章目录🌵

  • 💡一、变量的作用域是什么?
  • 📚二、变量的四种作用域
  • 🔧三、作用域的查找顺序
  • 💻四、实例演示和代码示例
  • 📚五、作用域与变量生命周期
  • 🚀六、举一反三:如何修改作用域中的变量
  • 📖七、总结与最佳实践
  • 🔥结语

💡一、变量的作用域是什么?

  在Python编程中,变量的作用域是一个非常重要的概念。简单来说,变量的作用域决定了变量在程序中的可见性和可访问性。换句话说,它决定了变量在哪些部分可以被引用和使用。

  变量的作用域可以分为四个级别:局部作用域、嵌套局部作用域、全局作用域和内置作用域。下面我们将详细解释这些作用域的概念和区别。

📚二、变量的四种作用域

  1. 局部作用域

    局部作用域也称为函数作用域,是变量在函数内部定义时的范围。在函数内部定义的变量只在该函数内部可见,当函数执行完毕后,这些变量就会被销毁。

    def my_function():
        local_var = "我在局部作用域内"
        print(local_var)
    
    my_function()  # 输出:我在局部作用域内
    # 尝试在函数外部访问 local_var 会导致 NameError
    # print(local_var)  # NameError: name 'local_var' is not defined
    
  2. 嵌套局部作用域

    嵌套局部作用域指的是在函数内部定义的另一个函数中的变量作用域。内部函数可以访问外部函数的局部变量,但外部函数无法直接访问内部函数的局部变量。

    def outer_function():
        outer_var = "我在外部函数作用域内"
        
        def inner_function():
            inner_var = "我在嵌套局部作用域内"
            print(outer_var)  # 可以访问外部函数的变量
            print(inner_var)
        
        inner_function()
    
    outer_function()  # 输出:我在外部函数作用域内,我在嵌套局部作用域内
    
  3. 全局作用域

    全局作用域是指在整个程序中都可见的变量作用域。在函数外部定义的变量属于全局作用域,它们可以在程序的任何地方被访问和修改(除非在函数内部被重新定义为局部变量)。

    global_var = "我在全局作用域内"
    
    def another_function():
        print(global_var)  # 可以访问全局变量
    
    another_function()  # 输出:我在全局作用域内
    
  4. 内置作用域

    内置作用域是Python解释器自带的变量作用域,它包含了所有内置函数和异常的名字。这些名字在程序任何地方都是可见的,但通常我们不会修改它们。

    例如,len()print()等内置函数就位于内置作用域中。

🔧三、作用域的查找顺序

  了解这四种作用域后,我们需要知道Python是如何在多个作用域中查找变量的。当我们在程序中引用一个变量时,Python会按照以下顺序进行查找:

  1. 局部作用域:首先在当前函数或方法内部查找变量。
  2. 嵌套局部作用域:如果当前函数内部还有嵌套函数,则继续在这些嵌套函数内部查找。
  3. 全局作用域:如果局部变量中未找到,则到全局变量中查找。
  4. 内置作用域:最后,如果全局变量中也未找到,则到内置作用域中查找。

这个查找顺序也被称为LEGB规则,即Local(局部)、Enclosing(嵌套局部)、Global(全局)、Built-in(内置)。

💻四、实例演示和代码示例

下面是一个综合了以上作用域的示例代码:

# 全局作用域
global_scope_var = "全局变量"

def outer_function():
    # 嵌套局部作用域(属于outer_function)
    nested_scope_var = "嵌套局部变量"
    
    def inner_function():
        # 局部作用域(属于inner_function)
        local_scope_var = "局部变量"
        
        # 访问嵌套局部作用域变量
        print(nested_scope_var)
        
        # 访问全局作用域变量
        print(global_scope_var)
        
        # 尝试访问内置作用域变量(例如len)
        print(len([1, 2, 3]))
        
        # 尝试访问不存在的变量会导致NameError
        # print(non_existent_var)  # NameError: name 'non_existent_var' is not defined
    
    inner_function()

outer_function()

📚五、作用域与变量生命周期

  变量的生命周期与其作用域紧密相关。局部变量在函数被调用时创建,在函数返回时销毁。全局变量在程序开始时创建,在程序结束时销毁。了解变量的生命周期对于管理内存和避免潜在的错误(如引用已销毁的局部变量)至关重要。

🚀六、举一反三:如何修改作用域中的变量

  在Python中,变量的作用域不仅限定了变量的可见性,还影响了我们如何修改这些变量的值。了解如何在不同作用域中修改变量是编程中的一项重要技能。

  1. 修改局部变量

    局部变量是在函数内部定义的,因此它们只能在函数内部被修改。一旦函数执行完毕,这些变量的值就会丢失。

    def modify_local_variable():
        local_var = 10
        local_var += 5  # 修改局部变量
        print(local_var)  # 输出:15
    
    modify_local_variable()
    
  2. 修改全局变量

    在函数内部,如果你想修改全局变量,你需要使用global关键字来声明这个变量是全局的。否则,Python会将其视为一个新的局部变量。

    global_var = 20
    
    def modify_global_variable():
        global global_var  # 声明变量是全局的
        global_var += 10  # 修改全局变量
        print(global_var)  # 输出:30
    
    modify_global_variable()
    print(global_var)  # 输出:30,全局变量已被修改
    
  3. 避免在函数内部修改全局变量

    虽然可以在函数内部修改全局变量,但这通常不是一个好的做法。因为它可能导致代码难以理解和维护。更好的做法是通过参数传递变量到函数中,并在函数内部返回修改后的值。

    def modify_and_return_value(var):
        var += 5
        return var
    
    global_var = 25
    global_var = modify_and_return_value(global_var)
    print(global_var)  # 输出:30
    
  4. 嵌套作用域中的变量修改

    在嵌套函数中,内部函数可以访问外部函数的变量,但通常不建议直接修改外部函数的变量,因为这可能导致意外的副作用。如果确实需要修改,可以通过返回值或其他机制来实现。

    def outer_function():
        outer_var = 100
        
        def inner_function():
            nonlocal outer_var  # 声明变量是非局部的(在Python 3中)
            outer_var += 20    # 修改嵌套作用域中的变量
            return outer_var
        
        return inner_function()
    
    result = outer_function()
    print(result)  # 输出:120
    

    在Python 3中,nonlocal关键字用于指示一个变量引用最近的外层作用域的变量,而不是全局变量。

📖七、总结与最佳实践

  理解变量的作用域是编写高质量Python代码的关键。不同的作用域规则允许我们组织代码,使其更加清晰、可维护,并减少潜在的错误。最佳实践包括:

  • 尽量避免在函数内部修改全局变量,而是通过参数和返回值来传递和修改数据。
  • 在嵌套函数中,如果需要修改外部函数的变量,使用nonlocal(在Python 3中)来明确声明变量的作用域。
  • 对于复杂的程序,可以考虑使用类和对象来封装数据和行为,以更好地管理变量的作用域和生命周期。

通过遵循这些最佳实践,你可以编写出更加健壮、可读的Python代码。

🔥结语

  在Python编程中,变量的作用域是一个核心概念,它决定了变量在程序中的可见性和生命周期。通过理解局部作用域、全局作用域和内置作用域,以及如何在不同作用域中修改变量,你可以编写出更加高效、可维护的代码。希望这篇文章能够帮助你深入理解Python变量的作用域,并在实际编程中加以应用。如果你有任何疑问或建议,请随时在评论区留言,我们会尽快回复!

关键词: Python、变量作用域、局部变量、全局变量、内置变量、LEGB规则、作用域修改、最佳实践

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

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

相关文章

Django添加app

Django添加App python manage.py startapp [app_name]快速上手 注册app,setting.py 编写url和视图的对应关系 添加视图函数 命令行启动 python manage.py runserver页面模板

循序渐进丨MogDB 数据库新特性之SQL PATCH绑定执行计划

1 SQL PATCH 熟悉 Oracle 的DBA都知道,生产系统出现性能问题时,往往是SQL走错了执行计划,紧急情况下,无法及时修改应用代码,DBA可以采用多种方式针对于某类SQL进行执行计划绑定,比如SQL Profile、SPM、SQL …

详解前端登录流程:实现原理与最佳实践

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

考研复习C语言初阶(3)

目录 一.函数是什么? 二.C语言中函数的分类 2.1库函数 2.2自定义函数 三.函数的参数 3.1实际参数(实参) 3.2 形式参数(形参) 四.函数的调用 4.1 传值调用 4.2 传址调用 五. 函数的嵌套调用和链式访问 5.1 嵌套调用 5…

使用Python编写简单学生管理系统

学完python基础,把学过的知识运用起来做一个简单的学生管理系统 1、需求分析 需求:进入系统显示系统功能界面,功能如下: ① 添加学员信息 ② 删除学员信息 ③ 修改学员信息 ④ 查询学员信息(只查询某个学员) ⑤ 遍历所有学…

专家院士共同参编的《数字空间共同体白皮书》正式启动

数字产业化、产业数字化,促进数字技术和实体经济深度融合,成为数字经济高质量发展的重要路径。数字空间与物理空间双向融合,用数字技术提升企业有限资源的有效配置,构建经济双空间增长模式,是形成企业新质生产力的关键…

JVM基本概念、命令、参数、GC日志总结

原文: 赵侠客 一、前言 NPE(NullPointerException)和OOM(OutofMemoryError)在JAVA程序员中扮演着重要的角色,它也是很多人始终摆脱不掉的梦魇,与NPE不同的是OOM一旦在生产环境中出现就意味着只靠代码已经无…

鸿蒙App语法/结构/注意

注意 默认情况下,应用只能访问有限的系统资源。其他资源权限处理https://developer.harmonyos.com/cn/docs/documentation/doc-guides-V3/accesstoken-overview-0000001544703857-V3 .1、权限申请使用流程 https://developer.harmonyos.com/cn/docs/documentatio…

【REST2SQL】12 REST2SQL增加Token生成和验证

【REST2SQL】01RDB关系型数据库REST初设计 【REST2SQL】02 GO连接Oracle数据库 【REST2SQL】03 GO读取JSON文件 【REST2SQL】04 REST2SQL第一版Oracle版实现 【REST2SQL】05 GO 操作 达梦 数据库 【REST2SQL】06 GO 跨包接口重构代码 【REST2SQL】07 GO 操作 Mysql 数据库 【RE…

poetry库:依赖管理和打包工具

这个工具是在群里看见别人说好用的,所以了解一下。 1.poetry初始 官网:https://python-poetry.org/ 项目仓库:https://github.com/python-poetry 或 https://github.com/python-poetry/poetry 教程:https://python-poetry.org/…

Day01-项目介绍及初始化-登录页面(test)

1.人力资源项目介绍 1.1 项目架构和解决方案 1.2 课程安排 1.3 课程具备能力 1.4 课程地址 vue-element-admin文档地址:链接演示地址: 链接人力资源项目演示地址: 链接 2. 拉取项目基础代码 拉取命令 $ git clone https://github.com/P…

河北专升本(C语言编程题)

一:基础算法原理 1. 冒泡排序 原理:从左到右,相邻元素进行比较。每次比较一轮,就会找到序列中最大的一个或最小的一个。这个数就会从序列的最右边冒出来。 以从小到大排序为例,第一轮比较后,所有数中最大的…

【设计】基于web的会员管理系统

1、引言 设计结课作业,课程设计无处下手,网页要求的总数量太多?没有合适的模板?数据库,java,python,vue,html作业复杂工程量过大?毕设毫无头绪等等一系列问题。你想要解决的问题&am…

云计算项目九:K8S安装

K8S安装 Kube-master安装 按照如下配置准备云主机 防火墙相关配置:禁用selinux,禁用swap,且在firewalld-*。上传kubernetes.zip 到跳板机 配置yum仓库(跳板机) 跳板机主机配置k8s软件源服务端 [rootjs ~]# yum -y…

仿射变换下的点位纠偏

点位偏差一直是一个很头疼的问题,但是由于摄像头和实际环境的局限性,我们不得不面对这个问题。对此,使用判别的方式进行一个仿射变换,是一种非常有效的方式,下图中图1是基准图,图2是目标图,图3是…

使用CSS制作动态的环形图/饼图

使用纯 CSS Animation conic-gradient 实现一个环形图。 饼图的实现思路和环形图一样&#xff0c;去掉中间的圆形遮盖 after 伪类元素即可。 一、构建基础样式 构建圆形节点和中间的遮盖元素。 <style>body {background-color: rgb(130, 226, 255);}.circle {top: 16…

GIS之深度学习08:安装GPU环境下的pytorch

环境&#xff1a; cuda&#xff1a;12.1.1 cudnn&#xff1a;12.x pytorch&#xff1a;2.2.0 torchvision&#xff1a;0.17.0 Python&#xff1a;3.8 操作系统&#xff1a;win &#xff08;本文安装一半才发现pytorch与cuda未对应&#xff0c;重新安装了cuda后才开始的&a…

时间服务器

目录 软件介绍 软件安装 准备工作 设置当前时区 修改chronyd配置文件 设置允许哪个客户端可以访问该服务器 设置本地服务器时间为第10层级 时钟层&#xff1a; 实例:配置时间服务器客户端服务端 Serves Client 配置环境&#xff1a; systemctl命令 lsof 命令 语法 选项 lsof输…

JL15-80/11电流继电器 过电流瞬时动作 电磁式结构 80A 一开一闭

JL15电流继电器 系列型号 JL15-1.5/11电流继电器JL15-2.5/11电流继电器 JL15-5/11电流继电器JL15-10/11电流继电器 JL15-15/11电流继电器JL15-20/11电流继电器 JL15-30/11电流继电器JL15-40/11电流继电器 JL15-60/11电流继电器JL15-80/11电流继电器 JL15-100/11电流继电器JL15…

mac本地启动sentinel

启动Sentinel控制台 1&#xff09;下载sentinel控制台jar包 https://github.com/alibaba/Sentinel/releases/download/1.8.6/sentinel-dashboard-1.8.6.jar 2&#xff09;启动sentinel控制台 使用如下命令启动控制台&#xff1a; java -Dserver.port8080 -Dcsp.sentinel.d…