装饰器,生成器,迭代器(面试必考)

装饰器

不带参数的装饰圈

def decorator(func):
    def inner(*args, **kwargs):
        print(1111122221111111)
        # func(*args, **kwargs)
        return fun(*args, **kwargs)
    return inner

带参数的装饰器会多一层嵌套

def outside(arg):
    def decorator(func):
        def inner(*args, **kwargs):
            print(1111122221111111)
            # func(*args, **kwargs)
            return fun(*args, **kwargs)
        return inner
return decorator
 from functools import wraps
 from time import time
 
 
 class Record():
     """通过定义类的方式定义装饰器"""
 
     def __init__(self, output):
         self.output = output
 
     def __call__(self, func):
 
         @wraps(func)
         def wrapper(*args, **kwargs):
             start = time()
             result = func(*args, **kwargs)
             self.output(func.__name__, time() - start)
             return result

         return wrapper
 from functools import wraps

 
 def singleton(cls):
     """装饰类的装饰器"""
     instances = {}
 
     @wraps(cls)
     def wrapper(*args, **kwargs):
         if cls not in instances:
             instances[cls] = cls(*args, **kwargs)
         return instances[cls]
 
     return wrapper
 
 
 @singleton
 class President:
     """总统(单例类)"""
     pass

此时改类装饰器没有保证线程安全 保证线程安全就该加lock

  from functools import wraps
  from threading import RLock
  
  
  def singleton(cls):
      """线程安全的单例装饰器"""
      instances = {}
      locker = RLock()
  
      @wraps(cls)
      def wrapper(*args, **kwargs):
          if cls not in instances:
              with locker:
                  if cls not in instances:
                      instances[cls] = cls(*args, **kwargs)
          return instances[cls]
  
      return wrapper

生成器

生成器是一个特殊的程序,可以被用作控制循环的迭代行为,python中生成器是迭代器的一种,使用yield返回值函数,每次调用yield会暂停,而可以使用next()函数和send()函数恢复生成器。
 应用场景:如生成一个超大list,这会十分占用内存,同时我们并不需要一次性的讲所有数据都读出,只是为了按顺序读取前几行的数据,故这时可采用生成器。
 生成器(generator)能够迭代的关键是他有next()方法,工作原理就是通过重复调用next()方法,直到捕获一个异常。

lis = [x*x for x in range(10)]
print(lis)

generator_ex = (x*x for x in range(10))
print(generator_ex) 	[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 
<generator object <genexpr> at 0x000002A4CBF9EBA0>

lis 为可迭代对象
generator_ex 为生成器也同时是可迭代对象

迭代器与可代对象 iter()
可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator

s='hello'     #字符串是可迭代对象,但不是迭代器
l=[1,2,3,4]     #列表是可迭代对象,但不是迭代器
t=(1,2,3)       #元组是可迭代对象,但不是迭代器
d={'a':1}        #字典是可迭代对象,但不是迭代器
set={1,2,3}     #集合是可迭代对象,但不是迭代器
f=open('test.txt') #文件是可迭代对象,但不是迭代器
 
#如何判断是可迭代对象,只有__iter__方法,执行该方法得到的迭代器对象。
# 及可迭代对象通过__iter__转成迭代器对象
from collections import Iterator  #迭代器
from collections import Iterable  #可迭代对象
 
print(isinstance(s,Iterator))     #判断是不是迭代器
print(isinstance(s,Iterable))       #判断是不是可迭代对象
 
#把可迭代对象转换为迭代器
print(isinstance(iter(s),Iterator))

参考文章 https://www.cnblogs.com/wj-1314/p/8490822.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值