前言
前面我们已经学习了Python的基础语法,了解了Python的分支结构,也就是选择结构、循环结构以及函数这些具体的框架,还学习了列表、元组、字典、字符串这些Python中特有的数据结构,还用这些语法完成了一个简单的名片管理系统。下面我就将介绍一下Python的一些进阶语法规则,为后面更复杂的编程打下基础。
-
闭包与装饰器
什么是闭包、装饰器函数、yield关键字 -
python高阶函数
lambda匿名函数、reduce函数、map函数、filter过滤器函数 -
面向对象编程
什么是面向对象、对象的封装、类的继承、类的多态 -
进程与线程编程
python中的进程与线程、多线程编程
第一章. 闭包与装饰器
1. 什么是闭包
# coding=utf-8
# 闭包
# def func1():
# print ("函数1运行")
# return func2()
# #函数1的返回值是函数2的引用
# def func2():
# print ("函数2运行")
# return 2
# r =func1()
# print (r)
# r2= r() # r = func2
# print (r2)
def func1():
print ("函数1运行")
def func2():
print ("函数2运行")
func2()
return func2()
f2 = func1()
print(f2)
f2()
"""
在一个函数,比如func1中的内部定义了另外一个函数function2
并且函数1(func1)的返回值是函数2(func2)的引用
这种情况,我们称之为闭包
简单来说就是外部函数返回内部函数的引用就叫做闭包
"""
print打印结果:
函数1运行
函数2运行
函数2运行
None
案例:龟兔赛跑
# coding=utf-8
import time
import random
# 定义跑道长度
track_length = 10
def runtime(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print (func.__name__,"运行时间是",end_time-start_time,"秒")
return wrapper
@runtime
def tortoise():
# for i in [1,2,3,4,5,6,7,8,9,10]:
for i in range(1,track_length+1):
print ("乌龟跑的{}米".format(i))
time.sleep(1)
@runtime
def rabbit():
for i in range(1,track_length + 1):
if i % 5 == 0:
time.sleep(random.randint(1,10))
print ("兔子跑了{}米".format(i))
tortoise()
rabbit()
print打印结果:
乌龟跑的1米
乌龟跑的2米
乌龟跑的3米
乌龟跑的4米
乌龟跑的5米
乌龟跑的6米
乌龟跑的7米
乌龟跑的8米
乌龟跑的9米
乌龟跑的10米
tortoise 运动时间是 10.04876708984375 秒
兔子跑了1米
兔子跑了2米
兔子跑了3米
兔子跑了4米
兔子跑了5米
兔子跑了6米
兔子跑了7米
兔子跑了8米
兔子跑了9米
兔子跑了10米
rabbit 运动时间是 9.022485494613647 秒
2. 什么是装饰器呢?
就是在特定条件下为某些函数再不改动函数体的时候为函数新添加一些功能,这就是装饰器
实现原理:
基于@语法和函数闭包,将原函数封装在闭包中,然后将函数赋值为一个新的函数(内置函数),执行函数时再在内层函数中执行闭包中的原函数
实现效果:
可以在你改变函数内部代码和调用的前提下,实现在函数执行和执行拓展功能
适用场景:
多个函数系统统一在执行前后定义一些功能
关于前言我们了解这么多就够了,然后小编带着大家推导出装饰器
装饰器:
装饰器的写法:
这里我们有一个需求,我们定义了5个函数,想在5个函数执行前和执行后都打印一句话:装饰器的学习。首先我们来写于一下没有装饰器的写法,话不多说直接上代码:
def a():
pass
def b():
pass
def c():
pass
def d():
pass
def e():
pass
先定义5个函数,再加上我们要打印的话:
def a():
print("装饰器的学习")
print("装饰器的学习")
def b():
print("装饰器的学习")
print("装饰器的学习")
def c():
print("装饰器的学习")
print("装饰器的学习")
def d():
print("装饰器的学习")
print("装饰器的学习")
def e():
print("装饰器的学习")
pass
print("装饰器的学习")
a()
b()
c()
d()
e()
运行一下:
发现运行成功,但我们想如果我要修改打印的话就要都修改一次,特别麻烦,而且,这是5个函数如果是500个,我们还要一个一个的去加吗?这就有我们的装饰器了,首先我用装饰器修改下,再给大家解释。
def outer(origin):
def inner():
print("装饰器的学习")
res = origin()
print("装饰器的学习")
return res
return inner
@outer
def a():
pass
@outer
def b():
pass
@outer
def c():
pass
@outer
def d():
pass
@outer
def e():
pass
a()
b()
c()
d()
e()
运行一下:
发现这样我们也成功了,接下来小编来个大家解释
首先:
我们要明白@的作用,那我们的函数a来举例子@的作用就是帮我们执行一次a=outer(a),首先python将把我们的a变成参数传给outer函数,运行后再赋值给a,这就是@的作用。
其次给大家解释一下自定的outer函数
我自己称这个函数为@下函数的补丁函数,也就是装饰器函数还是拿a函数举例子,首先a函数变成参数传给了我们的outer函数,outer里又嵌套了一个inner函数 ,然后将函数a赋值给res,然后用return语句返回出结果,外层函数返回inner函数,也就是将inner函数运行一次,这就是工作流程。
最后分别在各函数前加上装饰,最后运行出结果
这就是装饰器的写法。
装饰器的参数
这时我遇到一个问题如果函数内有参数而且每个函数的参数数量不同,我们应