[装饰器、迭代器、自定义迭代器、生成式、三元表达式]

[装饰器、迭代器、自定义迭代器、生成式、三元表达式]

一、 无参装饰器

1、什么是装饰器

器指的是工具,可以定义成函数

装饰指的是为其他事物添加额外的东西点缀

合到一起解释:

装饰器指的是定义一个函数,该函数是用来为其他函数添加额外的功能

2、为什么要用装饰器?

开放封闭原则

开放:指的是拓展功能是开放的

封闭:指的是对修改源代码是封闭的

装饰器就是在不修改被装饰对象源代码以及调用方式的前提下为被装饰对象 添加新功能

装饰器模板

	装饰器模板
# def deco(func):
#     def wrapper(*args,**kwargs):
#         res = func(*args,**kwargs)
#         return res
#     return wrapper

为index添加运行时间的功能

import time    #导入时间模块

 def outter(func):
     # func = index
     def wrapper(*args,**kwargs):
         start = time.time()
         res = func(*args,**kwargs)
         end = time.time()
         print(end-start)
         return res
     return wrapper

 @outter  # 语法糖
 def index():
     print('from index')
     time.sleep(1)
     return 123

 @outter
 def home(name):
     print(name)
     time.sleep(1)
     return 123

 res = home('egon')
 print(res)

 res = index()
 print(res)

简单认证功能

def deco(func):
    def wrapper(*args,**kwargs):
        name = input('username: ').strip()
        pwd = input('password: ').strip()
        if name =='egon' and pwd =='123':
            res = func(*args,**kwargs)
            return res
        else:
            print('登录失败')
    return wrapper
@deco
def index():
    print('form index')
index()

多次调用语法糖

def deco1(func1):  # func1 = wrapper2的内存地址
    def wrapper1(*args,**kwargs):
        print(1111)
        res = func1(*args,**kwargs)
        print(6666)
        return res
    return wrapper1

def deco2(func2): # func2 = wrapper3的内存地址
    def wrapper2(*args,**kwargs):
        print(2222)
        res = func2(*args,**kwargs)
        print(5555)
        return res
    return wrapper2

def deco3(func3):  # func3 == 最原始index内存地址
    def wrapper3(*args,**kwargs):
        print(3333)
        res = func3(*args,**kwargs)
        print(444)
        return res
    return wrapper3

        # index == wrapper1 的内存地址
@deco1  #deco1 (wrapper2的内存地址),   ------> wrapper1的内存地址
@deco2  #deco2 (wrapper3的内存地址),   ------> wrapper2的内存地址
@deco3  #deco3 (原始index的内存地址),   ------> wrapper3的内存地址
def index():
    print('form index')
index()

二、 有参装饰器

有参装饰器模板

def auth(mode):
    def deco(func):
        def wrapper(*args,**kwargs):
            res = func(*args, **kwargs)
            return res
        return wrapper
    return deco

案例

有参装饰器
def auth(mode):
    def deco(func):
        def wrapper(*args,**kwargs):
            name = input('username: ').strip()
            pwd = input('password: ').strip()
            if mode == 'file':
                if name == 'pig' and pwd == '123':
                    res = func(*args,**kwargs)
                    return res
                else:
                    print('账号密码错')
            elif mode == 'mysql':
                print('基于mysql认证')
            elif mode == 'ldap':
                print('基于ldap认证')
            else:
                print('无效认证')
        return wrapper
    return deco

@auth('file')
def index():
    print('form index')
index()

@auth('ldap')
def home(name):
    print('傻子')
home('egon')
----------------------------------------------------------------------------------------------------------------------------------------

一、 [迭代器]

1、什么是迭代器?

迭代器指的是迭代取值的工具,迭代是一个重复的过程,每一次重复都是基于上次的结果而继续的,单纯的

循环并不是迭代

2、为何要用迭代器?

迭代器是用来迭代取值的工具,而涉及到把多个值循环取出来的类型

有:列表、字符串、元组、字典、集合、文件

上述迭代取值的方式只适用于有索引的数据类型

为了解决索引迭代取值的局限性、

python必须提供一种不依赖于索引的取值方式、这就是迭代器

3、如何用迭代器?

