Python之高级特性<3>--(装饰器、内置高阶函数与异常)

一、装饰器

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之间")

执行如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值