关于python:Python-迭代器-生成器-装饰器-上下文管理器

42次阅读

共计 3763 个字符,预计需要花费 10 分钟才能阅读完成。

根本约定

ClsX: 类 X
Valx: 变量 x
Funcx: 函数 x
Codex: 代码片段 x

Python 外部对象非凡办法 / 属性

1.__dict__属性:

ClsA.__dict__,类 A 的属性字典,包含
属性,https://www.cnblogs.com/alvin2010/p/9102344.html
ValA.__dict__, 变量 X 的属性字典

2.__getattr__(self, item):

# 获取名为 item 的属性
# 默认等同于:return self.__dict__[item]

3.__setattr__(self, item, value):

# 设置名为 item 的属性值为 value
# 默认等同于:self.__dict__[item] = value



迭代器和生成器

迭代是 Python 中遍历拜访汇合元素的一种形式。

迭代器是一个能够记住遍历的地位的对象。
迭代器对象从汇合的第一个元素开始拜访,直到所有的元素被拜访完完结。迭代器只能往前不会后退。
迭代器有两个根本的办法:iter() 和 next()。

https://www.runoob.com/python…

# 假如有个办法,能够依据传入的 ID,从服务器获取内容,返回为空的时候阐明没有内容了

def get_data(rid):
    if rid > 5:
        return 
    return '数据 %s' % rid

def get_data2(rid):
    if rid > 3:
        return
    return 'Data%s' % rid

# 当初咱们须要遍历全副数据
i = 1
while True:
    data = get_data(i)
    if not data:
        break
    print(data)
    i += 1

i = 1
while True:
    data = get_data2(i)
    if not data:
        break
    print(data)
    i += 1

# 封装版本
def get_all(func):
    datas = []
    i = 1
    while True:
        data = func(i)
        if not data:
            break
        datas.append(data)
        i += 1
    return datas

for data in get_all(get_data):
    print(data)

# 生成器版本
def gen_all(func):
    i = 1
    while True:
        data = func(i)
        if not data:
            break
        yield data
        i += 1


for data in gen_all(func=get_data):
    print(data)

# 迭代器版本
class AllGetter:
    def __init__(self, func):
        self.func = func
        self.i = 1
    
    def __iter__(self):
        return self
 
    def __next__(self):
        data = self.func(self.i)
        if not data:
            raise StopIteration
        self.i += 1
        return data

x = (i for i in [1,2,3])
while True:
    print(x.__next__())
    

for data in AllGetter(func=get_data):
    print(data)


x = AllGetter(func=get_data)
for data in x:
    print(data)

#等同于

it = iter(x) # it = x.__iter__()
while True:
    print(next(it))

装璜器

# 如果咱们须要统计某些函数 func1、func2 的执行工夫
import time
def func1():
    time.sleep(1)

def func2():
    time.sleep(2)

t1 = time.time()
func1()
print('func1', time.time() - t1)

t2 = time.time()
func2()
print('func2', time.time() - t2)

# 这类问题可形象为以下:# Code1
# FuncX
# Code2


def func3(a, b):
    print('a+b', a+b)

# 定义函数的做法
def timeit(func, *args, **kwargs):
    t = time.time()
    func(*args, **kwargs)
    print(func.__name__, time.time() - t)

timeit(func1)
timeit(func2)
timeit(func3, 1,2)

def funcwrap(rawfunc):
    def _wrap(newfunc):
        newfunc.__name__ = rawfunc.__name__
        return newfunc
    return _wrap

# 装璜器写法
def timeit2(func):
    from functools import wraps
    def _func(*args, **kwargs):
        t = time.time()
        r = func(*args, **kwargs)
        print(func.__name__, time.time() - t)
        return r
    return _func

@timeit2
def func4():
    time.sleep(0.5)

# 装璜器左右相似

newfunc4 = timeit2(func4)
func4 = newfunc4
func4(1,2)


# 装璜器用于类

clzs = []

def addit(clz):
    clzs.append(clz)
    return clz

@addit
class A(object):
    pass

@addit
class B(object):
    pass
    
@addit
class C(object):
    pass

print(clzs)

# 带参数的装璜器

def asapi(logined):
    def _wrap(func):
        def _func(*args, **kwargs):
            if logined:
                print('err')
                return 
            r = func(*args, **kwargs)
            return r
        return _func
    return _wrap

@asapi(logined=True)
def fun6():
    print('xxx')

# 等同于

logined = asapi(logined=True)

@logined
def fun6():
    print('xxx')

上下文管理器

# 某些状况下,咱们须要统计某段代码的执行工夫
# 这类问题可形象为以下:# Code1
# CodeX
# Code2


import time


def func1():
    x = 2
    # 咱们要统计上面这三行代码的执行工夫
    a = 1
    b = a + x
    x = 4


# 个别做法
def func1():
    x = 2
    st = time.time()
    a = 1
    b = a + x
    x = 4
    print('cost time', time.time()-st)



# 上下文治理做法

class TimeIt(object):
    def __enter__(self):
        self.start = time.time()
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print('time cost', time.time()-self.start)



def func1():
    x = 2
    with TimeIt():
        a = 1
        b = a + x
        x = 4

# 等同于
def func1():
    x = 2
    ti = TimeIt()
    ti.__enter__()
    a = 1
    b = a + x
    x = 4
    ti.__exit__(None,None,None)


# 和上下文环境进行交互

class TimeIt2(object):
    def __enter__(self):
        self.start = time.time()
        self._marks = []
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        for n, t in self._marks:
            print(n, t-self.start)
    
        print('time cost', time.time()-self.start)
    
    def mark(self, name):
        print('->', name, time.time() - self.start)
        self._marks.append((name, time.time()))


with TimeIt2() as t:
    time.sleep(2)
    t.mark('T1')
    time.sleep(1)
    t.mark('T2')
    time.sleep(0.5)

# 等同于
ti = TimeIt2()
t = ti.__enter__()
time.sleep(2)
t.mark('T1')
time.sleep(1)
t.mark('T2')
time.sleep(0.5)
ti.__exit__(None,None,None)


# 上下文交互 2

class SendContext(object):
    def __init__(self, tag):
        self.tag = tag
    
    def __enter__(self):
        self.msglist = []
        return self.send
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(self.msglist)
    
    def send(self, userid):
        self.msglist.append(userid)
        

with SendContext('order') as send:
    for o in [1,2,3,4]:
        send(1)

正文完
 0