1、可迭代对象:但凡内置有 __ iter __ 方法的称之为可迭代对象

例如:

s1 = ''   # 字符串
s1.__iter__()

l = []		# 列表
res = l.__iter__()

t = (1,)	# 元组
t.__iter__()

d = {'k1':22}	# 字典
d.__iter__()

2、迭代器对象:但凡内置有__ next __方法的,并且内置有 iter 方法的对象称之为迭代器对象

例如:

# 文件
with open('a.txt',mode='r',encoding='utf-8') as f:
     f.__iter__()
    pass

二、强调:

调用可迭代对象中的 __ iter __方法会得到一个迭代器对象

调用迭代器对象中的__ next __方法会得到下一个值

调用迭代器对象中的__ iter __方法会得到 迭代器本身

for循环的工作原理:for循环可以称之为:迭代器循环

d = {'k1':11,'k2':22,'k3':33}
    1、调用.__iter__()方法得到一个迭代器对象
    2、迭代器对象调用.__next__()方法会拿到一个返回值,然后返回赋值给x
    3、循环往复步骤2,直到抛出StopIteration异常for循环会捕捉异常然后结束循环

for x in d:
    print(x,d[x])
    
 list('hello')  list原理通for循环一样

迭代器优缺点总结:

     优点:1、提供了一种统一的迭代取值方式。(可以不依赖于索引和key)
              2、惰性计算:不消耗内存
             

    缺点:1、取值不够灵活

         2、除非取尽,否则无法获取迭代器的长度,更像是‘一次性的’,

三、 自定义迭代器

函数内但凡出现yield关键字,在调用函数不会触发函数体运行,会得到一个生成器

生成器就是 自定义迭代器

自定义生成器
def func():
    print('第一次')
    yield 1
    print('第二次')
    yield 2
    print('第三次')
g = func()

res = g.__next__()
print(res)
res = g.__next__()
print(res)

案例:
def my_range(start,sotp,stpe):

    while start<sotp:
        start += stpe
        yield start
g = my_range(1,10,2)
res = next(g)
print(res)
res = next(g)
print(res)

总结说明:

 有了yield关键字,我们就有了一种自定义迭代器的实现方式。
 yield可以用于返回值,但不同于return,函数一旦遇到return就结束了,
 而yield可以保存函数的运行状态挂起函数,用来返回多次值

yield 和 return

相同点:返回值都一样

不同点:return只返回一次值,yield可以返回多次

一、生成式

1、列表生成式

l = ['alex_dsb','egon_dsb','lxx_dsb','wxl_dsb','liupengfei']
new_l = []
for name in l:
    if name.endswith('dsb'):
        new_l.append(name)
print(new_l)

new_l = [name for name in l if name.endswith('dsb')]

print(new_l)

2、字典生成式

keys = {'neme','age','gender'}
dic = {key:None for key in keys}
print(dic)

items = {('neme','egon'),('age','18'),('gender','male')}
dic1 = {k:v for k,v in items if k !='gender'}
print(dic1)

3、集合生成式

keys = {'neme','age','gender'}
dic = {key for key in keys}
print(dic)

4、生成器表达式

res = (i for i in range(10) if i>3)
print(res,type(res))
print(next(res))
print(next(res))
print(next(res))

5、获取文件字节数量

方式一:

with open(r'a.txt',mode='rt',encoding='utf-8') as f:
    res = 0
    for line in f:
        res += len(line)
    print(res)

方式二:

 with open(r'a.txt', mode='rt', encoding='utf-8') as f:
     res = ([len(line) for line in f])
     print(sum(res))

方式三:效率最高

with open(r'a.txt',mode='rt',encoding='utf-8') as f:
    res = sum((len(line) for line in f))
上述可以简写如下
    res = sum(len(line) for line in f)
    print(res)

三元表达式

语法格式:

条件成立时要返回的值 if 条件 else 条件不成立时要返回的值

def func(x,y):
    if x > y :
        return x
    else:
        return y

res = func(1,2)
print(res)


针对以上格式
三元表达式:
x = 1
y = 2
res= x if x > y else y
print(res)
posted @ 2021-03-30 15:58  刘较瘦丫  阅读(67)  评论(0)    收藏  举报