一、函数对象
- 函数可以被引用
- 函数可以作为函数的参数
- 函数可以作为函数的返回值
- 可以被存储到容器类型中
引用
def func1():
print("run")
a = func1() #run
可以当参数传给另外一个函数
def func1():
print('run')
def func2(f):
f()
func2(func1) #run
可以当作一个函数的返回值
def func1():
print('run')
def func3():
return func1
f = func3()
f()
print(f) #<function func1 at 0x000001A62CDD2E18>
print(func1) #<function func1 at 0x000001A62CDD2E18>
可以当作容器类型的元素
def func4():
print("func4 run")
list = [func4]
list[0]() #func4 run
示范1:
def login():
print("登陆")
def register():
print("注册")
def shopping():
print("购物")
res = input("请选择功能名称:")
funcdic = {"login":login,"register":register,"shopping":shopping}
if res in funcdic:
funcdic[res]()
else:
print("输入有误!")
示范2:
def register():
print('注册')
def login():
print('登陆')
def shopping():
print('购物')
def pay():
print('支付')
func_dic={
'1':register,
'2':login,
'3':shopping,
'4':pay
}
while True:
print("""
0 退出
1 注册
2 登陆
3 购物
4 支付
""")
choice=input('>>>: ').strip()
if choice == '0':break
if choice in func_dic:
func_dic[choice]()
else:
print('输入错误的指令')
二、函数嵌套
- 嵌套定义:在一个函数中定义了另一个函数
- 嵌套调用:在一个函数中调用了另一个函数
- 注意:定义在函数内的函数只能函数内使用 外界不能访问
示范1:
def func1():
print("func1")
def func2():
print("func2")
func1()
func2() #func2、func1
示范2:
def func1():
print("func1")
def func2():
print("func2")
func2() #内部函数只能内部函数调用
func1() #func1、func2
示范3:
from math import pi
def circle(radius,mode=0):
def perimiter(radius):
return 2 * pi * radius
def area(radius):
return pi * (radius ** 2)
if mode == 0:
return perimiter(radius)
elif mode == 1:
return area(radius)
print(circle(10,0))
print(circle(10,1))
示范4:
def max2(x,y):
if x > y:
return x
else:
return y
def max4(a,b,c,d):
res1=max2(a,b)
res2=max2(res1,c)
res3=max2(res2,d)
return res3
print(max4(1,2,3,4))
三、名称空间
-
什么的名称空间:存储名称的空间
-
名称空间的分类:
-
内置名称空间:存储解释器自带的一些名称与值的对应关系(python解释器启动时创建 所有代码全部执行完毕 关闭解释器时 销毁)
-
全局名称空间: 只要你的名字的定义是顶着最左边写的就在全局空间,除了内置的函数内的 都在全局中(执行py文件创建全局名称空间 关闭解释器时 销毁)
-
局部名称空间:只要是函数内的名称就是局部的(调用函数时创建 函数执行完毕就销毁)
- 名称空间的加载顺序
内置的 -> 全局的 ->局部的
- 名称的查找顺序
局部的 -> 全局的 -> 内置的
-
四、作用域(作用范围)
-
什么是作用作用域:域指的是区域、范围的的意思
-
全局的名称空间和内置的名称空间在使用上没什么区别,局部的和全局的内置的就区别了,局部定义的只能在局部使用
-
给三个空间划分范围:
全局的和内置可以划分为同一个范围,globals()表示的全局范围 就是所谓的全局作用域
局部的单独划分为一个范围,locals()表示局部作用域
注意:你在全局中使用locals看到的就是全局的内容与globals没有区别
print(locals()) print(globals())
print(dir(globals()["__builtins__"])) #查看全局作用域中的内容
a = 'ssssssssss'
print(globals()) #返回当前位置的全部全局变量
示范1:
def func():
a = 100
print(locals())
func() #查看局部变量的内容 {'a': 100}
示范2:
age = 18
def func2():
# 明确声明 要使用全局中的age
global age
age = 19
print(age)
func2() # 19
print(age) # 19
示范3:
l=[]
def func():
l.append(111)
l.append(222)
func()
print(l) #[111, 2222]
示范4:
a = 1
def func3():
a = 10
def inner():
# 明确声明要使用上一中的a,如果上一层没有,则找上上层,但是注意不能找到全局中的
nonlocal a
a = 100
print(a)
inner()
print("这是func3中a",a)
func3() #inner内部a的值为100 func3外部函数a的值为100
print(a) #全局变量a的值为1
总结:
global适用于函数内部修改全局变量的值
nonlocal适用于嵌套函数中内部函数修改外部变量的值
五、闭包函数
- 闭包函数也是一个函数
- 与普通函数的区别:
- 定义在另一个函数中的
- 在这个内部的函数中使用了外部的名称
示范1
age = 20
# 如下就是一个闭包函数
def fun1():
age = 18
def inner():
print("hello")
print(age)
# 在返回这个内部的函数时,不是单纯的返回函数,还把函数中访问到的局部名称一起打包了
# 相当于将内部函数与访问的数据打包在一起了,闭包这个名字就是这么得来的
return inner
f = fun1() # f 就是inner
f() #打印hello、18
c = 1000
def func2():
a = 1
b = 10
def inner():
print(a)
print(b)
print(c)
return inner
f = func2()
f() #分别打印1、10、1000
#__closure__用于访问闭包时打包的数据
print(f.__closure__[0].cell_contents) #1
print(f.__closure__[1].cell_contents) #10
六、装饰器
-
什么时装饰器:给一个已有的对象(一个函数) 添加新的功能
装饰器本身可以是任意可调用对象
被装饰对象本身也可以是任意可调用对象
-
为何要用装饰器:开放封闭原则:对修改封闭,对扩展开发
简单的说:装饰器就是 一个用于给其他函数增加功能的函数
示范1
import time
def download2():
start_time = time.time()
print("开始下载xxx.mp4")
time.sleep(2)
print("xxxx.mp4 下载完成!")
end_time = time.time()
print("下载耗时", (end_time - start_time))
download2()
示范2
import time
def download():
print("开始下载xxx.mp4")
time.sleep(2)
print("xxxx.mp4 下载完成!")
def outter(func):
a = 1
print(locals(),"xxxxxx")
def inner():
#在调用原始函数前 增加新功能
func()
# print(inner)
return inner
download = outter(download)
download()
import time
def outter(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper
@outter
def index():
time.sleep(1)
print('welcome to index page')
return 1234
#index()
print(index())