11、Python之变量:看得见还是看不见

引言

在前面一篇关于Python变量的文章中,更多地结合对象的内存结构及字节码指令,来看不同代码针对不同的类型的对象的不同效果。


今天这篇文章中,想对新手在使用Python变量中,可能遇到的其他困惑,再展开来说一下。


大概分为这几个模块:
1、几种变量赋值操作
2、Python中的变量作用域
3、变量赋值实例

几种变量赋值操作

赋值语句

首先,从概念上来说,赋值的代码,我们一般叫做“赋值语句”。


需要注意的是,通常来说,在编程语言中,语句与表达式是有区别的,表达式是有结果值的,可以作为赋值语句的一部分,也可以是其他语句中的组成部分。但是,赋值语句就不可以了,赋值语句就应该是一个单独的代码行,而不应该,也不能出现在其他语句或者表达式中。

# 赋值语句
# a equals 10
a = 10
print(a)
# 表达式可以单独写,虽然没有啥意义
a * 2
# 表达式可以作为赋值语句的一部分
# b equals a multiply 2
b = a * 2
# 赋值语句不能作为其他非赋值语句或者表达式的一部分:
# c = (b = a) * 2


赋值表达式(海象操作符)

有时候存在一些场景,我们需要先进行赋值操作,然后对变量的值进行比较或者进一步处理,这时候就需要拆开来写:

goods_count = {
    'apple': 5,
    'banana': 0,
    'orange': 1
}
apple_cnt = goods_count.get('apple', 0)
if apple_cnt > 3:
    print(f'可销库存:{apple_cnt},不需要补货')
else:
    print(f'可销库存:{apple_cnt},需要补货了')


本着“能用一行代码搞定的,绝不应该写两行”的理念(瞎说的),Python从3.8开始,引入了新的语法,叫做“赋值表达式”,不同于赋值语句,赋值表达式是可以出现在其他语句中的。


赋值表达式使用的操作符,叫做海象操作符,可以意会。


使用赋值表达式改写一下:

goods_count = {
    'apple': 5,
    'banana': 0,
    'orange': 1
}

# 赋值表达式:apple_cnt := goods_count.get('apple', 0)
if (apple_cnt := goods_count.get('apple', 0)) > 3:
    print(f'可销库存:{apple_cnt},不需要补货')
else:
    print(f'可销库存:{apple_cnt},需要补货了')


链式赋值

不同于之前读书那会儿,学习C,新手容易犯的错误,就是链式赋值,但是,这在Python中是允许的

a = b = c = d = 10
print(a)
print(b)
print(c)
print(d)

Python中的变量作用域

有时候,明明变量有的,解释器跟看不到一样,愣是报错。
有时候,明明对变量重新赋值了,也没有报错,确又没有赋值成功。


如果是一个不理解Python解释器逻辑的Python新手,会觉得Python解释器就好像眼睛不太好使的病人……

在编程语言中,一般都有一个作用域(Scope)的概念。简单理解,就是变量能发生作用的范围。变量的作用域决定了变量在程序中的可见性和生命周期。不同的编程语言中,关于变量的作用域的设计可能会有些细微的差别。

作用域类型

在Python中,主要有四种作用域,范围从小到大,依次为:

  • 局部作用域(Local Scope):在函数内部定义的变量,仅在函数内部可见
  • 嵌套作用域(Enclosing Scope):在嵌套函数中,外部函数的变量,对内部函数可见
  • 全局作用域(Global Scope):在模块级别定义的变量,在整个模块中可见
  • 内置作用域(Built-in Scope):Python内置的变量和函数,如print、len等
LEGB规则

Python查找变量的顺序遵循LEGB规则:

  • L(Local):首先在局部作用域查找变量
  • E(Enclosing):如果在局部作用域中找不到,则在嵌套作用域查找
  • G(Global):如果在嵌套作用域中找不到,则在全局作用域查找
  • B(Built-in):如果在全局作用域中找不到,则在内置作用域查找

如果这些作用域中都没有定义名称相同的变量,那么程序就会抛出NameError异常。

变量赋值实例

对变量的使用,分为两种情况,一种是读,一种是写(重新赋值)。
关于变量读的操作,应用前面的LEGB规则就行了。

