Python高级特性

本文深入探讨了Python的高级特性,包括生成式、生成器与yield关键字、迭代器与可迭代对象的概念。重点介绍了闭包的定义及实现方式,以及装饰器在功能增强和代码复用上的应用。此外,还涵盖了内置高阶函数如map、reduce、filter和sorted的使用。通过实例练习,帮助读者巩固这些知识。
摘要由CSDN通过智能技术生成

一 生成式

1列表生成式

列表生成式就是一个用来生成列表的特定语法形式的表达式。是Python提供的一种生成列表的简洁形式, 可快速生成一个新的list。

普通的语法格式    [exp for iter_var in iterable]
带过滤功能语法格式:    [exp for iter_var in iterable if_exp]
循环嵌套语法格式:    [exp for iter_var_A in iterable_A for iter_var_B in iterable_B]
 

2 需求: 生成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)

3 列表生成式优化版
 

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

4 需求: 找出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)

5 集合生成式
 

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

6 字典生成式
 

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

二 生成器与yield关键字

1 什么叫生成器?

在Python中,一边循环一边计算的机制,称为生成器:Generator。

2 什么时候需要使用生成器

性能限制需要用到,比如读取一个10G的文件,如果一次性将10G的文件加载到内存处理的话(read方法),内存肯定会溢出;但使用生成器把读写交叉处理进行,比如使用(readline和readlines)就可以再循环读取的同时不断处理,这样就可以节省大量的内存空间.

3 生成器的特点是什么?

解耦. 爬虫与数据存储解耦;
减少内存占用. 随时生产, 即时消费, 不用堆积在内存当中;
可不终止调用. 写上循环, 即可循环接收数据, 对在循环之前定义的变量, 可重复使用;
生成器的循环, 在 yield 处中断, 没那么占 cpu.
 

4如何创建生成器?

[]改成()

# 生成器实现的第一种方法: 将生成式改写成生成器
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(g)
print(next(g))
print(next(g))

三 生成器、迭代器与可迭代对象

迭代是访问容器元素的一种方式。迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。

可迭代对象:可以直接作用于for循环的对象(如何判断是否可以迭代?)
一类是集合数据类型,如list, tuple,dict, set,str等;
一类是generator,包括生成器和带yield的generator function。

可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
把list、dict、str等Iterable变成Iterator可以使用iter()函数

四 闭包

什么是闭包?如何实现闭包?
闭包就是指有权访问另一个函数作用域中的变量的函数。
创建闭包最常见方式,就是在一个函数内部创建另一个函数。
常见形式: 内部函数使用了外部函数的临时变量,且外部函数的返回值是内部函数的引用。
闭包的一个常用场景就是装饰器。

import  time
start_time = time.time()  # 时间戳:从1970年1.1到现在经历的秒数
time.sleep(2)
end_time = time.time()    # 时间戳:从1970年1.1到现在经历的秒数
print(end_time-start_time)

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

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

五 装饰器

装饰器本质上是一个函数,该函数用来处理其他函数
,它可以让其他函数在不需要修改代码的前提下增加额外的功能,装饰器的返回值也是一个函数对象。
装饰器经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等应用场景。

1. 装饰器: 用来装饰函数的工具。

2. 功能: 在不改变源代码的情况下, 添加额外功能(eg: 计算运行时间, 记录日志,权限判断)的工具.

3. 如何实现装饰器? 基于闭包的

# 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)

4.万能装饰器

1 模板

def 装饰器名称(f):
    @wraps(f)  # 保留被装饰函数的属性信息和帮助文档
    def wrapper(*args, **kwargs):
        # 执行函数之前做的事情
        result = f(*args, **kwargs)
        # 执行函数之后做的事情
        return  result
    return  wrapper

 5含参数的装饰器

# 需求: 计算函数的运行时间
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()

 6多装饰器

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()

六 内置高阶函数

函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返
回一个函数!Python对函数式编程提供部分支持。

1. map函数

当序列多于一个时,map可以并行(注意是并行)地对每个序列执行如下图所示的过程

 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函数

reduce() 函数会对参数序列中元素进行累积

3. filter

filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表

 4 sorted() 函数

sorted() 函数对所有可迭代的对象进行排序操作。返回重新排序的列表。
sorted(iterable, key=None, reverse=False)
key: 主要是用来进行比较的元素,只有一个参数,
reverse: 排序规则,True 降序 ,False 升序(默认)

七 练习

1 求1*2*..10的结果, 用reduce和匿名函数实现

result = reduce(lambda x,y: x*y, range(1, 11))
print(result)

2 筛选所有的偶数

result = filter(lambda x: x % 2 == 0, [1, 2, 4, 5, 8])
print(list(result))

3 筛选所有的奇数

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)


 

  • 8
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值