1. 闭包
闭包,个人理解就是:闭包 = 函数 + 环境变量。
一个简单的闭包例子如下。
def curve_pre():
a = 25 # 闭包的环境变量
def curve(x):
return a * x * x
return curve
f = curve_pre() # 返回一个函数
f(3) # 调用函数
print(f.__closure__[0].cell_contents) # 取出闭包的环境变量25
闭包的意义,她保存的是一个环境,她把现场保存了下来。
def f1():
a = 25
def f2():
a = 30 # a 此时被认为是一个局部变量,不影响外部a的取值,此时闭包是不存在的
print(a) # 打印30
return a
print(a) # 打印25
f2()
print(a) # 打印25
return f2
f = f1()
一个简单的问题以及解决它的思路,包括不使用闭包和使用闭包两种解决方式。
# 一个问题:一个旅行者,计算路线的长度,x=0代表起点,每走一步加一
# 先走3步,result = 3
# 走5步,result = 8
# 走6步,result = 14
# 问题的关键在于要保存中间过程
# 不用闭包的解决思路
x = 0 # 全局变量
def walk(step):
global x # 解决方法是global
new_x = x + step # 不加global 这里会报错
x = new_x # 不加global,此处x被当做一个局部变量,没有定义,所以会报错
return x
print(walk(3))
print(walk(5))
print(walk(6))
# 用闭包的方式解决
origin = 0
def factory(pos):
def go(step):
nonlocal pos # 声明pos不是局部变量
new_pos = pos + step
pos = new_pos
return new_pos
return go
tourist = factory(origin)
print(tourist(3))
print(tourist(5))
print(tourist(6))
2.匿名函数和 三元表达式
借助lambda实现匿名函数。
以下是一个简单的例子,正常函数和匿名函数实现两个数相加,比较之下,显然,匿名函数更加简洁,可读性更高,体现了Python的优势。
def add(x, y):
return x+y
f = lambda x,y: x+y # 没有名字,不用return,简洁,冒号后面只能是表达式
print(add(1, 2))
print(f(1, 2))
三元表达式
# 三元表达式 x > y ? x : y
# python如何实现三元表达式
r = lambda x,y: x if x>y else y
print(r(2,3))
3. map
# map
# 计算一个列表所有元素的平方
list_x = [1,2,3,4,5,6]
list_y = [1,2,3,4,5,6]
# 第一种方法,传统的方法
def square(x):
return x * x
for x in list_x:
print(square(x))
# 用map实现, map会把list中的每一项都传入函数,可以理解为一个映射
m = list(map(square, list_x))
print(m)
# map的真正作用,与lambda一起用,不能提高效率,但代码变得更加简洁
m = list(map(lambda x: x*x, list_x)) # 匿名函数
print(m)
# map的参数可以不止一个
m = list(map(lambda x,y:x*x+y, list_x, list_y))
print(m)
4. reduce
# reduce
from functools import reduce
r = reduce(lambda x,y:x+y, list_x) # 连续计算,连续调用lambda,每一次计算结果变成下一次计算的参数
# ((1+2)+3)+ ....
print(r)
5. filter
# filter: 过滤
list_x = [1,0,1,0,0,1]
r = list(filter(lambda x: True if x == 1 else False, list_x)) # 返回False,过滤0
print(r) # [1, 1, 1], 过滤了0
6. 装饰器
# 装饰器:最有用的高阶知识
import time
def f1(): # 一个简单的函数,先输出时间,再打印信息
print(time.time()) # 一个时间戳
print('this is a function')
f1()
# 假如有100个函数同时要打印time.time()呢,难道要写100次?显然不行!
def f2():
print('this is a function')
def f3():
print('this is a function')
def print_current_time(func): # 接收一个函数参数
print(time.time())
func()
# 这种方法其实本质上并没有改变
print_current_time(f2)
print_current_time(f3)
# 如何更优雅的实现呢, 这就是装饰器的好处
import time
def decorator(func):
def wrapper(*args, **kw): # 接收可变参数和关键字参数,装饰器才有意义
print(time.time())
func(*args, **kw)
return wrapper
f = decorator(f2) # 但是这种调用方式也是很麻烦,如何改进?
f()
# 如何更优雅的实现呢
@decorator
def f4():
print('this is a function')
f4() # 没有改变原来调用的方式
# 如果f函数有参数呢,装饰器要做什么改变吗,要把装饰器的内置函数变成可变参数*args
@decorator
def f5(func_name):
print('this is a function:' + func_name)
f5('fun1')
@decorator
def f6(func_name1, func_name2):
print('this is a function:' + func_name1)
print('this is a function:' + func_name2)
f6('fun1','fun2')
# 如果f函数有关键字参数呢,装饰器要做什么改变吗,要把装饰器的内置函数加上**kw关键字参数
@decorator
def f7(func_name1, func_name2, **kw): # kw是关键字参数
print('this is a function:' + func_name1)
print('this is a function:' + func_name2)
print(kw)
f7('testfun1', 'testfun2', a=1, b=2, c='123')