Python命名空间和作用域,让你的代码逻辑更清晰!

关于Python,我们前面的基础部分,基本也说完了,包括我们也讲了高阶特性,面向对象编程。现在我来补充一个知识:命名空间和作用域

这是Python两个重要的概念,它们决定了变量的可见性和访问范围。理解命名空间和作用域可以帮助我们更好地编写代码,避免命名冲突,并提高代码的健壮性。

1.简介

首先,命名空间(Namespaces)就像是一个大字典,里面存着变量名和对应的东西(比如值或者函数)。这个字典告诉程序:“哥们,当我说这个名字的时候,我的是这个东西!”但有趣的是,在不同的地方(也就是不同的命名空间)里,同一个名字可能会指向不同的东西。就像同名字的人在不同的城市,但是他们却是两个不一样的人!

然后,作用域(Scopes)就是规定了你在哪里能找到这些变量或者修改它们的值。它有点像是规定了一个变量的“活动范围”。在Python中,作用域告诉你:“哥们,这个地方,你可以用这个名字,改它的值也没问题!但那个地方,这个名字可就不认识了!”

所以,命名空间告诉你这个名字指的是啥,而作用域告诉你这个名字在哪里能用。

记住这两个概念,你就能理解Python程序中的变量是如何工作!

为什么命名空间和作用域对Python程序员重要?

  • 避免命名冲突: 使用命名空间可以避免不同模块或库中的相同名称的变量或函数产生冲突。
  • 代码组织和结构化: 通过命名空间,可以更好地组织代码,使代码结构更加清晰。
  • 作用域规则: 了解作用域规则可以帮助程序员理解变量的生命周期和可见性,从而编写更加健壮的代码。

2. 命名空间(Namespaces)

命名空间(Namespaces)是一个从名称到对象的映射,它允许程序员在代码中避免名称冲突。Python解释器会在多个不同的命名空间中管理这些名称。这些有助于确定变量的范围和可见性。

不同类型的命名空间

  • 内置命名空间(Built-in Namespace):
    • 包含了 Python 解释器启动时就加载到内存中的名称,这些名称对应着 Python 的内置函数和异常等。
    • 例如,print()len() 等函数都属于内置命名空间。

  • 全局命名空间(Global Namespace):
    • 全局命名空间是指在模块级别定义的名称空间,一般是指在函数外部定义的变量和函数名。
    • 在一个模块中,全局命名空间始终有效,模块的全局变量和函数在整个模块中可见。

  • 局部命名空间(Local Namespace):
    • 每个函数调用会创建一个局部命名空间,用于存储该函数内部定义的变量名。
    • 这些变量在函数执行期间有效,函数执行结束后,局部命名空间被销毁。
    • 在函数内部定义的变量、函数参数以及由函数调用所创建的局部变量,都属于局部命名空间。

如下图:

示例代码:

# 全局命名空间
global_var = "I'm in the global namespace"

def example_function(arg1):
    # 局部命名空间
    local_var = "I'm in the local namespace"
    print(arg1)

# 内置命名空间
print(len("hello"))  # 内置函数 len() 属于内置命名空间

在这里:global_var 属于全局命名空间,example_function 和 local_var 属于 example_function  的局部命名空间。函数 len() 属于内置命名空间。

3. 作用域(Scopes)

作用域(Scopes)是在程序中定义变量的区域,它决定了变量的可见性和访问规则。作用域规则确定了在何处可以访问变量以及如何解析变量名。

Python 的作用域规则按照以下顺序来查找变量:

1.局部作用域(Local Scope):

    • 定义在函数内部的变量属于局部作用域。
    • 在函数内部声明的变量只在该函数内部可见,函数执行结束后这些变量的作用域也就结束了。

2.嵌套作用域(Enclosing Scope):

    • 嵌套作用域是指在函数内部定义的内部函数的作用域。
    • 内部函数可以访问外部函数中的变量,但不能修改它们。

