课程目标
- 理解Python中函数即变量
- Map函数
- Reduce函数
- 匿名函数
- 装饰器(设计模式)基于以上理论
理解Python中函数即变量
• 变量可以指向函数
• 函数名也是变量
• 传入函数
• 函数本身也可以赋值给变量,即:变量可以指向函数
Python内置的map函数
• map()函数接收两个参数,一个是函数,一个是Iterable
• map将传入的函数依次作用到序列的每个元素,并把结果作为
新的Iterator返回
• >>> def f(x):
… return x * x
…
>>> r = map(f, [1, 2, 3, 4, 5, 6, 7]) >>> list(r)
[1, 4, 9, 16, 25, 36, 49]
Python内置的reduce函数
• reduce把一个函数作用在一个序列[x1, x2, x3, …]上 ,reduce
把结果继续和序列的下一个元素做累积计算
• reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) • 把序列[7,8,3,4,9,7]变换成整数783497
>>> from functools import reduce
>>> def fn(x, y):
... return x * 10 + y
>>> reduce(fn, […])
装饰器模式原理
• 在代码运行期间动态增加功能的方式,称为“装饰器”
(Decorator) • @property
• @setter
# abs(-10)函数调用,abs是函数本身
print(abs(-10))
# abs = 10
#
# abs函数被覆盖掉
# 把函数当作参数传递给其他函数
# 代理模式在平常开发时非常常用
def add(x,y,f):
return f(x)+f(y)
print(add(-5,-6,abs))
'''
map函数
'''
l = [1,2,3,4,5,6,7,8,9,]
def f(x):
return x*x
m = map(f,l)
print(m)
print(list(m))
# l 列表中每个int转换成字符串
l = [1,2,3,4,5,6,7,8,9,]
print(list(map(str,l)))
# 把一个list组成一个整数
l= [4,2,5,7,8,9]
from functools import reduce
def f(x,y):
return x*10 + y
print(reduce(f,l))
print(type(reduce(f,l)))
#str() int() 内部实现的原理
# '5632'==》5632
# 1.把字符串每个元素取出来,转化成对应的数字,得到一个数字序列
# 2.两个数字序列每两个乘以10 相加,得到一个整数
def f(x,y):
return x*10 + y
def char2num(s):
digits = {
'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}
return digits[s]
s1 = '5632'
nums = reduce(f,map(char2num,s1))
print(nums)
'''
匿名函数 在函数中去定义函数,只被当前定义的函数所调用
'''
DIGITS = {
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}
def str2int(s):
def f(x, y):
return x * 10 + y
def char2num(s):
return DIGITS[s]
return reduce(f,map(char2num,s))
print(str2int('6463745'))
# lambda 表达式
def str2int(s):
def char2num(s):
return DIGITS[s]
return reduce(lambda x,y:x*10+y,map(char2num,s))
print(str2int('234'))
'''
装饰器的使用
'''
# 面试的时候都问装饰器(热点问题)
import datetime
# 定义一个装饰器来升级now函数 以一个函数作为参数,并返回一个函数
def log(f):
#匿名函数
def writediary(*args,**kw): #对参数没有限制
# 把返回值返回给s,不用写close
with open('./a.txt','w') as f1:
f1.write(f.__name__)
print('写入日志成功,函数名字是;%s'%f.__name__)
return f(*args,**kw)
return writediary
#装饰器调用 @
@log
def now():
print(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
#调用方式1
# ff = log(now)
#
# ff()
# 调用方式2
now()
'''
Python内置的装饰器 @property @setter
'''
class Student(object):
def __init__(self,score):
self.__score = score
def get_score(self):
return self.__score
def set_score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self.__score = value
stu1 = Student(90)
print(stu1.set_score(85))
print(stu1.get_score())
# 加上装饰器,方法变属性
class Student(object):
def __init__(self,score):
self.__score = score
@property
def score(self):
return self.__score
@score.setter
def score(self, value):
if not isinstance(value, int):
raise ValueError('score must be an integer!')
if value < 0 or value > 100:
raise ValueError('score must between 0 ~ 100!')
self.__score = value
stu2 = Student('67')
stu2.score = 59
print(stu2.score)
# 作业
# #
# # • 利用map()函数,把用户输入的不规范的英文单词,变为首字母大
# # 写,其他小写的规范名字。输入:
# # [‘MIKE’, ‘Adidas’, ’coffee‘],输出:
# # [’Mike‘, ’Adidas‘, ’Coffee‘]:
#
#方式一
# def normalize(name):
# result = name[0].upper() + name[1:].lower()
# return result
#
#
# L1 = ['MIKE', 'Adidas', 'coffee']
# L2 = list(map(normalize, L1))
#
# print(L2)
#方式二
# L = ['adam','LISA','TOM']
# def normalize(name):
# return list(map(lambda x:x.capitalize(),name))
# print(normalize(L))
# • 请设计一个装饰器,它可以作用于任何函数上,打印函数执行时间:
# def metric(fn):
# print('%s executed in %s ms' % (fn.__name__, 10.24))
# return fn
import time
def metric(fn):
# 匿名函数
def execute_time(*args,**kwargs):
#起始时间
start_time = time.time()
#外部传入的参数(函数传参)
l=fn(*args,**kwargs)
#结束时间
end_time = time.time()
print('耗时:{:.4f}s'.format(end_time - start_time))
return l
#返回函数的值
return execute_time
# 装饰器用法,相当于metric(exexute_fn)
@metric
# 定义一个普通的遍历函数
def execute_fn(int):
boss = 0
for i in range(int):
boss += i
i += 1
return boss
# 在装饰器的作用下,相当于调用了metric函数中的execute_time函数,metric(execute_fn)
execute_fn(12000)