但是,对于变量的写,就有些不太一样了,要分为两种情况:
1)如果变量已经在定义在当前作用域中,那么直接把新的值交给它即可;
2)如果当前作用域中不存在这个变量,那么即便外围作用域中有同名的变量,Python还是会把本次的赋值操作当成是变量定义来处理。这时会产生的一个重要的效果,也就是说,Python会把包含赋值操作的这个函数当成新定义的这个变量的作用域。

# 全局变量
a = 10
print(f"Global Scope: {a}")

# 定义函数,改变a
def change_a():
    # 局部变量a的定义及赋值
    a = 20
    print(f"Local Scope: {a}")

# 调用函数,改变a
change_a()
# 查看全局变量a的取值
print(f"Global Scope: {a}")

输出结果:

新手可能会认为这种赋值规则比较奇怪,但是Python是故意这样设计的。这样,才能防止函数中的局部变量污染外围模块。

假如不这样做,那么函数里的每条赋值语句都有可能影响全局作用域中的变量,这样不仅混乱,而且会让全局变量之间彼此交互影响,从而导致很多难以探查的bug。

设计思想是好的,但是,现在问题来了,要怎么从局部作用域来修改全局作用域中的变量呢?Python中提供了解决方案,通过global关键字声明引用全局变量:

# 全局变量
a = 10
print(f"Global Scope: {a}")

# 定义函数,改变a
def change_a():
    # 声明引入全局变量 a
    global a
    a = 20
    print(f"Local Scope: {a}")

# 调用函数,改变a
change_a()
# 查看全局变量a的取值
print(f"Global Scope: {a}")

输出结果:

关于变量的使用及作用域,暂时就介绍到这里。更多的内容,在后面介绍到函数、闭包等,还会有所涉及。

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

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

相关文章

乐器培训课程报名小程序模板源码

模板介绍 一款实用的音乐课程,乐器培训,艺术类网页课程报名手机小程序模板下载。包含:主页、列表、个人中心、报名等模块。 图片演示 乐器培训课程报名小程序模板源码

《Windows API每日一练》9.13资源-鼠标位图和字符串

鼠标指针位图(Mouse Cursor Bitmap)是用于表示鼠标指针外观的图像。在 Windows 窗口编程中,可以使用自定义的鼠标指针位图来改变鼠标的外观,并提供更加个性化的用户体验。 ■以下是一些与鼠标指针位图相关的要点: ●…

九、C++11常用新特性—模板的优化

1.模板的右尖括号 在泛型编程种,模板实例化有一个非常繁琐的地方,那就是连续的两个右尖括号(>>)会被编译器解析成右移操作,而不是模板参数表的结束,在C11以前需要在>>之间加上一个空格> >。C11之后…

中职网络安全Server2216

任务环境说明:✓ 服务器场景:Server2216(开放链接)✓ 用户名:root密码:1234561.黑客通过网络攻入本地服务器,通过特殊手段在系统中建立了多个异常进程找出启动异常进程的脚本,并将其绝对路径作为Flag值提交…

WindowsMac共享文件夹设置

共享文件夹设置 共享文件夹设置Windows系统设置步骤一:设置共享文件夹步骤二: 访问共享文件夹 Mac系统中设置共享文件夹步骤一:设置共享文件夹步骤二:访问共享文件夹 小贴士结论 共享文件夹设置 有时需要在多台电脑之间共享文件夹&#xff0…

学习嵌入式对于学历有要求吗?

学习嵌入式系统开发通常并不对学历有严格的要求,尤其是在技术行业中,实际的技能和经验往往比学历更为重要。我收集归类了一份嵌入式学习包,对于新手而言简直不要太棒,里面包括了新手各个时期的学习方向编程教学、问题视频讲解、毕…

【C++报错已解决】Multiple Definition of Symbol

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 引言一、问题描述1.1 报错示例1.2 报错分析1.3 解决思路 二、解决方法:方法一:使用extern关键…

设计模式之Facade设计模式

Facade设计模式,也称为外观模式,是一种结构型设计模式,它主要用于为子系统中的一组接口提供一个统一的高层接口,从而使得子系统更加容易使用。以下是关于Facade设计模式的详细介绍: 一、定义 Facade模式为多个复杂的…

