名称空间、全局变量、闭包函数
函数多种方法
名称空间
name = 'kiki'
底层原理:
1.申请内存空间存储kiki
2.给kiki绑定一个变量名name
3.后续通过变量名name就可以访问到kiki
名称空间就是用来存储变量名与数据值绑定关系的地方(简单理解为存储变量名的地方)
名称空间分类
名称空间分为内置名称空间和全局名称空间
1.内置名称空间
解释器运行自动产生,里面包含了很多名字
eg:len print input
2.全局名称空间
py文件运行产生,里面存放文件级别的名字
name = 'kiki'
if name:
age = 18
while True:
gender = 'female'
def index():
pass
class MyClass(object):
pass
name\age\gender\index\MyClass
3.局部名称空间
函数体代码运行\类体代码运行 产生的空间
名称空间存货周期及作用范围(域)
存活周期
内置名称空间
python解释器启动则创建,关闭则销毁
全局名称空间
py文件执行则创建,运行结束则销毁
局部名称空间
函数体代码运行则创建,函数体代码结束则销毁
作用域
内置名称空间
解释器级别的全局有效
全局名称空间
py文件级别的全局有效
局部名称空间
函数体代码内有效
名字的查找顺序
设计到名字的查找,一定要先搞明白自己在哪个空间
1.当我们在局部名称空间中的时候,查找的顺序如下
局部名称空间>>>全局名称空间>>>内置名称空间
2.当我们在全局名称空间中的时候,查找的顺序如下
全局名称空间>>>内置名称空间
注意:其实名字的查找是可以的
查找顺序案例
1.相互独立的局部名称空间默认不能互相访问
def demo():
name = 'kiki'
print(age)
def demo():
age = 18
print(name)
2.局部名称空间嵌套
先从自己的局部名称空间查找,之后由内而外依次查找
正确版本:
eg1:
goal = '每天能够准时吃饭!!!'
def demo():
goal = '每天按时完成博客!!'
def demo1():
goal = '每天按时完成录音!!'
def demo2():
goal = '每天按时完成作业!!'
def demo3():
goal = '剩余时间预习第二天课程!!'
demo3()
demo2()
demo1()
demo()
print(goal) # 每天能够准时吃饭!!!
图如下
错误版本:
eg:
goal = '每天能够准时吃饭!!!'
def demo():
goal = '每天按时完成博客!!'
def demo1():
goal = '每天按时完成录音!!'
def demo2():
demo2()
goal = '每天按时完成作业!!'
def demo3():
# goal = '剩余时间预习第二天课程!!'
demo3()
demo1()
demo()
print(goal) # IndentationError: expected an indented block 直接报错
""
"函数体代码中名字的查找顺序在函数定义阶段就已经固定死了
"""
上述例题查找的顺序如下
global与nonlocal关键字
1.global的用法
1.当不使用global时
number = 89
def index():
number = 34
index()
print(number) # 89
2.使用了global
number = 89
def index():
global number
number = 34
index()
print(number) # 34
"""
局部名称空间直接修改全局名称空间中的数据
"""
2.nonlocal的用法
1.当不使用nonlocal时
def index():
name = 'kiki'
def inner():
name = 'kimi'
inner()
print(name) # kiki
index()
2.当使用了nonlocal
def index():
name = 'kiki'
def inner():
nonlocal name
name = 'kimi'
inner()
print(name) # kimi
index()
"""
内层局部名称空间修改外层局部名称空间中的数据
"""
函数名的多种用法
函数名其实绑定的也是一块内存地址,只不过该地址里面存在的不是数据值,而是一段代码,函数名加括号就会找到代码并执行。函数对象指的是可以被当作‘数据’来处理,具体可分为四个方面的使用
1.可以当作变量名赋值
def index():
pass
res = index
res() # res() == index()
print(res) # <function index at 0x00000213D09461F0>
2.可以当做函数的参数
def index():
print('今天是10月11号')
def func(a):
print(a) # a=index <function index at 0x000002CCA40E61F0>
a() # a()==index() 直接调用index() 输出 ‘今天是10月11号’
func(index)
3.可以当作函数的返回值
1.返回值返回第一个函数名
def index():
print('天气晴')
def func():
print('适合出门')
return index
res = func() # 第一步看赋值的右边,调用func()函数输出‘适合出门’,返回index函数名给res
print(res) # 打印出index的函数名的内存地址 <function index at 0x0000028E8C7361F0>
res() # res() == index() 直接调用index()函数,输出‘天气晴’
2.返回值返回第二个函数名
def index():
print('天气晴')
def func():
print('适合出门')
return func
res = index() # 第一步看赋值的右边,调用index()函数输出‘天气晴’,然后到return返回func
print(res) # 打印出func的函数名内存地址 <function index.<locals>.func at 0x000002876A56A4C0>
res() # res() == func() 直接调用func()函数,输出‘适合出门’
4.可以当作容器类型(可以存放多个数据的数据类型)的数据
1.第一种方式----基础版
def register():
print('注册功能')
def login():
print('登录功能')
def withdraw():
print('提现功能')
def transfer():
print('转账功能')
def shopping():
print('购物功能')
while True:
print("""
1.注册功能
2.登录功能
3.提现功能
4.转账功能
5.购物功能
""")
choice = input('please input your choice>>>:').strip()
if choice == '1':
register()
elif choice == '2':
login()
elif choice == '3':
withdraw()
elif choice == '4':
transfer()
elif choice == '5':
shopping()
else:
print('查无编号!!!!')
2.第二种方式-----升级版
def register():
print('注册功能')
def login():
print('登录功能')
def withdraw():
print('提现功能')
def transfer():
print('转账功能')
def shopping():
print('购物功能')
demo_dict = {
'1':register,
'2':login,
'3':withdraw,
'4':transfer,
'5':shopping
}
while True:
print("""
1.注册功能
2.登录功能
3.提现功能
4.转账功能
5.购物功能
""")
choice = input('please input your choice>>>:').strip()
if choice in demo_dict:
# demo_dict.get(choice)()
name = demo_dict.get(choice)
name()
else:
print('查无编号')
闭包函数
定义在函数内部的函数,并且用到了外部函数名称空间中的名字
1.定义在函数内部
2.用到外部函数名称空间中的名字
def demo():
name = 'kiki'
def inner():
print(name)
""" 第二个函数里name用到了第一个函数name,称为闭包函数 """
闭包函数实际应用:是另外一种给函数体代码传参的方式
方式1:给函数体代码传参(代码里面缺什么变量名形参里面就补什么变量名)
def stu_class(name,age):
print(f"""
姓名:{name}
年龄:{age}
""")
stu_class('kimi',18)
""" 这种方式,输入一次参数就打印出的结果只有一个"""
方式2:闭包函数
def stu_class(name,age):
# name = 'kiki'
# age = 18
def register():
print(f"""
姓名:{name}
年龄:{age}
""")
return register
res = stu_class('kiki',18)
res()
res()
res = stu_class('kimi',20)
res()
res()
""" 这种可以连续输出好几个信息"""
对比信息图如下
解析步骤如下:
对比信息图如下
作业
1..判断下列money的值是多少并说明理由 思考如何修改而不是新增绑定关系
money = 100
def index():
money = 666
print(money)
答:money输出结果为100,第一步money绑定100,接下走def index(),函数体代码不走,print输出的时全局名称空间的money。
money = 100
def func1():
money = 666
def func2():
money = 888
func2()
print(money)
答案:money 为100,func1为调用,此时的money还是全局名称空间的money
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了