3.全局作用域(Global Scope):

    • 全局作用域是指在模块级别定义的变量的作用域。
    • 在模块中定义的变量可以在该模块中的任何地方使用。

4.内置作用域(Built-in Scope):

    • 内置作用域包含了 Python 的内置函数和异常等。
    • 这些名称在任何地方都可以访问到,无需导入任何模块。

上面这张图讲了作用域的四大规则,就是 LEGB 规则。下面接着看:

4. LEGB 规则

LEGB 规则的含义

LEGB 规则描述了 Python 中变量名解析的顺序,它按照如下顺序查找变量:

  • L - Local(局部作用域)
  • E - Enclosing(嵌套作用域)
  • G - Global(全局作用域)
  • B - Built-in(内置作用域)

当Python 在运行时遇到一个变量引用时,就会按照 LEGB 规则从局部作用域开始查找变量,然后逐级向上查找直到找到对应的变量或者查找完所有作用域。

LEGB 中的每个部分

作用域描述
Local- 最里层的作用域,在函数内部定义的变量属于局部作用域。
- 函数参数也属于局部作用域。
Enclosing- 包含了非全局(non-global)的嵌套函数的作用域。
- 在一个函数内部定义另一个函数,内部函数可以访问外部函数中的变量。
Global- 包含了模块级别定义的变量的作用域。
- 在模块中定义的变量可以在该模块中的任何地方使用。
Built-in- 包含了 Python 的内置函数和异常等。
- 这些名称在任何地方都可以访问到,无需导入任何模块。

简单来看一个示例代码:

x = 'global'

def outer():
    x = 'outer'

    def inner():
        x = 'inner'
        print(x)  # 首先在局部作用域查找,输出 'inner'

    inner()

outer()  # 输出 'inner',因为 inner() 函数内部的 x 是局部变量
print(x)  # 输出 'global',因为这里访问的是全局变量 x

在这里:inner() 函数首先在自己的局部作用域中查找变量 x,找到了 'inner'。而在最后一个 print(x) 中,因为没有在函数内部重新定义 x,所以找到的是全局变量 x,输出 'global'

5. 示例和应用

老规矩,通过几个示例和应用,讲一讲。

示例 1:不同作用域下变量的可见性

# 全局作用域
global_var = "I'm in the global scope"

def func():
    # 局部作用域
    local_var = "I'm in the local scope"
    print(global_var)  # 可以访问全局变量
    print(local_var)   # 可以直接访问局部变量

func()
print(global_var)  # 可以在函数外部访问全局变量
# print(local_var)  # 这里会报错,因为无法直接访问局部变量

示例 2:嵌套作用域

def outer():
    outer_var = "I'm in the outer function"

    def inner():
        inner_var = "I'm in the inner function"
        print(inner_var)  # 可以直接访问内部函数的变量
        print(outer_var)  # 可以访问外部函数的变量

    inner()

# print(outer_var)  # 这里会报错,因为无法直接访问外部函数的变量
outer()

6. 常见问题与注意事项

在这里,我通过两个常见的问题,来看看一些注意事项。

  • 未声明全局变量就在函数内修改:
x = 10

def func():
    x += 5  # 会报错,因为 x 没有在函数内部声明为 global

func()

这里局部变量冲突, 解决方法是在函数内部使用 global 关键字声明变量 x 为全局变量。

  • 在嵌套函数中修改外部函数变量:
def outer():
    count = 0

    def inner():
        count += 1  # 会报错,因为 count 没有在内部函数中声明为 nonlocal

    inner()
    print(count)

outer()

这里的问题也一样,解决方法为:在内部函数中使用 nonlocal 关键字声明变量 count 为非局部变量。

总结

熟练掌握命名空间和作用域就是你成为 Python 高级程序员的基础,也是学习更复杂 Python 程序设计模式的必要前提。

下面是一些全局变量和局部变量的使用技巧:

