【Python】高级语法:推导式、迭代器、生成器、装饰器

原文作者:我辈李想
版权声明:文章原创,转载时请务必加上原文超链接、作者信息和本声明。


文章目录

  • 一、推导式
    • 1.列表推导式
    • 2.集合推导式
    • 3.字典推导式
  • 二、迭代器
  • 三、生成器
    • 1.yield 生成器
    • 2.元组生成器
    • 3.生成器中重要方法
  • 四、装饰器
    • 1.函数装饰器
    • 2.可传参函数装饰器
    • 3.类装饰器
    • 4.可传参的类装饰器


一、推导式

语法格式为:

new_set = {expression for item in iterable if condition}

其中,
new_set 是新生成的集合;
expression 是一个表达式,用于计算集合中元素的值;
item 是集合的元素;
iterable 是一个可迭代对象,如列表、元组、字符串等;
if 语句是可选的,用于筛选元素。

1.列表推导式

列表推导式是 Python 中常用的一种快速创建列表的方式。它可以通过一行代码来生成一个新的列表,而不需要繁琐的循环和条件语句。
下面是一个简单的示例,演示了如何使用列表推导式生成一个1到10的平方数列表:

squares = [x**2 for x in range(1, 11)]
print(type(squares))
print(squares)

输出结果


