Python超快速入门基础知识——函数进阶:生成器、闭包、装饰器、高阶函数

本文详细讲解了Python中的生成器、闭包、装饰器和高阶函数的概念及应用。通过实例演示了生成器的两种实现方式,深入探讨了闭包的特点,阐述了装饰器如何在不修改源代码的情况下增加功能,并展示了如何实现万能装饰器和带参数的装饰器。同时,文章还介绍了多装饰器的使用以及Python内置的map、reduce、filter和sorted等高阶函数。
摘要由CSDN通过智能技术生成


本文整体知识框架

在这里插入图片描述

一、生成式
# 需求: 生成100个验证码(4个字母组成的验证码)

<一般方法>

import string
import random

codes = []
for count in range(100):
    code = "".join(random.sample(string.ascii_letters, 4))
    codes.append(code)
print(codes)

< 列表生成式优化版 >

codes = ["".join(random.sample(string.ascii_letters, 4)) for i in range(100)]
print(codes)
# 需求: 找出1-100之间可以被3整除的数。

<一般方法>

nums = []
for num in range(1, 101):
    if num % 3 == 0:
        nums.append(num)
print(nums)

<优化版>

nums = [num for num in range(1, 101) if num % 3 == 0]
print(nums)

<集合生成式>

result = {i ** 2 for i in range(10)}
print(result)

<字典生成式>

result = {i: i ** 2 for i in range(10)}
print(result)
二、生成器

生成器实现的第一种方法: 将生成式改写成生成器

nums = (i ** 2 for i in range(10000))

生成器实现的第2种方法:yield关键字
return: 函数遇到return就返回,return后面的代码并不会执行。
yield:遇到yield则停止执行代码, 当再次调用next方法时,会从上次停止的地方继续执行,遇到yield停止。

def login():
    print('step 1')  # 'step 1'
    yield 1  # output 1
    print('step 2')
    yield 2
    print('step 3')
    yield 3

# 如果函数里面有yield关键字,函数的返回值就是一个生成器
g = login()
print(next(g)) # 执行login()函数,step 1,遇到yield 1停止
print(next(g)) # 继续执行login()函数,step 2,遇到yield 2停止

<结果>
在这里插入图片描述

三、闭包

定义:

    1. 函数里面嵌套函数
    1. 外部函数的返回值是内部函数的引用
    1. 内部函数可以使用外部函数的变量
def timeit(name):
    def wrapper():
        print('wrapper ' + name)

    print('timeit') # 先执行
    return wrapper # 返回wrapper函数值


in_fun = timeit(name='westos')  # wrapper函数,in_fun实质上就是wrapper函数
in_fun()

<结果>
在这里插入图片描述

四、装饰器

定义:用来装饰函数的工具。
功能: 在不改变源代码的情况下, 添加额外功能(eg: 计算运行时间,记录日志,权限判断)的工具,需要基于闭包使用。

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  # 语法糖,add=timeit(add)
def add(x, y):
    return x + y

result = add(1, 3)
print(result)

<结果>
在这里插入图片描述

五、万能装饰器实现
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()

<简单爬虫的运行结果>
在这里插入图片描述
在这里插入图片描述

六、含参数的装饰器

装饰器携带参数,可以实现更加强大的装饰器

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....')
七、多装饰器
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)
需求: 求1*2*..100的结果, 用reduce和匿名函数实现
result = reduce(lambda x, y: x * y, range(1, 11))
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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值