一. 经典的两层装饰器,也是标准装饰器

案例

import time

def outter1(func):
def wrapper(*args, **kwargs):
start = time.time()
res = func(*args, **kwargs)
stop = time.time()
print(stop - start)
return res return wrapper # @函数的内存地址1(1,2,3,4,5) # 函数的内存地址(index)
def index(x, y):
print('index===>', x, y) @outter1
def home(name):
print('home====>', name)
引出两个点:
1、可以通过闭包的方式为函数体传参,可以包一层,也可以包两层
2、@后跟的必须是一个函数的内存地址
@函数的内存地址(1,2,3) 是可以的,但是前提是调用函数"函数的内存地址(1,2,3)"的
返回值必须是一个函数的内存地址 三层有参装饰器
第一阶
def outter(func):
def wrapper(*args, **kwargs):
inp_name=input("please input your name: ").strip()
inp_pwd=input("please input your password: ").strip()
with open('user.db',mode='rt',encoding='utf-8') as f:
for line in f:
name_db,pwd_db=line.strip('\n').split(':')
if inp_name == name_db and inp_pwd == pwd_db:
print('login successful')
res = func(*args, **kwargs)
return res
else:
print("账号或密码错误") return wrapper @outter
def index(x, y):
print('index===>', x, y) index(1, 2)

第二阶

获取认证信息途径有

1. ldap
2. mysql
3. file
...
def outter2(mode):
def outter(func):
def wrapper(*args, **kwargs):
inp_name=input("please input your name: ").strip()
inp_pwd=input("please input your password: ").strip()
if mode == "file":
print('认证来源=====>file')
with open('user.db',mode='rt',encoding='utf-8') as f:
for line in f:
name_db,pwd_db=line.strip('\n').split(':')
if inp_name == name_db and inp_pwd == pwd_db:
print('login successful')
res = func(*args, **kwargs)
return res
else:
print("账号或密码错误")
elif mode == "ldap":
print('认证来源=====>ldap')
elif mode == "mysql":
print('认证来源=====>mysql')
else:
print("未知的认证来源")
return wrapper
return outter outter=outter2(mode="mysql") @outter # index=outter(index) ==>index=wrapper
def index(x, y):
print('index===>', x, y) index(1, 2) # wrapper(1,2)

第三阶(完美)

def outter2(mode):
def outter(func):
def wrapper(*args, **kwargs):
inp_name=input("please input your name: ").strip()
inp_pwd=input("please input your password: ").strip()
if mode == "file":
print('认证来源=====>file')
with open('user.db', mode='rt', encoding='utf-8') as f:
for line in f:
name_db,pwd_db=line.strip('\n').split(':')
if inp_name == name_db and inp_pwd == pwd_db:
print('login successful')
res = func(*args, **kwargs)
return res
else:
print("账号或密码错误")
elif mode == "ldap":
print('认证来源=====>ldap')
elif mode == "mysql":
print('认证来源=====>mysql')
else:
print("未知的认证来源")
return wrapper
return outter @outter2(mode="mysql") # index=outter(index) ==>index=wrapper
def index(x, y):
print('index===>', x, y) index(1, 2) # wrapper(1,2)

二. 迭代器

简述:

迭代是一个重复的过程,每一次重复都是基于上一次的结果而来的
注意:迭代不是单纯的重复 迭代器是一种迭代取值的工具,这种取值方式是通用,不依赖于索引
str ===》索引
list ===》索引
tuple ===》索引
t = (1111, 222, 333, 444, 555, 666)
i = 0
while i < len(t):
print(t[i])
i += 1 dict ===》key
set ===》既没有key也没有索引
f文件对象==》既没有key也没有索引
python为上述类型都内置了__iter__方法

例:

s = "hello"
ll = [111, 222, 333]
t = (1111, 222, 333, 444, 555, 666)
d = {"k1": 111, "k2": 222, "k3": 3333}
s1 = {'a', 'b', 'c'}
f = open(r'user.db', mode='rt', encoding='utf-8')
f.close()

操作方法

调用__iter__方法得到的返回值就是对应的迭代器

res = d.__iter__()  # res=iter(d)
print(res) # res是迭代器
a = res.__next__() # a=next(res)
b = res.__next__() # b=next(res)
c = res.__next__() # c=next(res)
d = res.__next__() # StopIteration
print(c) d = {"k1": 111, "k2": 222, "k3": 3333} iter_d = iter(d) while True:
try:
print(next(iter_d))
except StopIteration:
break

迭代对象和迭代器对象区分

迭代的对象:有__iter__内置方法的对象都是可迭代的对象,str、list、tuple、dict、set、文件对象
ps:可迭代对象.__iter__()返回的是迭代器对象 迭代器对象:
1、有__next__方法
2、有__iter__方法,调用迭代器的__iter__方法得到的就是迭代器自己
ps:迭代器对象之所内置__iter__方法是为了符合for循环第一个工作步骤
例:
f = open(r'user.db', mode='rt', encoding='utf-8')
line=f.__next__()
print(line)
line=f.__next__()
print(line)
for line in f:
print(line) f.close()
line=f.__next__() # 报错

叠加多个可迭代对象, 还是本身, 没有改变性质

d = {"k1": 111, "k2": 222, "k3": 3333}
res=d.__iter__() print(res)
print(res.__iter__())
print(res.__iter__() is res)
print(res.__iter__().__iter__().__iter__() is res)
二、for循环的工作原理=》迭代器循环
d = {"k1": 111, "k2": 222, "k3": 3333}

for k in d:
print(k)

解释:

