python — 装饰器、迭代器
1 装饰器
1.1目的、应用场景:
目的:
在不改变原函数内部代码的基础上,在函数执行前后自定义功能。
应用场景:
想要为函数扩展功能时,可以选择用装饰器。
1.2 编写装饰器和应用
基本装饰器
# 装饰器的编写格式 (双层嵌套函数)
def 外层函数(参数):
def 内层函数(*arg,**kwarg)
return 参数(*arg,**kwarg)
return 内层函数 #装饰器的应用格式
@外层函数
def 要装饰的函数()
pass # 执行函数,自动触发装饰器了
要装饰的函数()
练习题
def func(arg):
def inner():
print('before')
v = arg()
print('after')
return v
return inner def index():
print('123')
return '666' # 示例一
v1 = index() # 执行index函数,打印123并返回666赋值给v1. # 示例二
v2 = func(index) # v2是inner函数,arg=index函数
index = 666
v3 = v2() # 示例三
v4 = func(index)
index = v4 # index ==> inner
index() # 示例四
index = func(index)
index()
def func(arg):
def inner():
v = arg()
return v
return inner # 第一步:执行func函数并将下面的函数参数传递,相当于:func(index)
# 第二步:将func的返回值重新赋值给下面的函数名。 index = func(index)
@func
def index():
print(123)
return 666 print(index)
# 计算函数执行时间 def wrapper(func):
def inner():
start_time = time.time()
v = func()
end_time = time.time()
print(end_time-start_time)
return v
return inner@wrapper
def func1():
time.sleep(2)
print(123)
@wrapper
def func2():
time.sleep(1)
print(123)def func3():
time.sleep(1.5)
print(123)func1()
注:问题:为什么要加*arg、**kwarg 理解:变量赋值
def func():
print(1) v1 = func
func = 666
``` - 看看到底return的是什么? - 自己有找自己的,自己没有到上一级作用域去找
背会:
@xx # index = xx(index)
def index():
pass
index()
```
- 2. 关于参数
```python
def x(func):
def inner(a1):
return func(a1)
return inner
@x
def index(a1):
pass
```
```python
def x(func):
def inner(a1,a2):
return func(a1,a2)
return inner
@x
def index(a1,a2):
pass
# index = inner
index(1,2)
# ################################### 参数统一的目的是为了给原来的index函数传参
def x(func):
def inner(a1,a2):
return func()
return inner
@x
def index():
pass
# func = 原来的index函数u
# index = inner
index(1,2)
```
如果给好几个函数写一个统一的装饰器,怎么办?
```python
def x1(func):
def inner(*args,**kwargs):
return func(*args,**kwargs)
return inner
@x1
def f1():
pass
@x1
def f2(a1):
pass
@x1
def f3(a1,a2):
pass
```
装饰器建议写法:
```python
def x1(func):
def inner(*args,**kwargs):
data = func(*args,**kwargs)
return data
return inner
```
- 3. 带参数的装饰器
```python
# 第一步:执行 v1 = uuu(9)
# 第二步:ret = v1(index)
# 第三步:index = ret
@uuu(9)
def index():
pass
```
```python
# ################## 普通装饰器 #####################
def wrapper(func):
def inner(*args,**kwargs):
print('调用原函数之前')
data = func(*args,**kwargs) # 执行原函数并获取返回值
print('调用员函数之后')
return data
return inner
@wrapper
def index():
pass
# ################## 带参数装饰器 #####################
def x(counter):
def wrapper(func):
def inner(*args,**kwargs):
data = func(*args,**kwargs) # 执行原函数并获取返回值
return data
return inner
return wrapper
@x(9)
def index():
pass
```
练习题
```python
# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,把每次结果添加到列表中,最终返回列表。
def xxx(counter):
print('x函数')
def wrapper(func):
print('wrapper函数')
def inner(*args,**kwargs):
v = []
for i in range(counter):
data = func(*args,**kwargs) # 执行原函数并获取返回值
v.append(data)
return v
return inner
return wrapper
@xxx(5)
def index():
return 8
v = index()
print(v)
# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,并返回最后一次执行的结果
def xxx(counter):
print('x函数')
def wrapper(func):
print('wrapper函数')
def inner(*args,**kwargs):
for i in range(counter):
data = func(*args,**kwargs) # 执行原函数并获取返回值
return data
return inner
return wrapper
@xxx(5)
def index():
return 8
v = index()
print(v)
# 写一个带参数的装饰器,实现:参数是多少,被装饰的函数就要执行多少次,并返回执行结果中最大的值。
def xxx(counter):
print('x函数')
def wrapper(func):
print('wrapper函数')
def inner(*args,**kwargs):
value = 0
for i in range(counter):
data = func(*args,**kwargs) # 执行原函数并获取返回值
if data > value:
value = data
return value
return inner
return wrapper
@xxx(5)
def index():
return 8
v = index()
print(v)
```
```
def x(counter):
print('x函数')
def wrapper(func):
print('wrapper函数')
def inner(*args,**kwargs):
if counter:
return 123
return func(*args,**kwargs)
return inner
return wrapper
@x(True)
def fun990():
pass
@x(False)
def func10():
pass
```
### 2 迭代器
自己不会写迭代器,只需要会用。
任务:请展示列表中所有的数据
- 1. while + 索引 + 计数器
2. 迭代器,对 某种对象(str/list/tuple/dict/set类创建的对象)-可迭代对象中的元素进行逐一获取
表象:具有_ _ next _ _方法且每次调用都获取可迭代对象中的元素(从前到后一个一个获取)。
- 1. 先将某对象(如列表)转换成迭代器
v1 = iter([11,22,33,44])
v1 = [11,22,33,44]_ _ iter _ _() _
2. 迭代器想要获取每个值:反复调用(val = v1._ _ next _ _())
```python
v1 = [11,22,33,44]
# 列表转换成迭代器
v2 = iter(v1)
result1 = v2.__next__()
print(result1)
result2 = v2.__next__()
print(result2)
result3 = v2.__next__()
print(result3)
result4 = v2.__next__()
print(result4)
result5 = v2.__next__() # v1只有4个元素,第五次获取就会报错:StopIteration
print(result5)
v1 = "alex"
v2 = iter(v1)
while True:
try:
val = v2.__next__()
print(val)
except Exception as e:
break
```
3. 直到报错:StopIteration错误,表示已经迭代完毕。

