1. 装饰器

  • 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象。
  • 强调装饰器的原则:1 不修改被装饰对象的源代码 2 不修改被装饰对象的调用方式
  • 装饰器的目标:在遵循1和2的前提下,为被装饰对象添加上新功能
  • 开放封闭原则:对修改封闭,对扩展开放
import time

def timmer(fun):
start_time=time.time()
fun()
end_time=time.time() def fun1():
print("in func1") timmer(fun1) #改变了原先函数的执行
  • 就要用闭包来包装此函数

import time

def timmer(fun):
def inner():
start_time=time.time()
fun()
end_time=time.time()
print("run in {} time {}".format(fun,end_time-start_time))
return inner #实际上是把函数名字传递给timmer,timmer执行,之所以返回inner是因为inner在全局不可以被调用 def fun1():
print("in func1") print(timmer(fun1)) #可以运行,其实就是执行Inner,目的就是在全局可以调用,
fun1=timmer(fun1) #函数本身就是变量,变量值互换
fun1()
  • 这样最基本的装饰器就完成了,Python为我们提供了语法糖,一个完整的装饰器如下:会允许函数传参并且返回值不变

import time

def timmer(fun):
def inner(*args,**kwargs):
start_time=time.time()
ret = fun(*args,**kwargs)
end_time=time.time()
print("run in {} time {}".format(fun,end_time-start_time))
return ret
return inner #实际上是把函数名字传递给timmer,timmer执行,之所以返回inner是因为inner在全局不可以被调用 @timmer
def fun1(num):
print("in func1 {}".format(num))
return 123 # print(timmer(fun1)) #可以运行,其实就是执行Inner,目的就是在全局可以调用,
# fun1=timmer(fun1) #函数本身就是变量,变量值互换
print(fun1(1))
  • 这样可以修饰多个函数,但是要批量更改该怎么,如果不想装饰了,需要挨个去掉吗

import time

def outer():
Flag=False
def timmer(fun):
def inner(*args,**kwargs):
if Flag:
start_time=time.time()
ret = fun(*args,**kwargs)
end_time=time.time()
print("run in {} time {}".format(fun,end_time-start_time))
return ret
else:
ret = fun(*args, **kwargs)
return ret
return inner #实际上是把函数名字传递给timmer,timmer执行,之所以返回inner是因为inner在全局不可以被调用
return timmer @outer() #之所以加执行就是把outer的返回值timmer函数的内存地址放在这里,其实就是@timmer
def fun1(num):
print("in func1 {}".format(num))
return 1 @outer()
def fun2(num):
print("in func2 {}".format(num))
return 2 @outer()
def fun3(num):
print("in func3 {}".format(num))
return 3 print(fun1(1))
print(fun2(2))
print(fun3(3))
  • 编写装饰器,为多个函数加上认证的功能(用户的账号密码来源于文件),要求登录成功一次,后续的函数都无需再输入用户名和密码

  • 使用小知识点eval

login_status={"user":None,"status":False}

def outer():
Flag=True
def auth(func):
def inner(*args,**kwargs):
if Flag:
with open("user.txt",encoding="utf-8") as read_f:
if login_status['user'] and login_status['status']:
ret = func(*args, **kwargs)
return ret
user_info=eval(read_f.read())
name=input("your name>>:").strip()
password=input("your password>>:").strip()
if name in user_info and user_info[name]["password"] == password:
login_status["user"]=name
login_status["status"]=True
print(login_status)
ret = func(*args,**kwargs)
return ret
else:
print("bad")
else:
ret = func(*args, **kwargs)
return ret
return inner
return auth @outer()
def fun1():
print("in func1")
return 1 @outer()
def fun2():
print("in func2")
return 2 @outer()
def fun3():
print("in func3")
return 3 fun1()
fun2()
fun3()
  • 多个装饰器装饰同一个函数

def wrapper1(func):
def inner():
print('wrapper1 ,before func')
func()
print('wrapper1 ,after func')
return inner def wrapper2(func):
def inner():
print('wrapper2 ,before func')
func()
print('wrapper2 ,after func')
return inner @wrapper2
@wrapper1
def f():
print('in f') f()

  结果原因如下:从后分析

装饰器小练习:

#编写下载网页内容的函数,要求功能是:用户传入一个url,函数返回下载页面的结果
import time
from urllib.request import urlopen def wrapper(func):
def inner(*args,**kwargs):
start_time=time.time()
ret = func(*args,**kwargs).decode('utf-8')
end_time=time.time()
print("{} time is {}".format(*args,end_time-start_time))
return ret
return inner @wrapper
def get(url):
return urlopen(url).read() # print(get('http://www.baidu.com'))
get('http://www.baidu.com')

2. 迭代器

  •  其实迭代就是我们说的,可以将某个数据集内的数据“一个挨着一个的取出来”,就叫做迭代

  • 可迭代协议的定义非常简单,就是内部有了__iter__方法。
from collections import Iterable

l = [1, 2, 3, 4]
t = (1, 2, 3, 4)
d = {1: 2, 3: 4}
s = {1, 2, 3, 4} print(isinstance(l, Iterable))
print(isinstance(t, Iterable))
print(isinstance(d, Iterable))
print(isinstance(s, Iterable))
print(dir([1,2]))
  • 用__next__也可以遍历,不依赖for循环

l=[1,2,3,4]
l_iter=l.__iter__() #先把可迭代对象变成迭代器
print(l_iter.__next__()) #依次取值
print(l_iter.__next__()) #依次取值
print(l_iter.__next__()) #依次取值
print(l_iter.__next__()) #依次取值
  • while..try..

