欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2023-01-28 12:19:51
目录迭代器生成器装饰器总结迭代器每一个可迭代类内部都要实现__iter__()方法,返回一个迭代类对象,迭代类对象则定义了这个可迭代类如何迭代。for循环调用list本质上是是调用了list的迭代器进...

迭代器

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

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

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

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

# 可迭代对象类
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一样一步一步推进函数。可以实现的功能是可以实现让函数内部暂停,实现了程序的异步功能,这样可以及进行该函数与外部构件的信息交互,实现了系统的解耦。

from  collections import iterable
def f():
    pass
# 含有yield指令的函数可以称为生成器
def g():
    yield()
print(type(f()),isinstance(f(),iterable))
print(type(g()),isinstance(g(),iterable))

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

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   

装饰器

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

不带参数的装饰器

# 不带参数的装饰器
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__)

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

# 带参数的装饰器(实现输出到自定义的日志文件)
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()        

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

# 带参数的装饰器(实现输出到自定义的日志文件)
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迭代器,生成器与装饰器内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!