技巧描述优点缺点适用场景
尽量避免全局变量减少命名冲突和难以追踪的问题代码更清晰易懂,维护性更高可能需要更多参数传递代码中变量较少,逻辑相对简单
传递参数通过函数参数传递值代码更清晰,易于测试参数过多可能导致代码难以阅读函数需要多个数据进行操作
使用常量定义不会改变的变量为常量提高代码可读性和可维护性可能导致代码不够灵活变量值固定,不会发生变化

如何避免命名冲突:

技巧描述优点缺点适用场景
命名规范使用有意义的变量名,遵循命名规范降低命名冲突的可能性需要一定的时间和精力成本所有代码
模块化代码将代码模块化,使用模块和包将变量隔离在不同的命名空间中代码结构可能变得更加复杂代码量较大,逻辑较为复杂

关于命名空间和作用域,我们就讲这么多,有机会再一起讨论。

欢迎大家和我一起继续学习、记录python的下一个知识点。

如果感觉阅读对您还有些作用,可以评论留言,关注我。谢谢您的阅读!

往期学习:


Python安装教程(版本3.8.10)windows10

Linux系统:安装Conda(miniconda)

Conda快速安装的解决方法(Mamba安装)

VSCode安装教程(版本:1.87.0)Windows10

Python基础语法:从入门到精通的必备指南

Python的基本数据类型

Python数据类型间的转换(隐式、显式)-CSDN博客

Python基础知识:运算符详解-CSDN博客

Python基础知识:数字类型及数学函数详解-CSDN博客

Python字符串操作及方法详解!一篇就搞定!-CSDN博客

Python列表及其操作详解,从此不再迷茫!-CSDN博客

Python元组(Tuple)深度解析!

Python字典的使用技巧(一篇详解)

Python条件控制深度解析,成为编程必备

Python循环语句全解析(附实战演练)

Python函数高效编程技巧,提升你的代码效率!

Python模块和包全解析,一篇文章就够!

Python lambda(匿名函数),一文详解

Python面向对象编程:合集篇(类、对象、封装、继承和多态)

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

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

相关文章

2023新版mapinfo美化电子地图 新版2013Arcgis shp电子地图 下载

2023新版MapInfo和电子地图美化,以及2013版ArcGIS的SHP电子地图设计,是地理信息系统(GIS)领域中的两个重要话题。下面将分别对这两个主题进行描述。 样图: 链接:https://pan.baidu.com/s/1WB4AGsycyBGagVq5…

React Hooks全部总结

Hooks 概念理解 学习目标: 理解 Hooks 的概念及解决的问题 什么是 hooks hooks 的本质: 一套能够使函数组件更强大、更灵活的(钩子) React 体系里组件分为类组件和函数组件 多年使用发现,函数组件是一个更加匹配 Rea…

百度百科词条创作技巧分享,提高创建成功率

我们在百度引擎上搜索一些品牌,很快就能看到品牌的百科内容。我们也可以通过百科快速了解品牌的方方面面,也可以相信品牌有很强的实力。从这几点来看,朋友们可以知道百科词条的重要性,我们可以在以下时间继续了解相关的事情。 1、…

【OceanBase诊断调优】—— 敏捷诊断工具obdiag一键分析OB集群日志设计与实践

最近总结一些诊断OCeanBase的一些经验,出一个【OceanBase诊断调优】专题,也欢迎大家贡献自己的诊断OceanBase的方法。 1. 前言 obdiag定位为OceanBase敏捷诊断工具。1.2版本的obdiag支持诊断信息的一键收集,光有收集信息的能力,…

蓝桥杯单片机快速开发笔记——PCF8591电压信号探测器(可调电阻Rb2电压)和采样光敏电阻

一、原理图 此处考点分析:可能会在引用iic文件时需要自己在头文件定义SCL/SDA sbit sda P2^1; sbit scl P2^0; 二、思维导图 三、代码示例 #include "iic.h" #include "smg.h"unsigned int adc1_value 0; //AIN1的采样数据 float adc…

2024,这些优质可视化大屏素材,承包你一整年的可视化项目

