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
局部修改全局名称空间中不可变类型的数据(str、int、float、tuple)
使用不可变类型的数据就需要关键字global来解决
但是可变类型的数据就不需要关键字来解决(list、dict、set)
'''使局部空间变量值修改全局空间的变量值 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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!