【十】Python全栈之路--作用域

【十】Python全栈之路--作用域,第1张

【十】Python全栈之路--作用域

文章目录
    • 1. return返回值
    • 2. 全局变量_局部变量
    • 3. 函数名的使用
    • 4. 函数的嵌套
      • 4.1 函数的嵌套
      • 4.2 nonlocal的使用
    • 5. 闭包函数的定义
    • 6. 闭包的特点_意义

1. return返回值
# ### return 自定义函数的返回值
"""
概念:return 把函数内部的数据返回到函数的外面,返回到函数的调用处
1.return + 六大标准数据类型 , 除此之外还可以返回函数 或者 是类对象
2.return 在执行时,意味着终止函数,后面的代码不执行.
3.如果不定义return返回值,默认返回None
"""

# (1) return + 六大标准数据类型
def func():
	# return 111
	# return 6.89
	# return "你好帅啊,我爱死你乐"
	# return [1,2,3]
	# return {"a":1,"b":2}
	return 1,2,3 # 返回元组
res = func()
print(res)

# (2) return 在执行时,意味着终止函数,后面的代码不执行.
def func():
	print(1)
	print(2)
	return 3
	print(4)
res = func()
print(res)

def func():
	for i in range(5):
		if i == 3:
			return 4
		print(i)
res = func()
print(res)

# (3) 如果不定义return返回值,默认返回None
def func():
	pass
	
res = func()
print(res) # None
	
# 注意点 打印的数据和返回的数据不是等价的,返回的数据是可以自定义的;
res = print(1234)
print(res)  # None
	

# 模拟+-*/计算器
"""
功能:   完成计算
参数:   2个数字和运算符
返回值: 计算后的结果
"""
def calc(num1,num2,sign):
	if sign == "+":
		return num1 + num2
	elif sign == "-":
		return num1 - num2
	elif sign == "*":
		return num1 * num2
	elif sign == "/":
		if num2 == 0:
			return "除数不能为零"
		return num1 / num2
	else:
		return "抱歉,超出了我的运算范围."
	
res = calc(3,5,"+")
res = calc(3,5,"-")
res = calc(3,5,"*")
res = calc(3,0,"/")
res = calc(3,0,"&")
print(res)
	
2. 全局变量_局部变量
# ### 全局变量和局部变量
"""
1.概念
	局部变量:在函数内部定义的变量就是局部变量
	全局变量:在函数外部定义的变量或者在函数内部使用global关键字声明是全局变量

2.作用域:
	局部变量的作用范围仅仅在函数的内部
	全局变量的作用范围横跨整个文件
	
3.生命周期:该变量的作用时长
	内置命名空间 -> 全局命名空间  -> 局部命名空间 (开辟空间顺序)
	内置属性 > 全局属性 > 局部属性 (作用时长:长->短)
"""

# 1 局部变量
def func():
	# 定义一个局部变量
	a = 1
	# 获取当前的局部变量
	print(a)
	# 修改一个局部变量
	a = 2
	print(a)
	
func()
# print(a) error

# 2.全局变量
# 定义一个全局变量
b = 10
# 获取当前的全局变量
print(b)
# 修改一个全局变量
b = 20
print(b)

def func():
	print(b)
func()

# 3.函数内部定义全局变量
def func():
	global c
	c =30
func()
print(c)

# 4.函数内部修改全局变量
d = 50
def func():
	global d
	d = 51
func()
print(d)

"""
总结:global的使用
如果当前不存在全局变量,可以在函数内部通过global关键字来定义全局变量
如果当前存在全局变量,可以在函数内部通过global关键字来修改全局变量
"""

3. 函数名的使用
# ### 函数名的使用
"""
# python中的函数可以像变量一样,动态创建,销毁,当参数传递,作为值返回,叫第一类对象.其他语言功能有限
"""
def func():
	print( "我是func函数")

# (1)动态创建
a = 1
print(a)
a = func
a()