for循环的工作步骤
1、调用in后的对象的__iter__方法,得到对应的迭代器
2、k=next(迭代器),然后执行一次循环
3、循环往复,知道把迭代器的值取干净了,抛出异常,for循环会自动捕捉异常,结束循环 迭代器总结:
优点
1、不依赖索引,是一种通用的取值方式
2、节省内存
d = {"k1": 111, "k2": 222, "k3": 3333}
iter_d=iter(d) next(iter_d)

缺点:

1、不能取指定位置的值
2、不能预估值的个数,无法统计长度
ll = [111, 222, 333]
print(ll[2]) iter_ll=iter(ll)
next(iter_ll)
next(iter_ll)
print(next(iter_ll))
 

day16 三层装饰器和迭代器的更多相关文章

  1. Python自动化 【第四篇】:Python基础-装饰器 生成器 迭代器 Json & pickle

    目录: 装饰器 生成器 迭代器 Json & pickle 数据序列化 软件目录结构规范 1. Python装饰器 装饰器:本质是函数,(功能是装饰其它函数)就是为其他函数添加附加功能 原则: ...

  2. 简学Python第四章__装饰器、迭代器、列表生成式

    Python第四章__装饰器.迭代器 欢迎加入Linux_Python学习群  群号:478616847 目录: 列表生成式 生成器 迭代器 单层装饰器(无参) 多层装饰器(有参) 冒泡算法 代码开发 ...

  3. Python之函数(自定义函数,内置函数,装饰器,迭代器,生成器)

    Python之函数(自定义函数,内置函数,装饰器,迭代器,生成器) 1.初始函数 2.函数嵌套及作用域 3.装饰器 4.迭代器和生成器 6.内置函数 7.递归函数 8.匿名函数

  4. Python之装饰器、迭代器和生成器

    在学习python的时候,三大“名器”对没有其他语言编程经验的人来说,应该算是一个小难点,本次博客就博主自己对装饰器.迭代器和生成器理解进行解释. 为什么要使用装饰器 什么是装饰器?“装饰”从字面意思 ...

  5. Python装饰器、迭代器&生成器、re正则表达式、字符串格式化

    Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用 ...

  6. Python(四)装饰器、迭代器&生成器、re正则表达式、字符串格式化

    本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解 ...

  7. python 函数之装饰器,迭代器,生成器

    装饰器 了解一点:写代码要遵循开发封闭原则,虽然这个原则是面向对象开发,但也适用于函数式编程,简单的来说,就是已经实现的功能代码不允许被修改但 可以被扩展即: 封闭:已实现功能的代码块 开发:对扩张开 ...

  8. 循序渐进Python3(四) -- 装饰器、迭代器和生成器

    初识装饰器(decorator ) Python的 decorator 本质上就是一个高阶函数,它接收一个函数作为参数,然后,返回一个新函数. 使用 decorator 用Python提供的 @ 语法 ...

  9. Python之路第四天,基础(4)-装饰器,迭代器,生成器

    装饰器 装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象 ...

随机推荐

  1. pytorch入门2.0构建回归模型初体验(数据生成)

    pytorch入门2.x构建回归模型系列: pytorch入门2.0构建回归模型初体验(数据生成) pytorch入门2.1构建回归模型初体验(模型构建) pytorch入门2.2构建回归模型初体验( ...

  2. cubic-bezier() 函数

    2020-03-13 cubic-bezier() 函数 ubic-bezier() 函数定义了一个贝塞尔曲线(Cubic Bezier). 贝塞尔曲线曲线由四个点 P0,P1,P2 和 P3 定义. ...

  3. 油猴脚本 之 网教通直播评论记录抓取 v2.0

    先放一个 <油猴脚本 之 网教通直播评论记录抓取>那篇文章的传送门 . 修复内容 将所有表情转为 [符号表情] 字样,而非删除: 修复被禁言用户读取异常,现在被禁言用户表示为 张三 [已禁 ...

  4. Java中Clob类型转换成String类型的问题

    1.问题: 项目中使用druid+达梦数据库(基本类似Oracle),查出的Clob类型数据在运行时为ClobProxyImpl对象而不是内容,不能转为字符串 2.原代码: map为达梦数据库或Ora ...

  5. Beta冲刺<9/10>

    这个作业属于哪个课程 软件工程 (福州大学至诚学院 - 计算机工程系) 这个作业要求在哪里 Beta冲刺 这个作业的目标 Beta冲刺--第九天(05.27) 作业正文 如下 其他参考文献 ... B ...

  6. Head First 设计模式

    OO基础 抽象 封装 多态 继承 OO原则 封装变化 多用组合,少用继承 针对接口编程,不针对实现编程 为交互对象之间的松耦合设计而努力 对扩展开放,对修改关闭 依赖抽象,不要依赖具体类 最少知识原则 ...

  7. 深入理解Java闭包概念

    闭包又称词法闭包 闭包最早定义为一种包含<环境成分>和<控制成分>的实体. 解释一:闭包是引用了自由变量的函数,这个被引用的变量将和这个函数一同存在. 解释二:闭包是函数和相关 ...

  8. element ui 版本升级

    element ui 版本升级 1. 卸载之前版本 npm uninstall element-ui 2.重新安装element-ui npm i element-ui 3.就如package.jso ...

  9. I/O格式化与运算符

    I/O格式化与运算符 输出函数 Python3 - print() 在Python3中.print()的使用方法如下: >>> # ==== Python3 print() ==== ...

  10. Java | 顶层类(Top-Level Class)

    前言 本文内容根据 Java 官方教程中的<课程:类和对象>编写而成. 本文提供的是 JDK 14 的示例代码. 定义 顶层类(Top-Level Class),是 Java 中对类的一种 ...