可视化设计一直以来是个难题。如果不知道方法论、没有相关资源,那即使熬了几个大夜,掉了一地头发,设计出来了的东西也只会落个遭人嫌弃的下场。 所以,为了帮助大家提高可视化开发效率,快速制作出美观的可视化效果&…

luceda ipkiss教程 63:器件端口延伸ExtendPorts

案例分享:通过picazzo3库中的ExtendPorts函数实现器件的端口延伸 如: 所有代码如下: from si_fab import all as pdk from ipkiss3 import all as i3 from picazzo3.container.extend_ports import ExtendPorts# Building the MMI PCell wi…

C语言例:整型常量025,求解十进制和十六进制

1. 八进制数的每一位乘以对应的权值(8的幂),然后将结果相加,得到十进制数。 025 21 2.八进制先转二进制(一变三),再二进制转十六进制(四合一) 025 0001 0101 0…

Unity类银河恶魔城学习记录11-1 p103 Item源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释,可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili ItemData.cs using System.Collections; using System.Collections.Generi…

vue3+ts动态表单渲染,antd的useForm改造

let fieldList: any getFormFields(fieldInfo.coreNavigationList[0].list[0].list,fieldInfo.positionCodeRespVO,isCanBeUpdateProcess.value,isDetail.value 1); fieldInfo数据格式: {"name": "默认模板","status": "ENA…

03、判断和循环

三、判断与循环 文章目录 三、判断与循环顺序结构分支结构If语句在程序中就是用来判断的switch 循环结构forwhiledo while 顺序结构 顺序结构是Java程序默认的执行流程,按照代码的先后顺序,从上到下依次执行。 分支结构 If语句在程序中就是用来判断的 …

opc客户端

支持opc,da,ua通信(匿名登陆及用户登陆) 支持批量节点数据监听,当数据有变化时更新 支持单个节点读取和写入 KeepServer做为modbus server keepserver通信配置 https://blog.csdn.net/xiaochenXIHUA/article/detail…

高通推出第三代骁龙8s移动平台,首款终端预计将于3月面市

2024年3月18日,圣迭戈——高通技术公司今日宣布推出第三代骁龙8s移动平台,为更多Android旗舰智能手机带来骁龙8系平台上最广受欢迎的特性,实现非凡的顶级移动体验。这款全新旗舰级平台的主要特性包括支持强大的终端侧生成式AI功能、始终感知的…

操作系统核心知识点大梳理

计算机结构 现代计算机模型是基于-冯诺依曼计算机模型 计算机在运行时,先从内存中取出第一条指令,通过控制器的译码,按指令的要求,从存储器中取出数据进行指定的运算和逻辑操作等加工,然后再按地址把结果送到内存中去…

【Leetcode-21合并两个有序链表】

题目详情: 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4]示例 2: 输入:l1 [], l2 […

由浅到深认识C语言(4):数组

该文章Github地址:https://github.com/AntonyCheng/c-notes 在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址:https://blog.csdn…

市场复盘总结 20240318

仅用于记录当天的市场情况,用于统计交易策略的适用情况,以便程序回测 短线核心:不参与任何级别的调整,采用龙空龙模式 一支股票 10%的时候可以操作, 90%的时间适合空仓等待 二进三: 进级率中 36% 最常用…

【LeetCode每日一题】303. 区域和检索 - 数组不可变

文章目录 [303. 区域和检索 - 数组不可变](https://leetcode.cn/problems/range-sum-query-immutable/)思路:前缀和代码: 303. 区域和检索 - 数组不可变 思路:前缀和 1.因为要根据给出的两个索引,来返回索引区间的和 2.创建一个…

选Gitee还是GitHub?

2024年3月18日,周一晚上 我选择GitHub 因为GitHub可以无限创建仓库

电脑装win11(作si版)

装win11经历 前言:因为我的u盘今天到了,迫不及待试试装机 然后在一系列准备好工具后,便是开始拿学校的机房电脑来试试手了~~ 前期准备 下载好win11镜像(可以去微软官网下载) 下载Rufus工具 https://www.lanzoue.com/…
最新文章