脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - python中的迭代器,生成器与装饰器详解

python中的迭代器,生成器与装饰器详解

2022-10-07 14:06FangNJ Python

大家好,本篇文章主要讲的是python中的迭代器,生成器与装饰器详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下

迭代器

每一个可迭代类内部都要实现__iter__()方法,返回一个迭代类对象,迭代类对象则定义了这个可迭代类如何迭代。

for循环调用list本质上是是调用了list的迭代器进行迭代。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 对list进行for循环本质上是调用了list的迭代器
list = [1,2,3,4]
 
# for 循环调用
for elem in list:
    print(elem)
 
# 迭代器调用
list_iter = list.__iter__()
while True:
   try:
    print(next(list_iter))
   except StopIteration:
       break

实现一个自己自定的迭代类,规定迭代一个可迭代的数据结构为“倒计时”模式。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 可迭代对象类
class CountDown(object):
    def __init__(self,num):
        self.num = num
    def __iter__(self):
        return MyIterator(self.num)
 
# 迭代类
class MyIterator(object):
    def __init__(self,num):
        self.NUM= num
        self.FINAL = 0
        self.now = num
        
    def __iter__(self):
        return self
    
    def __next__(self):
        step = 1 if self.NUM<self.FINAL else -1
        while self.now != self.FINAL:
            self.now += step
            return self.now - step
        raise StopIteration
        
cd_pos = CountDown(5)
cd_neg = CountDown(-5)
for i,j in zip(cd_pos,cd_neg):
    print(f'pos:{i}\tneg:{j}')

生成器

含有yield指令的函数可以称为生成器,它可以将函数执行对象转化为可迭代的对象。这样就可以像debug一样一步一步推进函数。可以实现的功能是可以实现让函数内部暂停,实现了程序的异步功能,这样可以及进行该函数与外部构件的信息交互,实现了系统的解耦。

?
1
2
3
4
5
6
7
8
from  collections import Iterable
def f():
    pass
# 含有yield指令的函数可以称为生成器
def g():
    yield()
print(type(f()),isinstance(f(),Iterable))
print(type(g()),isinstance(g(),Iterable))

使用生成器可以降低系统的耦合性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import os
# 生成器是迭代器的一种,让函数对象内部进行迭代
# 可以实现让函数内部暂停,实现了程序的异步功能,同时也实现了解耦。
 
def my_input():
    global str   
    str = input('input a line')
    pass
 
def my_write():
    with open('workfile.txt','w') as f:
        while(str):
            f.write(str+'\n')
            yield()
        return
 
 
mw = my_write()
while(True):
    my_input()
    try:
        next(mw)
    except StopIteration:
        pass
    if not str:
        break  

装饰器

装饰器封装一个函数,并且用这样或者那样的方式来修改它的行为。

不带参数的装饰器

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 不带参数的装饰器
from functools import wraps
# 装饰器封装一个函数,并且用这样或者那样的方式来修改它的行为。
def mydecorator(a_func):
    @wraps(a_func)  #声明这个注解就可以不重写传入的函数,只是调用的时候wrap一下。不加的话,a_func函数可以看作被重写为wrapTheFunction.
    def wrapTheFunction():
        print(f"function in {id(a_func)} starts...")
        a_func()
        print(f"function in {id(a_func)} ends...")
    return wrapTheFunction
 
# 在函数定义前加入此注解就可以将函数传入装饰器并包装
@mydecorator
def f():
    print('hi')
    pass
 
f()
print(f.__name__)

带参数的装饰器(实现输出到自定义的日志文件)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 带参数的装饰器(实现输出到自定义的日志文件)
from functools import wraps
 
def logit(logfile='out.log'):
    def mydecorator2(a_func):
        @wraps(a_func)
        def wrapTheFunction(*args, **kwargs):   # 这个保证了函数可以含有任意形参
            log_string = a_func.__name__ + " was called"
            print(log_string)
            # 打开logfile,并写入内容
            with open(logfile, 'a') as opened_file:
                # 现在将日志打到指定的logfile
                opened_file.write(log_string + '\n')
                return a_func(*args, **kwargs)
        return wrapTheFunction
    return mydecorator2
 
# func group1
@ logit('out1.log')
def func1(str):
    print(str)
    pass
@ logit('out2.log')
def func2(): pass
            
func1('I have a foul smell')
func2()       

实现一个装饰器类(这样写可以简化装饰器函数,并且提高封装性)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 带参数的装饰器(实现输出到自定义的日志文件)
from functools import wraps
 
def logit(logfile='out.log'):
    def mydecorator2(a_func):
        @wraps(a_func)
        def wrapTheFunction(*args, **kwargs):   # 这个保证了函数可以含有任意形参
            log_string = a_func.__name__ + " was called"
            print(log_string)
            # 打开logfile,并写入内容
            with open(logfile, 'a') as opened_file:
                # 现在将日志打到指定的logfile
                opened_file.write(log_string + '\n')
                return a_func(*args, **kwargs)
        return wrapTheFunction
    return mydecorator2
 
# func group1
@ logit('out1.log')
def func1(str):
    print(str)
    pass
@ logit('out2.log')
def func2(): pass
            
func1('I have a foul smell')
func2()       
   

总结

到此这篇关于python中的迭代器,生成器与装饰器详解的文章就介绍到这了,更多相关python迭代器,生成器与装饰器内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/FangNJ/article/details/122986008

延伸 · 阅读

精彩推荐
  • PythonPython3如何使用多线程提升程序运行速度

    Python3如何使用多线程提升程序运行速度

    这篇文章主要介绍了Python3如何使用多线程提升程序运行速度,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋...

    天外归云6302020-08-11
  • Python详解Python中的条件判断语句

    详解Python中的条件判断语句

    这篇文章主要介绍了Python中的条件判断语句,是Python入门中的基础知识,需要的朋友可以参考下 ...

    脚本之家10382020-06-28
  • Python开源软件包和环境管理系统Anaconda的安装使用

    开源软件包和环境管理系统Anaconda的安装使用

    Anaconda是一个用于科学计算的Python发行版,支持 Linux, Mac, Windows系统,提供了包管理与环境管理的功能,可以很方便地解决多版本python并存、切换以及各种第...

    刘春桂1852020-12-05
  • Pythonpython 合并表格详解

    python 合并表格详解

    这篇文章主要为大家详细介绍了python 合并表格的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    吃点饭饭7752022-01-24
  • PythonPython编程-封装,继承与多态

    Python编程-封装,继承与多态

    这篇文章主要介绍了Python编程-封装,继承与多态,文章主要目的解如何利用封装保护属性、掌握单继承和多继承、会重写和调用父类方法,理解多态的使用等...

    howard200511832022-09-05
  • PythonPython实战小游戏飞机大战详解

    Python实战小游戏飞机大战详解

    飞机大战想必是很多人童年时期的经典游戏,我们依旧能记得抱个老人机娱乐的场景,下面这篇文章主要给大家介绍了关于如何利用python写一个简单的飞机大...

    嗨!程序媛9442022-02-24
  • Python详解分布式系统中如何用python实现Paxos

    详解分布式系统中如何用python实现Paxos

    提到分布式算法,就不得不提 Paxos 算法,在过去几十年里,它基本上是分布式共识的代 名词,因为当前最常用的一批共识算法都是基于它改进的。比如,...

    华为云开发者社区11942021-11-05
  • Python在python中使用scatter绘制散点图的实例

    在python中使用scatter绘制散点图的实例

    今天小编就为大家分享一篇在python中使用scatter绘制散点图的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    木里先森4532021-07-31