首页 > 编程语言 >11、Python之变量:看得见还是看不见

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

时间:2024-07-11 12:25:44浏览次数:23  
标签:11 看得见 apple 变量 Python 作用域 print 赋值

引言

在前面一篇关于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}")

输出结果:

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

标签:11,看得见,apple,变量,Python,作用域,print,赋值
From: https://blog.csdn.net/dqrcsc/article/details/140305282

相关文章

  • python urllib 基础 5
    ajax的post请求importurllib.requestimporturllib.parse#url='https://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=cname'##headers={#'user-agent':"Mozilla/5.0(WindowsNT10.0;Win64;x64)AppleWebKit/537.36(KHTM......
  • Python毕业设计(四十八)、基于Python+Django+Vue的美食推荐系统
    如需要可私信或评论区留言!!!如需要可私信或评论区留言!!!如需要可私信或评论区留言!!!一、项目介绍        美食推荐系统分为前端用户端和后台管理系统。        用户端包括注册登录、查看系统推荐菜品列表、全部菜品列表、按分类筛选菜品、查看菜品统计分析、查......
  • pwnable.tw | 第3题cve-2018-1106
    前言pwnable.tw第三题,开始上难度了,考验的是一款真实程序的漏洞利用。漏洞源于一款开源的苹果AFP协议服务器程序Netatalk,漏洞最早是2018年发现的,2019年在HITCONQuals展示了1day利用,相关文章如下:2018年漏洞作者的原文翻译:NetatalkCVE-2018-1160的发现与利用hitcon相关文章:HITC......
  • Windows+Python配置和使用labelme打标工具(语义分割)
    Labelme是一个开源的图像标注工具麻省理工学院的计算机科学和人工智能实验室(CSAIL)开发。它主要用于创建计算机视觉和机器学习应用所需的标记数据集。LabelMe让用户可以在图片上标注对象和区域,为机器学习模型提供训练数据。它支持多种标注类型,如矩形框、多边形和线条等。它是用Py......
  • Python中的字符串:一次奇妙的冒险之旅
    大家好!今天,我们要踏上一段激动人心的旅程,一起探索Python中的字符串。你:一次奇妙的冒险之旅?字符串:哈哈,没错!对于操纵我的人来说,通常不是创建后就直接拿来用了。他们会对我进行各种魔法般的变换,让我变成他们需要的样子。经过一系列神奇的转换,我早已变得面目全非,真是一场又一场......
  • (免费领取源码)计算机毕业设计项目:宠物店管理系统 19849(开题答辩+程序定制+全套文案 )上
    目 录摘要1绪论1.1背景及意义1.2研究现状1.3springboot框架介绍2 宠物店管理系统系统分析2.1可行性分析2.2系统流程分析2.2.1数据流程3.3.2业务流程2.3系统功能分析2.3.1功能性分析2.3.2非功能性分析2.4系统用例分析2.5本章小结......
  • 【Python 基础】函数 - 1
    函数从前面的章节中,你已经熟悉了print()、input()和len()函数。Python提供了这样一些内建函数,但你也可以编写自己的函数。“函数”就像一个程序内的小程序。为了更好地理解函数的工作原理,让我们来创建一个函数。在文件编辑器中输入下面的程序,保存为h......
  • python-长方体边长和(赛氪OJ)
    [题目描述]给出共享长方体一个顶点的三个面的面积,求它十二条边的边长和。输入格式:一行三个整数 a , b , c 表示面积。输出格式:一行一个整数表示边长和。样例输入#1111样例输出#112样例输入#2466样例输出#228数据范围:对于100% 的数据,1≤a,b,c≤10000。来源/......
  • (免费领源码)Java/Mysql数据库+09536 SSM爱心捐赠物资维护系统,计算机毕业设计项目推荐上
    摘要随着信息技术的快速发展,计算机应用已经进入成千上万的家庭。随着物资数量的增加,物资库存管理也存在许多问题。物资数据的处理量正在迅速增加,原来的手工管理模式不适合这种形式。使用计算机可以完成数据收集、处理和分析,减少人力和物力的浪费。需要建立爱心捐赠物资维护系......
  • Windows11使用子系统Ubuntu20.04配置图形化界面和安装软件
    前言        在上一章节,我们在windows11下利用wsl2安装了Ubuntu-linux子系统,并下载了android10的源码进行编译(Ubuntu运行环境下Android10源码下载和编译_ubuntu18下载android10源码-CSDN博客)。如果想进行android源码以及framework的学习,一定需要代码编辑软件,我之前学......