Python D9 and D10

装饰器

一、本质

装饰器的本质就是一个闭包函数,因此具有闭包函数的一切功能。可以在不改变原代码的情况下,在这个函数上扩展功能。

二、装饰器的形成

装饰器就是为了扩展其他函数功能而添加的函数。

举个最简单的例子:

import time

def func1():
    print(‘in func1‘)

def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

func1 = timer(func1)
func1()

然而大家可以看出,在使用装饰器时的赋值非常麻烦,每用一次就要进行一次赋值。为了解决这个问题就引入了一个新的概念:语法糖。

import time
def timer(func):
    def inner():
        start = time.time()
        func()
        print(time.time() - start)
    return inner

@timer   #==> func1 = timer(func1)
def func1():
    print(‘in func1‘)

func1()

  大家可以看出,只要在定义一个函数的时候在上面紧贴的位置加一个@解释器的结构就可以在调用函数的时候直接加上了,是不是非常方便?接下来引入三个概念

1.装饰器——带参数的装饰器

def timer(func):
    def inner(a):
        start = time.time()
        func(a)
        print(time.time() - start)
    return inner

@timer
def func1(a):
    print(a)

func1(1)

2.装饰器—万能装饰器

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func1 = timer(func1)
def func1(a,b):
    print(‘in func1‘)

@timer   #==> func2 = timer(func2)
def func2(a):
    print(‘in func2 and get a:%s‘%(a))
    return ‘fun2 over‘

func1(‘aaaaaa‘,‘bbbbbb‘)
print(func2(‘aaaaaa‘))

3.装饰器—带返回值的装饰器

import time
def timer(func):
    def inner(*args,**kwargs):
        start = time.time()
        re = func(*args,**kwargs)
        print(time.time() - start)
        return re
    return inner

@timer   #==> func2 = timer(func2)
def func2(a):
    print(‘in func2 and get a:%s‘%(a))
    return ‘fun2 over‘

func2(‘aaaaaa‘,‘bbbbbb‘)
print(func2(‘aaaaaa‘))

三、开放封闭原则

1.对扩展是开放的

任何一个程序,不可能在设计之初就已经想好了所有的功能并且未来不做任何更新和修改。所以我们必须允许代码扩展、添加新功能。

2.对修改是封闭的

因为我们写的一个函数,很有可能已经交付给其他人使用了,如果这个时候我们对其进行了修改,很有可能影响其他已经在使用该函数的用户。

四、装饰器的固定格式

def timer(func):
    def inner(*args,**kwargs):
        ‘‘‘执行函数之前要做的‘‘‘
        re = func(*args,**kwargs)
        ‘‘‘执行函数之后要做的‘‘‘
        return re
    return inner

五、多个装饰器装饰一个函数

def pipixia(func):
    def inner():
        print(‘wrapper1 ,before func‘)
        func()
        print(‘wrapper1 ,after func‘)
    return inner

def qqxing(func):
    def inner():
        print(‘wrapper2 ,before func‘)
        func()
        print(‘wrapper2 ,after func‘)
    return inner

@qqxing
@pipixia
def f():
    print(‘in f‘)

f()

  这个过程就像是一层套一层一样,一层层的执行

时间: 2025-01-24 01:39:35

Python D9 and D10的相关文章

D10——C语言基础学PYTHON

C语言基础学习PYTHON--基础学习D10 20180906内容纲要: 1.协程 (1)yield (2)greenlet (3)gevent (4)gevent实现单线程下socket多并发 2.简单爬虫 3.select 4.IO多路复用 5.小结 6.练习 1 协程 协程又叫微线程,纤程.协程是一种用户态的轻量级线程.协程有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文.和栈保存到其他地方,在切换回来的时候回复先前保存的寄存器上下文和栈.协程能保存上一次调用时的状态.一个cpu支

PHP学习笔记:php网络流量统计系统

 说明:代码来源<PHP和MySQL Web应用开发>一书,还有就是代码有些是经过修改的,经过我的测验全部都可以用. 这里面ip地址显示的正常的,我电脑是支持 ipv6 的. 本示例的数据库脚本 ~~~ 先执行 set names gbk;   (因为脚本中包含中文)再执行语句: source d:\test\Vote.sql; CREATE DATABASE IF NOT EXISTS FluxStat COLLATE 'gb2312_chinese_ci'; USE FluxStat; C

PAT1042.Shuffling Machine

Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techniques are seen as weak, and in order to avoid "inside jobs" where employees collaborate with gamblers by performing inadequate shuffles, many cas

一种远程修改sqlite数据库的方法

一.实际需求 工业设备DA660是专门用来实现工业上可编程设备之间交换信息的交换机.现在要使得DA660采集下行设备的实时数据,然后传送到上位机显示.上位机还可以远程修改DA660的数据库配置. 二.数据库设计 我在DA660中设计了sqlite3数据库,名为da660.db,里面存放很多表,其中有一张表示baseinfo,其结构定义如下: 通道号是从0到15之间的正整数,从机地址是从0到256之间的正整数,设备类型定义为0到5之间的正整数,设备类型可从{"xz2000", "

Android Tombstone/Crash的log分析和定位

有一句话叫做常在河边走,哪有不湿鞋.我们这些研究和开发Android的project师正应了这句话,相必大家在调试的时候常常会遇到这么个东西吧 *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** Build fingerprint: 'XXXXXXXXX' pid: 1658, tid: 13086  >>> system_server <<< signal 11 (SIGSEGV), code

FPGA PS2协议

VerilogHDL那些事儿_建模篇(黑金FPGA开发板配套教程) 作者:akuei2 说明:参照该书将部分程序验证学习一遍 学习时间:2014年5月3号 主要收获: 1. 对PS2接口有初步了解: 2. 编码键盘和非编码键盘: 3. 通码和断码. PS2相关知识: 1. PS2接口 2. PS2协议对数据的读取,是"下降沿有效".数据总共有11位,起始位(1).数据位(8).奇偶校验位(1)和停止位(1). 3. 编码键盘与非编码键盘 编码键盘本身带有实现接口主要功能所需的硬件电路,

oc程序代码

// //  main.m //  aa // //  Created by rcfwzx on 15/11/20. //  Copyright (c) 2015年 rcfwzx. All rights reserved. // #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSString *[email protected]"jjkkll

MOS开关管的选择及原理应用

一般情况下普遍用于高端驱动的MOS,导通时需要是栅极电压大于源极电压.而高端驱动的MOS管导通时源极电压与漏极电压(VCC)相同,所以这时栅极电压要比VCC大4V或10V.如果在同一个系统里,要得到比VCC大的电压,就要专门的升压电路了.很多马达驱动器都集成了电荷泵,要注意的是应该选择合适的外接电容,以得到足够的短路电流去驱动MOS管. MOS管是电压驱动,按理说只要栅极电压到到开启电压就能导通DS,栅极串多大电阻均能导通.但如果要求开关频率较高时,栅对地或VCC可以看做是一个电容,对于一个电容

FPGA串口双字节收发

//本程序设计的目的是为了传输多字节通信,使用时添加一个主程序,把接收和发送模块进行例化就可以使用,程序使用的波特率为115.2K 1 //company:电子科技大学 2 //engineer:昌磊 3 //create data:2017.09.14 4 //Design name :多字节串口收发程序 5 //module name: 6 //descirption:可以实现多字节的串口收发通信 7 8 /******************************************