# (2)动态销毁
del a
# a()
# func()

# (3)当参数传递
def func2():
	return "我是func2函数"

def func1(f):
	return f() # "我是func2函数"

res = func1(func2)
print(res)

# (4)作为值返回
def func3():
	print( "我是func3函数" )
	
def func4(f):
	return f
res = func4(func3)	
print(res)
res()

print("<=========>")
# (5)函数名可以作为容器类型数据的元素
lst = [func,func3]
for i in lst:
	i()

print("
") # ### __doc__ 或者help查看文档 def big_chang_cishen(something): """ 功能: 教你怎么吃大肠 参数: 吃的内容 返回值: 是否满意 """ print("把{}洗一洗".format(something)) print("直接找肠子头,放嘴里,吸一下") print("擦擦嘴,满意的放下肠子头") return "吃完了,真好吃~" big_chang_cishen("生肠子") # 方法一 res = big_chang_cishen.__doc__ print(res) # 方法二 help(big_chang_cishen)

4. 函数的嵌套 4.1 函数的嵌套

# ### 函数的嵌套
"""
互相嵌套的两个函数![请添加图片描述](https://img-blog.csdnimg.cn/f3ab3fd8502e43eebd473306c0e28633.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA54as5aSc5rOh5p645p2e,size_20,color_FFFFFF,t_70,g_se,x_16)
:
	包裹在外层的叫做外函数,内层的就是内函数
"""
def outer():
	# inner()
	def inner():
		print("我是inner函数")
	
""""""
# (1)内部函数可以直接在函数外部调用么 不行
# inner()
# (2)调用外部函数后,内部函数可以在函数外部调用吗 不行
# outer()
# inner()
# (3)内部函数可以在函数内部调用吗 可以
outer()
# (4)内部函数在函数内部调用时,是否有先后顺序 有的
# 先定义在调用
# 在其他语言中有预加载的机制,提前把函数驻留到内存中,然后再去编译脚本内容
# python没有预加载函数的机制,只能先定义在调用;


# 外函数是outer  中间函数是inner  最里层是smaller ,调用smaller函数
def outer():
	def inner():
		def smaller():
			print("我是smaller函数")
		smaller()
	inner()
outer()


# LEGB 原则
def outer():	
	
	def inner():
		
		def smaller():	
			
			print(a)
		smaller()
	inner()
outer()

"""
LEGB原则(就近找变量原则)
#找寻变量的调用顺序采用LEGB原则(即就近原则)
B —— Builtin(Python);Python内置模块的命名空间      (内建作用域)
G —— Global(module); 函数外部所在的命名空间        (全局作用域)
E —— Enclosing function locals;外部嵌套函数的作用域(嵌套作用域)
L —— Local(function);当前函数内的作用域            (局部作用域)
依据就近原则,从下往上 从里向外 依次寻找
"""



 
4.2 nonlocal的使用 
# ### nonlocal的使用 (用来修改局部变量)
"""
nonlocal遵循LEGB原则
(1) 它会找当前空间上一层的变量进行修改
(2) 如果上一层空间没有,继续向上寻找
(3) 如果最后找不到,直接报错
"""

# (1)它会找当前空间上一层的变量进行修改
def outer():
	a = 10
	def inner():
		nonlocal a
		a = 20
		print(a)
	inner()
	print(a)
outer()

# (2)如果上一层空间没有,继续向上寻找
def outer():
	a = 20
	def inner():
		a = 15
		def smaller():
			nonlocal a
			a = 30
			print(a)
		smaller()
		print(a)
	inner()
	print(a)
outer()

# (3)如果最后找不到,直接报错
"""nonlocal 只能修改局部变量,"""
"""
a = 20
def outer():	
	def inner():
		def smaller():
			nonlocal a
			a = 30
			print(a)
		smaller()
		print(a)
	inner()
	print(a)
outer()
error
"""


# (4) 不通过nonlocal 是否可以修改局部变量呢?ok
def outer():
	lst = [1,2,3]
	def inner():
		lst[-1] = 3000
	inner()
	print(lst)
outer()

5. 闭包函数的定义 <==1==># ### 闭包函数 """ 互相嵌套的两个函数,如果内函数使用了外函数的局部变量 并且外函数把内函数返回出来的过程,叫做闭包 里面的内函数叫做闭包函数 是不是闭包? 1.内函数用了外函数的那个局部变量 2.外函数返回内函数 """ # 1.基本语法形式 def zhaoshenyang_family(): father = "马云" def hobby(): print("我对钱没有一丝丝的兴趣,我不看重钱,这是我爸爸{}说的".format(father)) return hobby func = zhaoshenyang_family() func() print("<==2==>") tup = func.__closure__ print(tup[0].cell_contents) # 马云 print(tup) print("<11111>") # 2.闭包的复杂形式 def zhaowanli_family(): gege = "王思聪" didi = "鞋王,高振宁" money = 1000 def gege_hobby(): nonlocal money money -= 500 print("我交朋友不在乎他有没有钱,反正都没有我有钱.我就喜欢交女朋友... 钱物还剩下{}".format(money)) def didi_hobby(): nonlocal money money -= 400 print("家里有鞋柜,各式各样的奢侈鞋,一双大概20~30万,钱物还剩下{}".format(money)) def big_master(): return [gege_hobby,didi_hobby] return big_master func = zhaowanli_family() print(func) lst = func() print(lst) # 获取哥哥函数 gege = lst[0] gege() # 获取弟弟函数 didi = lst[1] didi() # 3.使用 __closure__ , cell_contents 判定闭包 """如果返回的元组中有数据说明是闭包,谁的生命周期被延长就打印谁""" tup = func.__closure__ print(tup) # 先获取第一个单元格 cell_contents获取对象中的内容 func1 = tup[0].cell_contents print("<22222>") """打印闭包函数didi_hobby中,生命周期被延长的属性""" print(func1.__closure__[0].cell_contents) func1() # 在获取第二个单元格 cell_contents获取对象中的内容 func2 = tup[1].cell_contents print("
") """打印闭包函数gege_hobby中,生命周期被延长的属性""" print(func2.__closure__[0].cell_contents) func2()



6. 闭包的特点_意义

# ### 闭包特点
"""
特点:在闭包函数中,内函数使用了外函数的局部变量,
该变量会与内函数发生绑定,延长该变量的生命周期,
持续到脚本执行结束.
"""
def outer(val):
	def inner(num):
		return val + num
	return inner
	
func = outer(10)
res = func(15)
print(res)


# ### 闭包的意义
"""全局变量的作用域大,容易被篡改"""
num = 0
def click_num():
	global num
	num += 1 # num = num + 1
	print(num)
click_num()
click_num()
click_num()
num = 100
click_num()
click_num()

# 改造,用闭包来实现
"""
闭包的意义:
	闭包可以优先使用外函数中的变量,并对闭包中的值起到了封装保护的作用.外部无法访问.
"""
def outer():
	x = 0
	def click_num():
		nonlocal x
		x += 1
		print(x)
	return click_num

click_num = outer()
click_num()
click_num()
click_num()
x = 100
click_num()
click_num()

小提示:
def outer():
      a = 10
      def inner():
            a = 20
            print(a)
       inner()
       print(a)
outer()
这里的输出结果是20 10,嵌套里的两个a变量互不干扰


列表可以直接可以在内外函数直接传递值,修改列表
的时候不需要使用nolocal来修改变量的值。

闭包可以延长局部变量的周期  
没办法在函数的内部去修改一个全局变量的,必须通过一个global(跟nonlocal一个道理的)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4830108.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-10
下一篇 2022-11-10

发表评论

登录后才能评论

评论列表(0条)

保存