当前位置: 首页 > news >正文

(小甲鱼python)函数笔记合集四 函数(IV)总结 函数中参数的作用域 局部作用域 全局作用域 global语句 嵌套函数 nonlocal语句等详解

一、基础复习

  1. 函数的基本用法 创建和调用函数 函数的形参与实参等等
  2. 函数的几种参数 位置参数、关键字参数、默认参数等
  3. 函数的收集参数*args **args 解包参数详解

二、函数中参数的作用域

作用域:一个变量可以被访问的范围,一个变量的作用域总是由它在代码中被赋值的位置来决定的。

1.局部作用域
局部变量:如果一个变量定义的位置是在一个函数的里面,那么它的作用域就仅限于该函数中。

>>> def myfunc():
	x=520
	print(x)

	
>>> myfunc()    # x为局部变量
520
>>> 
>>> print(x)   # 在外部访问会报错
Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    print(x)
NameError: name 'x' is not defined

2.全局作用域
全局变量:如果是在任何函数的外部定义一个变量,那么它的作用域就是全局的。

>>> x=880
>>> def myfunc():
	print(x)
	
>>> myfunc()    # x为全局变量
880

在一个函数中,局部变量和全局变量同名都为x时,局部变量就会覆盖掉全局变量。

>>> x=880
>>> def myfunc():
	x=520
	print(x)

>>> myfunc()     #打印局部变量x的值
520
>>> print(x)       #出了函数,打印全局变量
880
>>> 

通过id()函数查看全局变量和局部变量。
#例1:
函数内部如果没有同名的局部变量覆盖的话,它打印的这个id()就是上面全局变量的id

>>> x=880
>>> id(x)
2579527195760
>>> def myfunc():
	print(id(x))

>>> myfunc() #函数内部如果没有同名的局部变量覆盖的话,它打印的这个id()就是上面全局变量的id
2579527195760
>>> 

#例2:
局部变量的id值和全局变量的id值不同。

>>> x=880
>>> id(x)
2579527195760
>>> def myfunc():
	x=520
	print(id(x))

>>> myfunc()   # id值不同
2579527920528
>>> 

3.global语句
global语句在函数内部修改全局变量的值。
使用global语句,可以让函数内的局部变量全局可用,并且在别的文件里也可以引用到。

>>> x=880
>>> def myfunc():
	global x     # global语句可以让函数内的局部变量全局可用。
	x=520
	print(x)

>>> myfunc()   
520
>>> print(x)  # 全局变量x=880被global语句修改为520
520

4.嵌套函数
函数嵌套函数

#内部函数无法被调用
>>> def funA():
	x=520
	def funB():
		x=880
		print("In funB,x=",x)
	print("In funA,x=",x)

>>> funB()  #内部函数无法被调用
Traceback (most recent call last):
  File "<pyshell#47>", line 1, in <module>
    funB()
NameError: name 'funB' is not defined

要想调用funB()函数,在定义时就要调用。

>>> def funA():
	x=520
	def funB():
		x=880
		print("In funB,x=",x)
	funB()   # 调用funB()函数,在定义时就要调用。
	print("In funA,x=",x)

>>> funA()
In funB,x= 880
In funA,x= 520
>>> 

5.nonlocal语句
nonlocal语句:在内部函数修改外部函数的变量。
nonlocal声明的变量不是局部变量,也不是全局变量,而是外部嵌套函数内的变量。

>>> def funA():
	x=520
	def funB():
		nonlocal x    # nonlocal语句修改了外部变量x=520的这个值。
		x=880
		print("In funB,x=",x)
	funB()
	print("In funA,x=",x)

>>> funA()
In funB,x= 880
In funA,x= 880
>>> 

6.LEGB规则

函数作用域之间的影响范围存在相互覆盖的情况,冲突出现时遵从LEGB规则。

L>E>G>B

  • L是local,局部作用域
  • E是Enclosed,是嵌套函数外层函数作用域
  • G是Global,是全局作用域。
  • B是Build-In,是内置作用域。

全局作用域局部作用域发生冲突时,python使用局部作用域的变量(除非使用global语句进行特殊说明)。
函数嵌套发生的时候,局部作用域又会覆盖外层函数这个作用域(除非使用nonlocal语句进行说明)
B是Build-In,只要起一个变量名和它相同,就足以把这个内置函数给毁了。

