Python函数(三)

2023-12-14 20:31:07

一、名称空间与作用域

1.什么是名称空间

就是用来存放变量名与变量值之间绑定关系的地方

2.内置名称空间

内置名称空间就是Python解释器中本身存在的,可以直接使用的
写代码过程中直接使用的名字都在该空间如:print、len、input

3.全局名称空间

在py文件中,顶格编写的变量名等都是全局的名称空间
如:1.普通代码的变量名 2.分支结构中的变量名 3.循环结构里的变量名
4.定义函数的函数名 5.定义类的类名

4.局部名称空间

在函数体代码中内部的存在的都是局部名称空间

全局变量:在函数外部存在的变量都是全局变量
局部变量:在函数内部存在的变量都是局部变量

在这里插入图片描述

5.名字的查找顺序

只有有了全局名称空间和局部名称空间才会存在名字的查找顺序

	寻找变量名之前一定要先看自己是那个空间
	1.当前在全局名称空间
		全局名称空间>>>>:内置名称空间
	2.当前在局部名称空间
		局部名称空间>>>>:全局名称空间>>>>:内置名称空间
	'''局部变量在外部是不能使用的'''
	
	如果三个空间中都没有这个变量名那结果就会报错。不存在
	名字的查找顺序默认情况下不能颠倒只能是:局部>>全局>>内置
	而名称空间的加载顺序是:内置>>全局>>局部

6.名称空间的作用域

作用域就是变量的作用范围。

	1.内置名称空间
		在全局任意位置都能够使用(全局有效)随时调用
	2.全局名称空间
		在全局任意位置都能够使用(全局有效)随时调用
	3.局部名称空间
		只能在局部使用(只能在函数内使用)调用的时候才有用
		只能在自己的空间里面使用,别的局部空间数据用不到
	'''函数结构梳理'''
	def demo():
	    name = 'jason'  # 定义一个变量
	    print(name) # 打印调用才会显示
	    return 'tom'  # return返回值
	
	demo()  # 调用执行 仅执行不会输出打印
	rel = demo()  # 赋值给rel 也是单调用会执行内部函数体代码
	print(rel)  # 把demo()的返回值输出
==========================================================
	局部名称空间复杂情况
	1.各自局部名称空间默认情况下不能彼此共享名字
	def demo():
	    name = 'jason'
	    print(age)   # 只能在各自的局部空间中使用(局部有效)
	
	def demo1():
	    age = 18
	    print(name)
	'''不调用阶段,逻辑错误不会报错'''
	demo()
	demo1()
	'''调用阶段,逻辑错误立马报错'''

	2.局部案例怎么拿到其他局部的变量名:嵌套式函数
	'''
	当本层函数没有x再在外层局部寻找x
	外层的局部空间也没有x就在全局空间找
	全局没有找内置空间 内置空间没有则报错
	'''
	x = 1
	def demo():
	    x = 2
	    def demo1():
	        x = 3
	        def demo2():
	            print(x)
	        demo2()
	    demo1()
	demo()

二、global和nonlocal的使用

	global
		正常情况下 局部名称空间里面出现新的名字会再局部空间中存储
		但是有时候需要再局部名称空间中修改全局变量,于是就有了global
		
		局部修改全局名称空间中不可变类型的数据(strintfloattuple)
		使用不可变类型的数据就需要关键字global来解决
		但是可变类型的数据就不需要关键字来解决(listdictset)
		
	'''使局部空间变量值修改全局空间的变量值 global'''
	x = 100
	def demo():
	    global x  #加上global这个时候int类型的全局数据就可以更改了
	    x = 20 # 这个是在局部修改全局的x值
	    print(x)
	
	demo() # 调用运行
	print(x) 


	nonlocal
	在内层局部空间修改外层局部空间中的不可变类型
	def demo():
		x = 20
		def demo1():
			nonlocal x  #int数据类型因此需要用nonlocal
			x = 40
		demo1()
		print(x)
	demo()
		
	在内层局部空间修改外层局部空间中的可变类型
	def demo():
		name_list = ['a','b'] #可变类型 故不需要使用nonlocal
		def demo1():
			name_list.append('c')
		demo1()
		print(name_list)
	demo()

	'''
	如果想在内层局部空间修改外层局部空间:
	1.修改的是不可变类型,需要用到nonlocal关键字的声明
	2.修改的是可变类型,不需要用到nonlocal关键字的声明
	'''

三、函数对象(函数名)

函数对象就是函数的名字

1.方式一:函数名可以当变量赋值

	def demo():
	    print('demo')
	    return 123
 	print(demo) #单函数名只能得到内存地址 <function demo at 0x0000029A6CC8D5E0>
	'''函数名就是函数在内存中得地址'''
 	print(demo()) #函数名()打印代码块并返回值
 	a = demo # 单函数名
  	print(a) # 打印得到的是函数名的内存地址
 	rel = a() #相当于单函数+(),直接是调用函数
 	print(rel) #所以打印代码块并返回值

2.方式二:函数名可以当函数的实参

	def demo():
	    print('demo')
	    return None

	def index(a):
	    a = demo # 单函数名不执行调用,只拿到内存地址
	    print(a)
	    res = a() # demo()
	    print(res) # 执行调用 返回定义值None
	
	index(demo) # 把函数demo当成实参

3.方式三:函数名可以当成函数返回值

	def demo():
	    print('demo')
	    return 'jason'

	def index():
	    print('index')
	    return demo # 单函数名 返回内存地址
	
	rel = index()
	print(rel) # 单函数名 返回内存地址
	
	rel1 = rel() 
	'''
	这里相当于把函数index的返回值赋值给了rel1,而函数index的返回值是函数名
	demo所以加括号就变成 demo()直接调用
	'''
	print(rel1)

4.方式四:函数名可以当成容器类型的元素

	def demo():
	    print('demo')
	    return None

	ll = [1,2,3,demo] # 这里把函数名当成一个变量了,但是没有括号故打印内存地址
	print(ll) # [1, 2, 3, <function demo at 0x000001E18796C5E0>]
	a = ll[3]() # 把列表索引demo元素赋值给a,并给予括号,故成demo()
	print(a)

四、闭包函数

1.什么是闭包函数?

1.就是函数内部定义函数,至少要有两层函数
2.内部的函数要使用外部函数名称空间中的名字
满足以上两种条件才能称之为闭包函数

	语法格式:
	def demo():
		x = 6
		def index(): #满足函数内部定义函数
			print(x) #满足内部函数使用外部函数名称空间中的名字
		return index
	demo()

2.闭包函数实际应用

	闭包函数的两种传参方式
	1.第一种传参方式
	def index(username):
    	print(username)
	index('jason')

	2.第二种传参方式
	def my_max(a,b):
	    if a>b:
	        return a
	    return b
	print(my_max(1,2))

文章来源:https://blog.csdn.net/achen_m/article/details/132738044
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。