l=[1,2,3,4]
l_iter=l.__iter__() #先把可迭代对象变成迭代器
# print(l_iter.__next__()) #依次取值
# print(l_iter.__next__()) #依次取值
# print(l_iter.__next__()) #依次取值
# print(l_iter.__next__()) #依次取值 while True:
try:
item = l_iter.__next__()
print(item)
except StopIteration:
break

3. 生成器

  • 一个包含yield关键字的函数就是一个生成器函数。yield可以为我们从函数中返回值

  • 但是yield又不同于return,return的执行意味着程序的结束,调用生成器函数不会得到返回的具体的值,而是得到一个可迭代的对象。

  • 每一次获取这个可迭代对象的值,就能推动函数的执行,获取新的返回值。直到函数执行结束。

  • 生成器有什么好处呢?就是不会一下子在内存中生成太多数据

def genrator_fun1():
a=1
yield a
b=2
yield b g=genrator_fun1()
print(next(g))
print(next(g))
#生成器监听文件输入的例子

  

  

  

  

  

Python中的装饰器,迭代器,生成器的更多相关文章

  1. python中的装饰器迭代器生成器

    装饰器: 定义:本质是函数(装饰其它函数) 为其它函数添加附加功能 原则: 1 不能修改被装饰函数源代码    2 不修改被装饰函数调用方式 实现装饰器知识储备: 1 函数即‘’变量‘’ 2 高阶函数 ...

  2. 精析python中的装饰器、生成器

    装饰器: 在编程时,要遵循一个原则,就是开放-封闭原则. 在不破坏原函数的情况下,要想对原函数进行一些修饰,那么这里就要用到装饰器. 例如:你完成了一些用函数写成的项目,此时公司正在年度考核,你需要给 ...

  3. 简单说明Python中的装饰器的用法

    简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下   装饰器对与 ...

  4. 【Python】python中的装饰器——@

    对装饰器本来就一知半解的,今天终于弄清楚了,Python中的装饰器是对装饰者模式的很好运用,简化到骨子里了. python中为什么需要装饰器,看这里:http://www.cnblogs.com/hu ...

  5. Python 中实现装饰器时使用 @functools.wraps 的理由

    Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下——比如测试时——会导致一些问题.Python 通过  ...

  6. 写python中的装饰器

    python中的装饰器主要用于在已有函数实现功能前附加需要输出的信息,下面将用实例展示我如何写装饰器. 首先分别尝试写装饰器装饰一个无参函数和一个有参函数(被装饰函数仅输出,无返回值情况下) def ...

  7. python中的装饰器decorator

    python中的装饰器 装饰器是为了解决以下描述的问题而产生的方法 我们在已有的函数代码的基础上,想要动态的为这个函数增加功能而又不改变原函数的代码 例如有三个函数: def f1(x): retur ...

  8. python中@property装饰器的使用

    目录 python中@property装饰器的使用 1.引出问题 2.初步改善 3.使用@property 4.解析@property 5.总结 python中@property装饰器的使用 1.引出 ...

  9. python装饰器,迭代器,生成器,协程

    python装饰器[1] 首先先明白以下两点 #嵌套函数 def out1(): def inner1(): print(1234) inner1()#当没有加入inner时out()不会打印输出12 ...

随机推荐

  1. [BZOJ 1503]郁闷的出纳员(fhq treap)

    [BZOJ 1503]郁闷的出纳员 题面 第一行有两个非负整数n和min.n表示下面有多少条命令,min表示工资下界. 接下来的n行,每行表示一条命令.命令可以是以下四种之一: 名称 格式 作用 I命 ...

  2. Sunday 字符串匹配算法(C++实现)

    简介: Sunday算法是Daniel M.Sunday于1990年提出的一种字符串模式匹配算法.其核心思想是:在匹配过程中,模式串并不被要求一定要按从左向右进行比较还是从右向左进行比较,它在发现不匹 ...

  3. 一、WebApi模型验证

    一.新建项目 选择空的项目webapi 查看启动端口 创建控制器 添加方法 public class VerifController : ApiController { public IHttpAct ...

  4. HTML基础 有序列表写个人收藏夹

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...

  5. 分布式理论 BASE、CAP、ACID

    CAP原理: 在理论计算机科学中,CAP定理(CAP theorem),又被称作布鲁尔定理(Brewer's theorem),它指出对于一个分布式计算系统来说,不可能同时满足以下三点: 一致性(Co ...

  6. ubuntu 自带截图工具快捷键盘

    PrtSc – 获取整个屏幕的截图并保存到 Pictures 目录. Shift + PrtSc – 获取屏幕的某个区域截图并保存到 Pictures 目录. Alt + PrtSc –获取当前窗口的 ...

  7. python基础:1.位、字节、字的关系

    1.位,简称b,或bit,比特,数据存储的最小单位.每个二进制数字0或1就是一个位(bit),网络通信常用bps,bit per second ,每秒传输多少位 2.字节,简称byte, 1byte ...

  8. 注解@requestBody自动封装复杂对象 (成功,自己的例子封装的不是一个复杂对象,只是一个简单的User对象,将jsp页面的name转成json字符串,再用JSON.stringify()传参就行了)

    注意:ajax向后台传值的时候,必须加上contentType:"application/json"; springmvc的注解@requestBody可以通过页面提交json来自 ...

  9. Python中使用"subplot"在一张画布上显示多张图

    subplot(arg1, arg2, arg3) arg1: 在垂直方向同时画几张图 arg2: 在水平方向同时画几张图 arg3: 当前命令修改的是第几张图 t = np.arange(0,5,0 ...

  10. 通过ssh访问虚拟机中的ubuntu系统

    首先把 network 连接方式由 NAT 改为 Bridge Adapter,这样虚拟机中的 ubuntu 就可以有独立的 IP 地址. 安装 openssh: sudo apt-get insta ...