python的装饰器、迭代器、yield_Python 迭代器 生成器 装饰器 上下文管理器

基本约定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()。# 假设有个方法,可以根据传入的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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值