>>> str="小甲鱼把str给毁咯"
>>> str(520)   #前面已经把str作为变量名赋值,现在它相当于一个全局变量。+
Traceback (most recent call last):
  File "<pyshell#58>", line 1, in <module>
    str(520)
TypeError: 'str' object is not callable
>>> str
'小甲鱼把str给毁咯'

课后题:
1.为什么小甲鱼在视频中说,Python 的阻止局部变量覆盖全局变量的做法,是一种出于对代码的 “保护” 的表现?
答:大家不妨设想一下,当一个程序很庞大的时候,自然就会有很多全局变量和函数,那么在函数中,很容易就会出现局部变量和全局变量同名的情况,如果没有这种“保护”,全局变量将面目全非,而且这种BUG非常不好调试!
2.学了这节课,你觉得除了通过参数给函数传递信息之外,还有什么途径可以传递信息到函数内部呢?
答:还可以通过全局变量传递信息。
3. 请问下面代码会打印什么呢?

>>> x = [1, 2, 3]
>>> def invert(x):
...     x = x[::-1]
...
>>> invert(x)
>>> print(x)
>>> # 请问这里会打印什么内容?

答:[1, 2, 3]
解析:见下题解析。
4.请问下面代码会打印什么呢?

>>> x = [1, 2, 3]
>>> def invert(x):
...     x[:] = x[::-1]
...
>>> invert(x)
>>> print(x)
>>> # 请问这里会打印什么内容?

答: [3, 2, 1]
解析:为什么上一题在函数内部执行 x = x[::-1] 语句,出了函数就还原;而这一题在函数内部执行 x[:] = x[::-1] 语句,则能够从根本上修改列表呢?
现在假设代码如下:

>>> x = [1, 2, 3]
>>> y = x
>>> x = x[::-1]

它在内存中的结构应该是下面这样:
在这里插入图片描述
如果假设代码如下:

>>> x = [1, 2, 3]
>>> y = x
>>> x[:] = x[::-1]

那么在内存中的结构则应该是下面这样:
在这里插入图片描述

5.请问下面代码会打印什么呢?

>>> x = 100
>>> def funA():
...     global x
...     x = 250
...     def funB():
...         nonlocal x
...         x = 520
...     funB()
...
>>> funA()
>>> print(x)
>>> # 请问这里会打印什么内容?

答:会报错!
解析:如果是在 IDLE 的交互模式下敲代码,没等你代码敲完就会报错了。
在 funA() 函数中,先将 x 变量定义为全局变量,接着在嵌套的 funB() 函数中,又试图通过 nonlocal 语句将内层的 x 变量定义为外层的同名变量……
但是,此时外层的 x 变量已经被提前一步定义为全局变量了(也就相当于外层不存在一个叫 x 的局部变量),于是找不到外层的同名的 x 变量,所以便会报错(SyntaxError: no binding for nonlocal ‘x’ found)。
如果在全局中并没有存在变量 x,然后我们在函数中通过 global x 声明,像这样:

>>> # 已知全局中不存在变量 x
>>> def myfun():
...     global x
...     x = 250

这个就不会报错,并且 myfun() 函数成功调用后,全局中会多出一个变量 x,并且被赋值为 250。

题目来自小甲鱼python函数IV

相关文章:

  • wordpress 侧边悬浮窗/网站推广方式组合
  • 网站做菠菜/长沙seo外包
  • 平阳住房和城乡规划建设局网站/站长工具中文
  • 网站不收录怎么办/手机自己怎么建电影网站
  • 自助网站免费注册/什么软件可以排名次
  • 做物流行业网站的开发公司/厦门网络推广哪家强
  • pytorch【Conv2d参数介绍】
  • 初学者C语言练习题-入门
  • 跨境电商必知:这7种实用的保留策略,可以有效减少客户流失
  • 激光雷达对植被冠层结构和SIF同时探测展望
  • 代码随想录算法训练营第七天 | 454.四数相加II ,383. 赎金信 ,15. 三数之和,18. 四数之和
  • Go map 实现原理
  • 致 Tapdata 开源贡献者:聊聊 2022 年的进展和新一年的共建计划
  • Node.js+Vue.js全栈开发王者荣耀手机端官网和管理后台(二) || 后台及接口完结篇
  • vs code中的platformIO插件,完成Arduino的程序编写,导入,安装开发板管理库
  • GW1NSR-LV4CQN48GC6/I5 FPGA呼吸灯
  • 面向对象设计 SOLID 原则和python例子
  • Spring Data Jpa如何实现审计和乐观锁功能