day13 装饰器与语法糖
day13 装饰器与语法糖
一、装饰器
1、什么是装饰器
    装饰器就是装饰别人的工具,具体是指为被装饰者添加新功能
    装饰器-》函数
    被装饰者-》函数
2、为何要用装饰器
    装饰器的核心思想:(开放封闭原则)
        在不修改被装饰者源代码以及调用方式的前提下,为被装饰者添加新功能
3、如何实现装饰器
    可以用闭包函数去实现装饰器
被装饰者
import time
def index():
    print('welcome to index page')
    time.sleep(3)
index()
方案一:问题-》修改了被装饰者的源代码
import time
def index():
    start = time.time()
    print('welcome to index page')
    time.sleep(3)
    stop = time.time()
    print(stop - start)
index()
方案二:问题-》会造成代码冗余
import time
def index():
    print('welcome to index page')
    time.sleep(3)
start = time.time()
index()
stop = time.time()
print(stop -start)
start = time.time()
index()
stop = time.time()
print(stop -start)
# 方案三:问题-》修改了被装饰对象的调用方式
import time
def index():
    print('welcome to index page')
    time.sleep(3)
def wrapper(func):
    start = time.time()
    func()
    stop = time.time()
    print(stop -start)
wrapper(index)
# 方案四:我们用wrapper函数赋值给原函数名index,wrapper应该与原函数保持一致,但是现在的问题是不一致
import time
def index():
    print('welcome to index page')
    time.sleep(3)
def outter(func):  # func = 最原始那个index函数的内存地址
    def wrapper():
        start = time.time()
        func()
        stop = time.time()
        print(stop -start)
    return wrapper
index = outter(index)  # f=outter(最原始那个index函数的内存地址)
                   # f=函数wrapper的内存地址
# print(f)
index()
方案四:让wrapper的参数与返回值与被装饰者保持一致
import time
def index(x,y,z):
    print('welcome to index page',x,y)
    time.sleep(3)
    return 123
def outter(func):  # func = 最原始那个index函数的内存地址
    def wrapper(*args,**kwargs):
        start = time.time()
        res = func(*args,**kwargs)
        stop = time.time()
        print(stop -start)
        return res
    return wrapper
index = outter(index)  # f=outter(最原始那个index函数的内存地址)
                   # f=函数wrapper的内存地址
res = index(111,222,333)  # res = wrapper(111,222,333)
print(res)
二、装饰器语法糖
# 装饰器语法糖:在不修改源代码情况下,为其新增功能称之为装饰器语法糖。
import time
from functools import wraps   # wraps:别人写好的装饰器模块
def outter(func):
    @wraps(func)
    def wrapper(*args, **kwargs):   # 可变长参数
        start = time.time()
        res = func(*args, **kwargs)
        stop = time.time()
        print(stop - start)
        return res
    return wrapper
@outter  # index = outter(index)
def index(x, y, z):
    """index函数的文档注释"""
    print('welcome to index page', x, y)
    time.sleep(3)
    return 123
# res = index(111, 222, 333)
# print(res)
# print(index)
help(index)
三、装饰器模板
# 装饰器模板
def outter(func):
    def wrapper(*args,**kwargs):
        print('hello')
        res = func(*args,**kwargs)
        return res
    return wrapper
@outter
def index():
    print('index=========>')
index()  # 调用
# 案例
def auth(func):
    def wrapper(*args,**kwargs):
        username = input('username>>>: ').strip()
        password = input("password>>>: ").strip()
        if username == 'meng' and password == '123':
            res = func(*args,**kwargs)
            return res
        else:
            print("认证失败")
    return wrapper
@auth
def index():
    print('index=========>')
index()
四、迭代器
1、什么是迭代器
    迭代器指的是迭代取值的工具
    什么是迭代???
        迭代是一个重复的过程,但是每一次重复都是基于上一次结果而继续的
    dic = {'k1':111,'k2':2222,'k3':33333}
    def foo(xxx):
        i = 0
        while i < len(xxx):
            print(xxx[i])
            i += 1
    foo(dic)
2、为何要用迭代器
    1.为了找到一种统一迭代取值方案(适用于str、list、tuple、dict、set,文件对象)
    2.节省内存
3、如何用迭代器
    可迭代的对象iterable:
        内置有__iter__方法的对象(str、list、tuple、dict、set,文件对象)
    迭代器对象iterator:
        内置有__iter__方法:生成一个可迭代对象
        内置有__next__方法:取值
# 可迭代对象:
    "abc".__iter__()
    [1,23].__iter__()
    (1,2,3).__iter__()
    {'k1':111}.__iter__()
    {1,2,3}.__iter__()
    f = open('a.txt',mode='wt')
    f.__iter__()
案例1:代码冗余
    dic = {'k1':1111,'k2':2222,'k3':3333}
    iter_dic = dic.__iter__()  # iter_dic=iter(dic) 变成一个可迭代对象
    print(iter_dic.__next__())  # print(next(iter_dic))
    print(iter_dic.__next__())
    print(iter_dic.__next__())   # 只能去列表的3个值,取完再取会报错。
    # print(iter_dic.__next__())  # 报错
    new_iter = dic.__iter__()   # 从新取只能在新建一个可迭代对象
    print(new_iter.__next__())  # 在从新取值
案例2:用捕捉异常让代码继续执行
dic = {'k1': 1111, 'k2': 2222, 'k3': 3333,'k4':4444,'k5':5555}
def did():
    iter_dic = iter(dic)
    while True:
        try:
            print(next(iter_dic))
        except StopIteration:
            break
