一、函数的嵌套和作用域链
1.函数的嵌套调用
def max(x,y): m = x if x > y else y return m def max1(a,b,c,d): res1 = max(a,b) res2 = max(res1,c) res3 = max(res2,d) return res3 print(max1(23,-7,31,11))
2.函数的作用域链
小范围作用域可以使用大范围的变量,但是反之不行
def f1(): a = 1 def f2(): def f3(): print(a) f3() #1 f2() f1()
3.函数名
函数名本质上就是函数的内存地址
(1)可以被引用
def func(): print("in func") f = func print(f) #<function func at 0x0000021011E51E18>
(2)可以被当作容器类型的元素
函数名
被当作容器类型的元素
def f1(): print("f1") def f2(): print("f2") def f3(): print("f3") l = [f1,f2,f3] d = {"f1":f1,"f2":f2,"f3":f3} l[0]() #f1() d["f2"]() #f2()
(3)可以当作函数的参数和返回值
函数名
当作函数的参数和返回值
def f1(): print("f1") def f2(argv): argv() return argv f = f2(f1) f()
(4)函数名可以赋值给其他变量
def func2(): print(222) def func3(x): print(a) return a a = 3 ret = func3(a) print(ret)
二、第一类对象(first——clss object)
1.可运行期创建
2.可用做函数参数或返回值
3.可存入变量的实体
三、闭包
内层函数,对外层函数(非全局)的变量的引用,叫做闭包
作用:保护内存
1.闭包函数
def wrapper(): name = "alex" def inner(): print(name) #alex inner() wrapper()
2.检查是不是闭包
cell 是闭包,none就不是闭包(面试题)
def wrapper(): name = "alex" def inner(): print(name) #alex inner() print(inner.__closure__) #cell 是闭包 wrapper()
在外层函数内部,执行inner()
def wrapper(): def inner(): print(666) return inner wrapper()() def wrapper(): def inner(): print(666) inner() wrapper()
3.闭包的用处
如果说你内存函数是个闭包,python内部有一个
机制,遇到闭包,他会在内存中开启有一个内存空间,不会关闭。
避免来回开关,不会随着函数的结束而关闭。
直到关闭python解释器,或python内部来回巡回,才会关闭
4.爬虫
from urllib.request import urlopen print(urlopen("http://www.cnblogs.com/jin-xin/articles/8259929.html").read()) #url 访问某个程序的路径 #uri 访问某个程序路径的 一部分 # 协议名 http https # 域名 cnblogs.com # 项目名 jin-xin # 模块名 articles # 页面名 8259929.html def index(url): content = urlopen(url).read() def get(): with open("爬虫","a") as f1: f1.write(content.decode("utf-8")) return get index("http://www.cnblogs.com/jin-xin/articles/8259929.html")()
四、装饰器
1.什么是装饰器?
装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,
装饰器的返回值也是一个函数对象。
2.装饰器的应用场景
比如插入日志,性能测试,事务处理,缓存等等场景。
3.简单的装饰器
import time def timmer(f): def inner(): start_time = time.time() time.sleep(0.1) f() end_time = time.time() print("执行效率%s"%(end_time - start_time)) return inner @timmer #func = timmer(func) #语法糖,需要放在你像测试函数上面。没有空格。python内部封装语法糖。python内部机制 def func(): print("完成") func()
4.带参数的装饰器
import time def timmer(f): def inner(a): start_time = time.time() time.sleep(0.1) f(a) end_time = time.time() print("执行效率%s"%(end_time - start_time)) return inner @timmer #func = timmer(func) #语法糖,需要放在你像测试函数上面。没有空格。python内部封装了。python内部机制 def func(a): print("%s完成"%a) func("萌哥")
import time flag = True def timmer_out(flag): def timmer(func): def inner(*args,**kwargs): if flag : start = time.time() time.sleep(0.3) ret = func(*args,**kwargs) end = time.time() print("执行效率%s"%(end - start)) return ret else: ret = func(*args,**kwargs) return inner return inner return timmer @timmer_out(flag) #1.先判断一下,True或者False 2. @timmer def f1(): print(666) @timmer_out(flag) def f2(): print(777) f1() f2()
5.带返回值装饰器
import time def timmer(f): #func def inner(*args,**kwargs): #"萌哥" start_time = time.time() time.sleep(0.1) ret = f(*args,**kwargs) #func("萌哥"),ret==222 end_time = time.time() print("执行效率%s"%(end_time - start_time )) return ret return inner @timmer #func = timmer(func) def func(a): return 222 print(func("萌哥")) 222
6.通用装饰器
def wrapper(func): def inner(*args,**kwargs): "执行函数前的操作" ret = func(*args,**kwargs) "执行函数后的操作" return ret return inner @wrapper def func(a): print(1) print(func(a))
7.多个装饰器装饰一个函数
def wrapper1(func): def inner(): print("wrapper1,before func") func() print("wrapper1,after func") return inner def wrapper2(func): def inner(): print("wrapper2,before func") func() print("wrapper2,after func") @wrapper2 @wrapper1 def f(): print("in f") f()
五、补充知识
1.函数的有用信息
def f1(): ‘‘‘ 本函数的功能:绘图功能,实时接收数据并绘图. :return: 绘图需要的数据,返回给前端某标签 ‘‘‘ print(f1.__doc__) print(f1.__name__) print(666) f1() # print(f1.__doc__) #获取函数的说明信息 # print(f1.__name__) # 获取函数的名字
2.开放封闭原则
1.对扩展是开放的
2.对修改是封闭的
3. *
在执行函数时,加*时打散。
在接受函数时,加*时聚合
def f1(*args,**kwargs): print(args) # (1, 2, 3, 4) # 执行函数时,不加*是聚合。接受函数时加*时聚合 print(*args) #1 2 3 4 # 执行函数时打散,没有任何数据类型 。print()也是一个函数 f1(1,2,3,4) def f1(*args,**kwargs): print(args) # (1, 2, 3, 4) # 执行函数时,不加*是聚合。接受函数时加*时聚合 print(*args) #1 2 3 4 # 执行函数时打散,没有任何数据类型 。print()也是一个函数 f1(*[1,2,3,4])