4. 如何判断一个对象是否是可迭代对象:内部是否有_ _ next _ _方法。
3. for循环:
```python
v1 = [11,22,33,44]
# 1.内部会将v1转换成迭代器
# 2.内部反复执行 迭代器.__next__()
# 3.取完不报错
for item in v1:
print(item)
```
### 3 可迭代对象
- 1. 内部具有_ _ iter _ _()方法且返回一个迭代器
```python
v1 = [11,22,33,44]
result = v1.__iter__()
```
2. 可以被for循环的
python — 装饰器、迭代器的更多相关文章
- python装饰器,迭代器,生成器,协程
python装饰器[1] 首先先明白以下两点 #嵌套函数 def out1(): def inner1(): print(1234) inner1()#当没有加入inner时out()不会打印输出12 ...
- Python装饰器、迭代器&生成器、re正则表达式、字符串格式化
Python装饰器.迭代器&生成器.re正则表达式.字符串格式化 本章内容: 装饰器 迭代器 & 生成器 re 正则表达式 字符串格式化 装饰器 装饰器是一个很著名的设计模式,经常被用 ...
- python装饰器(docorator)详解
引言: 装饰器是python面向对象编程三大器之一,另外两个迭代器.生成器只是我现在还没有遇到必须使用的场景,等确实需要用到的时候,在补充资料:装饰器在某些场景真的是必要的,比如定义了一个类或者一个函 ...
- Python 装饰&生成&迭代器
Python 的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆为了在阿姆斯特丹打发时间,决心开发一个新的脚本解释程序,作为ABC语言的一种继承.Py ...
- 关于python装饰器
关于python装饰器,不是系统的介绍,只是说一下某些问题 1 首先了解变量作用于非常重要 2 其次要了解闭包 def logger(func): def inner(*args, **kwargs) ...
- python装饰器通俗易懂的解释!
1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...
- Python 装饰器学习
Python装饰器学习(九步入门) 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 1 2 3 4 5 6 7 8 # -*- c ...
- python 装饰器修改调整函数参数
简单记录一下利用python装饰器来调整函数的方法.现在有个需求:参数line范围为1-16,要求把9-16的范围转化为1-8,即9对应1,10对应2,...,16对应8. 下面是例子: def fo ...
- python 装饰器学习(decorator)
最近看到有个装饰器的例子,没看懂, #!/usr/bin/python class decorator(object): def __init__(self,f): print "initi ...
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
随机推荐
- Ubuntu 在VirtualBox里无法联网【已解决】
1. 在virtualBox中设置网络:设置->网络->将连接方式选定为“网络地址转换(NAT)” 点确定 2.进入Ubuntu系统中:系统设置->网络, 在弹出的对话框中选择:有线 ...
- ORM 数据库使用
使用 Flask-SQLAlchemy 来操作数据库 1 配置 本文使用sqlite来作为例子演示,在config.py里面更新下数据库的配置 import os basedir = os.path ...
- Qtcreator中printf()/fprintf()不显示问题处理方法
此处只介绍解决办法,有兴趣的朋友可以分析原因. [问题] 使用Qtcreator开发项目中,printf()的诊断信息,在“应用程序输出”窗口不显示. [解决方法] 1.printf()不显示解决示例 ...
- 【SpringBoot】转载 springboot使用thymeleaf完成数据的页面展示
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/weixin_36380516/artic ...
- linux下怎么用ssh连接另一台linux服务器
linux系统大家都知道是服务器版本一般都没有图像界面,通过字符界面操作.用ssh远程方式远程,如果要从一台linux远程到另外一台系统应该怎么操作呢本经验咗嚛以cenots7为例演示 方法/步骤 ...
- Qt编写自定义控件23-广告轮播控件
一.前言 广告轮播这个控件做的比较早,是很早以前定制一个电信客户端时候用到的,该客户端需要在首页展示轮播预先设定好的图片,图片的路径可以自由设定,然后轮播的间隔速度可以自由控制,同时该控件还需要提供两 ...
- MIGO 收货
ls_code-gm_code = '01'. 01 - MB01 - Goods Receipts for Purchase Order 02 - MB31 - Goods Receipts for ...
- JAVA 基础编程练习题18 【程序 18 乒乓球赛】
18 [程序 18 乒乓球赛] 题目:两个乒乓球队进行比赛,各出三人.甲队为 a,b,c 三人,乙队为 x,y,z 三人.已抽签决定比赛名单. 有人向队员打听比赛的名单.a 说他不和 x 比,c 说他 ...
- iOS tableview的常用delegate和dataSource执行顺序
在这次项目中遇到了一个特别奇葩的问题:表视图创建的cell在7以上的系统能正常运行显示,在模拟器上就不能正常实现......为解决这个问题,纠结了好久...... 对在7系统上不显示的猜测: 用mas ...
- opengl读取灰度图生成三维地形
准备第三方库 glew.freeglut.glm.opencv 准备灰度图片和草地贴图 最终效果 代码包括主程序源文件mainApp.cpp.顶点着色器shader.vs.片元着色器shader.fs ...