一、装饰器
1.引入
# 1. 装饰器: 用来装饰函数的工具。
# 2. 功能: 在不改变源代码的情况下, 添加额外功能(eg: 计算运行时间, 记录日志,权限判断)的工具.
# 3. 如何实现装饰器? 基于闭包的
import time
def timeit(f): # f=add
def wrapper(x, y):
start = time.time()
result = f(x, y) # f实质上是add函数
end = time.time()
print("函数运行的时间为: %.4f" %(end-start))
return result
return wrapper
@timeit # 1. 语法糖, add=timeit(add)
def add(x, y):
return x + y
result = add(1, 3)
print(result)
#
# def max(x, y):
# return x if x > y else y
#
#
# def my_sum(*args):
# return sum(args)
执行如下:
2.万能装饰器的实现
"""
装饰器的万能模板:
def 装饰器名称(f):
@wraps(f) # 保留被装饰函数的属性信息和帮助文档
def wrapper(*args, **kwargs):
# 执行函数之前做的事情
result = f(*args, **kwargs)
# 执行函数之后做的事情
return result
return wrapper
"""
# 需求: 计算函数的运行时间
import time
from functools import wraps
def timeit(f):
"""计时器的装饰器"""
@wraps(f) # 保留被装饰函数的属性信息和帮助文档
def wrapper(*args, **kwargs):
"""wrapper内部函数"""
start = time.time()
result = f(*args, **kwargs)
end = time.time()
print(f"函数{f.__name__}运行时间为{end-start}秒")
return result
return wrapper
@timeit
def login():
"""login desc"""
print('login....')
@timeit
def crawl():
import requests
url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/Python.svg/1200px-Python.svg.png'
content = requests.get(url).content
with open('doc/python.png', 'wb') as f:
f.write(content)
print("下载图片成功")
print(help(login))
login()
crawl()
执行如下:
3.含参数的装饰器
# 需求: 计算函数的运行时间
import time
from functools import wraps
def timeit(args='seconds'):
def desc(f):
"""计时器的装饰器"""
@wraps(f) # 保留被装饰函数的属性信息和帮助文档
def wrapper(*args, **kwargs):
"""wrapper内部函数"""
start = time.time()
result = f(*args, **kwargs)
end = time.time()
if args == 'seconds':
print(f"函数{f.__name__}运行时间为{end-start}秒")
elif args == 'minutes':
print(f"函数{f.__name__}运行时间为{(end-start)/60}秒")
return result
return wrapper
return desc
@timeit(args='minutes') # timeit() @desc===> login=desc(login)
def login():
"""login desc"""
print('login....')
@timeit
def crawl():
import requests
url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/0/0a/Python.svg/1200px-Python.svg.png'
content = requests.get(url).content
with open('doc/python.png', 'wb') as f:
f.write(content)
print("下载图片成功")
print(help(login))
login()
# crawl()
4.多装饰器
from functools import wraps
def is_login(f):
@wraps(f)
def wrapper1(*args, **kwargs):
print('is_login, 用户是否登录')
result = f(*args, **kwargs)
return result
return wrapper1
def is_permission(f):
@wraps(f)
def wrapper2(*args, **kwargs):
print('is_permission, 用户是否有权限')
result = f(*args, **kwargs)
return result
return wrapper2
# 规则: 执行装饰器内容是从上到下。 被装饰的顺序是从下到上。
@is_login # show_hosts=is_login(wrapper2) show_hosts=wrapper1
@is_permission # show_hosts = is_permission(show_hosts) show_hosts=wrapper2
def show_hosts():
print("显示所有的云主机")
"""
--: show_hosts()
1). wrapper1()
2). wrapper2()
3). show_hosts()
"""
show_hosts()
执行如下:
二、内置高阶函数
# 1. map函数
result = map(lambda x: x ** 2, [1, 2, 4, 5])
print(list(result))
result = map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])
print(list(result))
# 2. reduce函数
from functools import reduce
# (((1+2)+3)+4)+5=reduce result
result = reduce(lambda x, y: x + y, [1, 2, 3, 4, 5])
print(result)
# 3. filter:
# 筛选所有的偶数
result = filter(lambda x: x % 2 == 0, [1, 2, 4, 5, 8])
print(list(result))
# 筛选所有的奇数
result = filter(lambda x: x % 2 != 0, [1, 2, 4, 5, 8])
print(list(result))
# 4. sorted:
result = sorted([1, 29, 2, 3])
print(result)
result = sorted([0, 29, 2, 0], reverse=True)
print(result)
result = sorted([0, 8, 9, 0, 16], key=lambda x:0 if x==0 else 1)
print(result)
执行如下:
# 练习: 求1*2*..100的结果, 用reduce和匿名函数实现
from functools import reduce
# (((1+2)+3)+4)+5=reduce result
result = reduce(lambda x, y: x * y, range(1,101))
print(result)
执行如下:
三、异常
1.常见的异常
# print(a) # NameError
# print(10/0) # ZeroDivsionError
# d = {'name':'westos'}
# print(d['age']) # KeyError
# with open('hello.txt') as f: # FileNotFoundError
# pass
# age = 18
# if age == 18:
# print('成年')
# else:
# print('未成年')
2.异常处理机制
"""
异常处理机制:
else:没有异常时,执行的内容
finally: 总会执行的内容
"""
try:
a = 1
print(b)
except NameError as e:
print('0-name error')
except KeyError:
print('4-key error')
except Exception as e:
print('1-exception')
else:
print('2-no error')
finally:
print('3-run code')
执行如下:
3.抛出异常
age = int(input('age:'))
if 0<age<150:
print(age)
else:
# 抛出异常
raise ValueError("年龄必须在0~150之间")
执行如下:
4.自定义异常
# 自定义的异常
class AgeError(ValueError):
pass
age = int(input('age:'))
if 0<age<150:
print(age)
else:
# 抛出异常
raise AgeError("年龄必须在0~150之间")
执行如下: