首页 > 编程语言 >python基础 :作用域

python基础 :作用域

时间:2023-10-31 18:00:29浏览次数:37  
标签:读取 作用域 基础 python 赋值 class 变量 函数

一 前言

环境:
python 3.10.11
win10

二 关于作用域

先来一个简单的例子,如下
image

执行结果
image

如上,在eating_other函数内为变量重新赋值,指向了一个新的对象,在该函数内输出的是新值,在该函数外输出的依旧是旧值,因为给变量重新赋值所产生的影响仅仅局限在在赋值所在的函数内,对赋值所在函数的外面的代码是无影响的

eating函数内本身并没有定义变量food,要读取该变量时,只能是从函数的外面寻找,如果外部也没有定义该变量,就会报错说该变量未定义。如果函数内和函数外都有food变量,会优先读取函数内的变量值

自己的粗浅理解是,每个py文件以及每个class以及每个函数都有自己的影响范围,这个范围就是作用域。作用域表现在两方面

  • 在每个py文件内及class内及函数内,读取变量时,它会优先在对应件内或class内或函数内寻找变量,若寻找不到,才会去外部寻找
  • 在每个py文件内及class内及函数内,给变量赋值时(即用符号=把该变量指向一个对象),该变量被默认为局部变量,只会被对应文件或class或函数内的代码读取

需要注意的是,作用域是可以互相包含的,如py文件内有class,class内有函数,那函数的作用域在class作用域内部,class作用域在py文件作用域内部
关于class的作用域,即读取或者给其作用域的变量重新赋值还需要结合class的相关特性来使用

三 外部作用域的值

读取外部作用域中的值

外部作用域为非函数

里面的函数作用域和外部作用域有同名变量,这时候,读取变量的代码位于哪一个作用域,就会优先读取哪一个作用域中变量
如果想在里面的函数读取外面函数作用域的同名变量,这时候要用函数gloabls,如下
image
如上,输出的就是外部作用域中的值

外部作用域为函数

即函数嵌套的情况,如下
image
和前面类似,外部函数和内部函数都有自己的作用域,读取变量的代码位于哪一个作用域,就会读取哪一个作用域中变量,如果未找到,才会去更外一层作用域中寻找

和之前不同的是,内外部函数有同名变量,在内部函数作用域中要读取同名属于外部函数的变量,此时并没有类似的函数供我们使用,此时只有打破同名的限制,有下面3种方法

  • 只能让内外部函数变量不同名,这样就可以找到外部的变量名
  • 定义内部函数时带上一个参数,执行时,外部函数把值传给该参数,从而带入到内部函数中
  • 像后面介绍的使用关键字nonlocal,在内部函数中声明要使用的变量为外部函数的变量

为外部作用域中的变量重新赋值

外部作用域为非函数

如下,在内部作用的变量赋值时无法对外面
image
输出值为water

要在函数内修改外面的变量值,要用关键字global,声明变量为全局变量
image
现在输出的值就是 ice

外部作用域为函数

嵌套函数中用关键字nonloal,用法和gloabl很像,但nonlocal并不是声明变量为全局变量,而是声明该变量为外部函数中的变量
image
如上,输出值是ice,若没有nonlocal food这一行,输出值是water

四 一些易错的例子

image
如上,函数内先读取再赋值,以为是先输出外部的值water,在输出内部的值ice
但执行结果确实报错
image
啥意思,说food是一个局部变量, 在它赋值前读取了它

函数内的第2行是赋值,读取是第一行。就是说第一行的读取不应该写在第二行的复制前面
我们很容易理解为第一行读取没有问题,没有变量就读取外面的变量,哪里有问题,和第2行有啥关系
但事实是,一旦在作用域内赋值,那在该整个作用域内,该变量都是局部变量,之前第一行的代码中的变量也被视为局部变量, 此时只有删掉第一行,或者在第一行声明food为全局变量

image

这个例子输出结果是多少,之前会 认为是{"today": "water"},但结果却是{"today": "ice"}
或者有时我会在函数内申明该字典为全局变量,但其实根本不用