【单片机毕业设计选题24054】-基于STM32的水质检测系统

系统功能: 主要功能模块原理图: 电源时钟烧录接口: 单片机和按键输入电路: 传感器采集电路: 资料获取地址 系统主要功能模块代码 初始化代码: /* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration-----------------------------------------------…

Golang | Leetcode Golang题解之第226题翻转二叉树

题目: 题解: func invertTree(root *TreeNode) *TreeNode {if root nil {return nil}left : invertTree(root.Left)right : invertTree(root.Right)root.Left rightroot.Right leftreturn root }

C++ | Leetcode C++题解之第225题用队列实现栈

题目&#xff1a; 题解&#xff1a; class MyStack { public:queue<int> q;/** Initialize your data structure here. */MyStack() {}/** Push element x onto stack. */void push(int x) {int n q.size();q.push(x);for (int i 0; i < n; i) {q.push(q.front());…

操作系统:信号究竟是什么?如何产生?

OS信号 一、信号的概念二、信号的产生1&#xff09;终端按键产生信号1、 前台进程、后台进程2、验证终端按键是否产生信号 2&#xff09;调用系统函数向进程发信号3&#xff09;硬件异常产生信号1、浮点数溢出&#xff0c;CPU产生信号2 浮点数溢出&#xff0c;产生信号原理3. 空…

字节码编程javassist之修改返回值

写在前面 本文看下如何修改返回值。 代码 需要增强的类&#xff1a; package com.dahuyou.javassist.huohuo.cc;import java.math.BigDecimal;public class MyApiTestNoAnnotation {public double queryUserInfo(String uId){return BigDecimal.ONE.doubleValue();}}插桩类…

JavaWeb—js(3)

Bom dom: document object model(文档对象模型), 是处理html、xml的标准编写接口。 节点和元素 整个页面也就是整个文档我们称之为文档节点; 文档节点使用document来表示; 页面中的所有标签我们称之为元素&#xff0c;使用element来表示; 如此处的文本、属性、注释等&…

腾讯又一平台即将停止运营

随着腾讯公司业务和战略的调整&#xff0c;某些业务逐渐退出历史舞台&#xff0c;如“腾讯直播平台NOW”&#xff0c;以及“QQ签到”&#xff0c;“腾讯待办”&#xff0c;“企鹅FM音频平台”等&#xff0c;最近又有一则重磅消息&#xff0c;那就是“腾讯课堂”也即将停止运营。…

前端构建工具(webpackvite)

这里写目录标题 构建工具webpack介绍配置文件简介entryoutputloaderbabel插件开发服务器&#xff08;webpack-dev-server&#xff09;soureMap vite 构建工具 当我们习惯了在node中编写代码的方式后&#xff0c;在回到前端编写html、css、js这些东西会感觉到各种的不便。比如:…

JS代码动态打印404页面源码

JS代码动态打印404页面源码&#xff0c;适合做网站错误页&#xff0c;具有js动态打印效果&#xff0c;喜欢的朋友可以拿去 源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务…

MES系统在装备制造行业核心应用场景介绍

MES软件在企业中有着广泛的应用场景&#xff0c;主要包括生产计划排程、生产过程监控、质量管理、设备管理、库存管理、数据分析等领域。 通过实时监控生产过程、收集数据、进行分析&#xff0c;MES软件可以帮助企业实现生产过程可视化、透明化&#xff0c;提高生产效率&#…

mybatis 延迟加载

MyBatis的延迟加载&#xff08;Lazy Loading&#xff09;是一种优化技术&#xff0c;用于在需要时才加载关联对象或集合&#xff0c;从而提高性能和效率。以下是对MyBatis延迟加载的详细介绍&#xff1a; 延迟加载的基本概念 延迟加载是指在第一次访问对象的属性时才加载该对象…

vue3 antdv Modal通过设置内容里的容器的最小高度,让Modal能够适当的变高一些

1、当收款信息Collapse也折叠的时候&#xff0c;我们会发现Modal的高度也变成了很小。 2、我们希望高度稍微要高一些&#xff0c;这样感觉上面显示的Modal高度太小了&#xff0c;显示下面的效果。 3、初始的时候&#xff0c;想通过class或者style或者wrapClassName来实现&#…