[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

列表推导式也可以使用条件语句来过滤元素。下面是一个示例,演示了如何使用列表推导式生成1到10的平方数列表,但只包括偶数:

squares = [x**2 for x in range(1, 11) if x % 2 == 0]
print(type(squares))
print(squares)

输出结果


[4, 16, 36, 64, 100]

在上面的示例中,列表推导式使用for循环语句遍历1到10的整数,但只包括偶数,并使用x**2计算每个偶数的平方,然后将结果添加到新的列表中。

列表推导式的优点是可读性高,能够快速创建列表。但是,当可读性受到影响或数据处理较复杂时,建议使用传统的循环和条件语句

2.集合推导式

Python 集合推导式是用来生成集合的一种快捷方式,它类似于列表推导式。

new_set = {x**2 for x in range(1,6)}
print(type(new_set))
print(new_set)

输出结果


{1, 4, 9, 16, 25}

上面的例子是生成由 1 到 5 的平方组成的集合。

3.字典推导式

字典推导式的语法与列表推导式和集合推导式类似,但是需要使用花括号 {},可以加入条件表达式等来筛选元素,实现更加复杂的生成。

my_dict = {i: i ** 2 for i in range(1, 6)}
print(type(my_dict))
print(my_dict)

输出结果


{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

在上面的例子中,我们使用了一个字典生成器,将 1 到 5 的整数作为字典的键,并将其平方作为值。

二、迭代器

在Python中,迭代器(Iterator)和可迭代对象(Iterable)是两个重要的概念。

可迭代对象是指实现了 iter 或者 getitem 方法的对象,例如列表、元组、集合、字典、字符串等。这些对象可以通过 for 循环进行迭代,或者使用 iter() 函数将其转换为迭代器。

迭代器是指实现了 iternext 方法的对象。__iter__方法返回迭代器对象本身,__next__方法返回数据集合中的下一个元素,如果没有下一个值,就抛出 StopIteration 异常。迭代器只能向前遍历一次,无法回到前面的位置。

示例:迭代对象转迭代器

my_list = [1, 2, 3]
iterator = iter(my_list)
print('my_list',type(my_list))
print('iterator',type(iterator))

输出结果

my_list 
iterator 

需要注意的是,虽然可迭代对象可以使用 iter() 函数转换为迭代器,但是迭代器本身也是可迭代对象。也就是说,迭代器可以在 for 循环中直接使用。

my_list = [1, 2, 3]
iterator = iter(my_list)
for item in iterator:
    print(item)

迭代器是一个可以遍历数据集合的对象,它的作用是提供一种统一的访问数据集合的方法,而不必关注数据的底层实现方式。

示例:创建一个迭代器

class MyIterator:
    def __iter__(self):
        self.a = 1
        return self

    def __next__(self):
        x = self.a
        self.a += 1
        return x

my_iter = MyIterator()
my_iter_iter = iter(my_iter)
print(type(my_iter_iter))

print(next(my_iter_iter))
print(next(my_iter_iter))
print(next(my_iter_iter))

输出


1
2
3

三、生成器

生成器是一种特殊的迭代器,它可以动态地生成数据而不是从一个固定的数据集合中返回数据。Python中的生成器是通过yield关键字来实现的。当函数中包含yield时,该函数就成为生成器函数,并返回一个生成器对象。

1.yield 生成器

示例1:

def num_generator(n):
    for i in range(1, n+1):
        yield i

# 使用生成器函数生成1到10的数字序列
print(type(num_generator(10)))
for num in num_generator(10):
    print(num)

输出


1
2
3
4
5
6
7
8
9
10

其中,生成器函数num_generator()使用yield语句生成数字序列,并在每次调用时返回一个值。使用for循环迭代生成器对象,每次迭代从生成器函数中获取一个值并打印。

2.元组生成器

示例2:

tuple_generator = (i for i in range(10))
result_tuple = tuple(tuple_generator)
print(type(tuple_generator))
print(type(result_tuple))
print(result_tuple)

输出结果



(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

在这个例子中,我们使用了生成器表达式 (i for i in range(10)) 来生成一个可迭代对象,然后使用 tuple() 函数将其转换为元组。

3.生成器中重要方法

next、send、throw是生成器中的3个重要方法,其中next和send可用于遍历生成器,throw用于抛出异常。

其中next函数使用时,当已经遍历到生成器的结尾,会抛一个异常StopIteration
其中send函数使用时,生成器的第一个值必须使用send(None)
其中throw效果等同于raise

生成器的优点是节省内存,因为它不会一次性生成所有值,而是逐个生成并在使用后释放内存。另外,生成器可以通过迭代器协议与其他Python对象进行交互,包括列表、字典等等。

四、装饰器

1.函数装饰器

Python装饰器是一种高级语法,它可以在不修改原函数代码的情况下,增加或改变原函数的功能。装饰器本质上是一个函数,它可以接收一个函数作为参数,并返回一个新的函数。

@decorator
def function():
    pass

其中 decorator 是一个装饰器函数,用于增强 function 函数的功能。装饰器函数的定义如下:

def decorator(func):
    def wrapper(*args, **kwargs):
        # 在这里增加或改变 func 函数的功能
        print(f'calling {func.__name__}()')
        return func(*args, **kwargs)
    return wrapper

装饰器函数 decorator 接收一个函数 func,并返回一个新的函数 wrapper。wrapper 函数可以在调用原函数之前或之后执行一些操作,然后调用原函数并返回其结果。

计时器示例:

import datetime

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = datetime.datetime.now()
        result = func(*args, **kwargs)
        end_time = datetime.datetime.now()
        print('{0} run time is {1}'.format(func.__name__, (end_time - start_time).total_seconds()))
        return result
    return wrapper

@timer
def my_function():
    time.sleep(2)
    print("Function complete.")

my_function()

其中 timer函数是装饰器函数,它接受一个函数作为参数,返回一个新函数wrapper。wrapper函数用于记录被装饰函数执行的时间,并在执行完毕后输出时间。最后,将my_function函数使用@timer装饰器修饰,从而实现函数计时的功能。
【Python】高级语法:推导式、迭代器、生成器、装饰器_第1张图片

2.可传参函数装饰器

装饰器函数也是函数,既然是函数,那么就可以进行参数传递,咱们怎么写一个带参数的装饰器呢

import datetime

def time_msg(msg=None):
    def timer(func):
        def wrapper(*args, **kwargs):
            start_time = datetime.datetime.now()
            result = func(*args, **kwargs)
            end_time = datetime.datetime.now()
            print('{0}:{1} run time is {2}'.format(msg,func.__name__, (end_time - start_time).total_seconds()))
            return result
        return wrapper
    return timer

@time_msg(msg="baiyu")
def my_function():
    time.sleep(2)
    print("Function complete.")

my_function()

【Python】高级语法:推导式、迭代器、生成器、装饰器_第2张图片

3.类装饰器

在python中,可以用类来实现装饰器的功能,称之为类装饰器。类装饰器的实现是调用了类里面的__call__函数。类装饰器的写法比我们装饰器函数的写法更加简单。

import datetime

class MyDecorator:
    def __init__(self, func):
        self.func = func
        print("执行类的__init__方法")
 
    def __call__(self, *args, **kwargs):
        print('进入__call__函数')
        start_time = datetime.datetime.now()
        result = self.func(*args, **kwargs)
        end_time = datetime.datetime.now()
        print('{0}:{1} run time is {2}'.format('',self.func.__name__, (end_time - start_time).total_seconds()))
        result.atrr = '自定义附加参数'  # 类调用时可
        return result 

@MyDecorator
def my_function():
    time.sleep(2)
    print("Function complete.")

@MyDecorator
class MyClass:
    print("MyClass.")

# my_function()

obj = MyClass()
print(obj.attr) # '附加参数'

【Python】高级语法:推导式、迭代器、生成器、装饰器_第3张图片
【Python】高级语法:推导式、迭代器、生成器、装饰器_第4张图片

4.可传参的类装饰器

import datetime

class MyDecorator(object):
    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2
 
    def __call__(self,func):
        print('进入__call__函数')
        def wrapped(*args, **kwargs):
            print("Decorator arguments:", self.arg1, self.arg2)
            start_time = datetime.datetime.now()
            result = func(*args, **kwargs)
            end_time = datetime.datetime.now()
            print('{0}:{1} run time is {2}'.format('',func.__name__, (end_time - start_time).total_seconds()))
            result.attr = '自定义附加参数'  # 类调用时可用
            return result 
        return wrapped

@MyDecorator('参1','参2')
class MyClass:
    print("MyClass.")

obj = MyClass()
print(obj.attr) # '附加参数'

在这里插入图片描述

你可能感兴趣的:(Python开始入门,python,开发语言)