did()
for x in dic:  # for循环原理:迭代器对象
    print(x)
自定义迭代器
# yield可以返回多次值
def func():
    print('hello1')
    print('hello1')
    yield 111
    print('hello2')
    print('hello2')
    yield 222
    print('hello3')
    print('hello3')
    yield 333
    print('hello4')
    print('hello4')
# 函数内但凡出现yield语法,我们再调用函数就不会立即触发函数体代码运行,会返回一个生成器对象,生成器对象就是一种自定义的迭代器
g = func()
print(g)  # 会打印出111
day13 装饰器与语法糖的更多相关文章
- python_装饰器_语法糖
		什么是高阶函数? -- 把函数名当做参数传给另外一个函数,在另外一个函数中通过参数调用执行 #!/usr/bin/python3 __author__ = 'beimenchuixue' __blog ... 
- PYTHON-有参装饰器,无参装饰器,语法糖
		装饰器 装饰器就是闭包函数的一种应用场景 一 为何要用装饰器 #开放封闭原则:对修改封闭,对扩展开放 二 什么是装饰器 装饰器他人的器具,本身可以是任意可调用对象,被装饰者也可以是任意可调用对象. 强 ... 
- Python学习——装饰器/decorator/语法糖
		装饰器 定义:本质是函数,为其他函数添加附加的功能. 原则:1.不能修改原函数的源代码 2.不能修改被原函数的调用方式 重点理解: 1.函数即“变量” 2.高阶函数:返回值中包含函数名 3.嵌套函数 ... 
- Python基础之函数:2、globlal与nonlocal和闭包函数、装饰器、语法糖
		目录 一.global与nonlocal 1.global 2.nonlocal 二.函数名的多种用法 三.闭包函数 1.什么是闭包函数 2.闭包函数需满足的条件 3.闭包函数的作用 4.闭包函数的实 ... 
- python中装饰器(语法糖)概念
		“”“” 什么是装饰器? """ 还是通过一个例子来慢慢说明 先看下面的例子 def func_1(x): return x*2 def fun_2(x): return ... 
- day-13装饰器
		函数的嵌套定义 概念:在一个函数的内部定义另一个函数 为什么要有函数的嵌套定义:1)函数fn2想直接使用fn1函数的局部变量,可以将fn2直接定义到fn1的内部,这样fn2就可以直接访问fn1的变量2 ... 
- python学习 day13   装饰器(一)&推导式
		装饰器&推导式 传参位置参数在前,关键词参数在后 函数不被调用内部代码不被执行 函数在被调用的时候,每次都会开辟一个新的内存地址,互不干扰 #经典案例 def func(num): def i ... 
- day13.装饰器进阶,迭代器
		1.from functools import wraps 这个函数可以保留原来函数的属性 # from functools import wraps def car_time(fun): # @wr ... 
- Python 语法糖装饰器的应用
		Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ... 
随机推荐
- 源码解析-Abp vNext丨分布式事件总线DistributedEventBus
			前言 上一节咱们讲了LocalEventBus,本节来讲本地事件总线(DistributedEventBus),采用的RabbitMQ进行实现. Volo.Abp.EventBus.RabbitMQ模 ... 
- hdu 2473 Junk-Mail Filter(并查集)
			题意: N个邮件需要鉴别. 两种操作: 1. M X Y:X和Y是同一种邮件 2.S X:X被误判(意味着X要被它从属的那个集合"踢出去"而所有其它的邮件的关系保持不变) 问最后总 ... 
- Java的了解
			Java的基础了解 第一天学习的重要知识点: 1.任何的程序本质有三个:变量:if语句:循环语句. 2.Java的类型:即是编译型也是解释型. 3.JVM:执行bteecode字节码的"虚拟 ... 
- Eclipse简单介绍
			1.编码设置:Windows>preference>Workspace>Other-UTF-8>apply and close: 2.字体大小设置:Windows>pre ... 
- 04 | 函数扩展 | es6
			函数参数的默认值 基本用法 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法. function log(x, y) { y = y || 'World'; console.log(x ... 
- redux 的简单实用案例
			redux 的简单实用案例 整体思想与结构 创建一个Action 创建一个Reducer 创建Store 在App组件开始使用 整体思想与结构 文件目录如下: 构建 action,通过创建一个函数,然 ... 
- OOP 4.21晚 指针知识点
			1.读法:int* ptr ptr是一个指针指向整型变量 2.指针类型:指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型; 3.指针所指向的类型:只须把指针声明语句中的指针名字和名字左边的指 ... 
- 在linux 环境下 安装php
			最近打算学写一个php 脚本~ 到了虚拟机环境上发现~没有环境. 只有老老实实去装一个php环境咯. 第一步 去官网下一个包 记得一定要下载tgz格式的 第二步~当然是传上虚拟机上咯~任意目录都可以. ... 
- 安装mysql会出现start service错误
			安装MySQL时无法启动服务(could not start the service MYSQL .Error:0)安装mysql会出现start service错误安装mysql时 配置到start ... 
- Arduino uno r3 使用 ESP8266 UART-WiFi 透传模块
			一.所需硬件材料 1.ESP8266:01s某宝上3.5块钱 2.杜邦线:某宝几块钱一组40P,这里只需要三根,用于连接 树莓派与继电器 3.烧录器 二.ESP8266 AT固件烧录 ESP8266主 ... 