这看起来是和之前在函数内部重新为变量赋值很像,但注意,这里并没有符号=,不是重新赋值。他是对变量指向对象中的值进行更新,之前是为该变量重新指向了一个新的对象,这两者是由根本区别的

标签:读取,作用域,基础,python,赋值,class,变量,函数
From: https://www.cnblogs.com/MyRecords/p/17800089.html

相关文章

  • 第三周练习--用python计算圆周率Pi
    非刷新文本进度条&公式法计算PiimporttimeN=100pi=0scale=10dur=0print("-----------执行开始-----------")start=time.perf_counter()#返回当前的计算机系统时间foriinrange(scale+1):a="**"*i#表示成功的进度b=".."......
  • Vue2 基础入门
    1Vue1.2第一个Vue实例(HelloVue)1.3插值表达式{作用:利用表达式进行插值,渲染到页面中表达式:是可以被求值的代码,JS引擎会讲其计算出一个结果以下的情况都是表达式:money+100money-100money*10money/10price>=100?'真贵':'还行'obj.namearr[0]fn()ob......
  • python中的鸭子类型
    python中的鸭子类型_python鸭子类型-CSDN博客浅谈Python鸭子类型-腾讯云开发者社区-腾讯云(tencent.com)python不支持多态也用不到多态,多态的概念是应用于java和C#这一类强类型语言中,而Python崇尚鸭子类型(DuckTyping)鸭子类型:是一种动态类型的风格。一个对象有效的语义,不是......
  • Kotlin语言基础入门:Kotlin简介
    在2019年GoogleI/O大会上,Google宣布今后将优先采用Kotlin进行Android开发。一,简介Kotlin是一种富有表现力且简洁的编程语言,不仅可以减少常见代码错误,还可以轻松集成到现有应用中。Google列举的Kotlin的优势:富有表现力且简洁:可以使用更少的代码实现更多的功能。表达自己的......
  • Python添加参数的几种方法
    用python添加参数都是用的input函数,不能添加默认值也不能输入help提示。最近发现了2个更好用的库分享给大家。一、使用input库。这个使用很简单,就不过多描述了。deftest(a,b):print(f"{a}+{b}="+str(int(a)+int(b)))if__name__=='__main__':a=input("inputa:......
  • 【Python微信机器人】第三篇:使用ctypes调用进程函数和读取内存结构体
    目录修整目前的系列目录(后面会根据实际情况变动):在windows11上编译python将python注入到其他进程并运行注入Python并使用ctypes主动调用进程内的函数和读取内存结构体使用汇编引擎调用进程内的任意函数利用beaengine反汇编引擎的c接口写一个pyd库,用于实现inlinehook利用......
  • 基础语法
    1.变量的定义varnametype=xxxvarname=xxxvarname1,name2,name3=xx,xx,xxvar{name1,name2=xx,xx}name1,name2:=xx,xxname:=xxx//name为变量名称2.go语言是强类型语言,在计算时类型必须都要保持一致;定义的类型变量必须要使用,否则会报错3.获取数组长度使用......
  • selenium+python,自动获取cookie登录
     一、通过cookie一直保持自动登录状态1.手动操作原理:保持自动登录状态1.通过cookie信息的唯一标识ID2.登录后一直保持不退出状态,就可以实现自动登录  登录后,session唯一标识:如果当前是登录状态,那就是登录。如果不是登录状态,就不是登录的。如何查看是否登录状态?浏览器......
  • C++基础杂记(2)
    将数组传入函数禁止修改数组的值函数的地址与函数的指针函数的指针数组函数的static与inline引用左值和引用传参C++11的数组for循环64位Linux操作系统中C++中常见基本类型所占字节数C++11类成员变量的初始化默认成员初始化器成员变量初始化列表委......
  • C++基础杂记(3)
    类的继承基类与派生类之间的构造行为在派生类中使用基类方法protected的访问权限多态公有继承关键字virtual示例抽象基类(ABC)私有继承和保护继承多重继承类的继承基类与派生类之间的构造行为派生类可以调用基类的公共成员,但无法调用基类的私有成员。所......