1.开放封闭原则

原则: 开放封闭原则,对扩展是开放的,对修改是封闭的。

封版概念:当写好一个功能以后,就不可以再修改此函数,避免下面一系列的调用产生错误。

因此产生了装饰器

2.装饰器形成过程

我们来模拟一个发明汽车的过程。首先封装了一个汽车,汽车可以跑起来就是已经封装好的功能函数

按照开放封闭思想,此函数不能再修改,且调用是 car()直接调用

def car():
print('小汽车跑起来')
car()

社会进步了,某天人们不满足现状,想计算一下汽车跑一段路程的时间,然后想增加了计时功能。

那么怎么将这个计时功能加入到汽车里面呢?

def car_time(fun):
start = time.time()
fun()
stop = car_time()
times = stop - start
print(times)

这里用到了闭包思想,返回函数功能。

def car_time(fun):
def inner():
start = time.time()
fun()
stop = car_time()
times = stop - start
print(times)
return inner

最终得到了

import time
def car():
time.sleep(2)
print('小汽车跑起来') def car_time(fun):
def inner():
start = time.time()
fun() # 函数的嵌套
stop = time.time()
times = stop - start
print('汽车用时:',times)
return inner # 返回函数内存地址给car_time car = car_time(car) #为了让原来的函数原封不动
car()

小汽车跑起来
  汽车用时: 2.0002264976501465

上面函数是不是看起来舒服多了,我们在不动原函数的基础上加入了计时功能。

语法糖

语法糖是啥呢,所有用户执行计时功能时,不能都 加 car = car_time(car) 这个赋值吧,要不被人骂死

然后产生了语法糖,用了美滋滋,就可以省去函数赋值这一步了

import time

def car_time(fun):
def inner():
start = time.time()
fun()
stop = time.time()
times = stop - start
print('汽车用时:',times)
return inner @car_time            # 没错这个就是语法糖,@装饰器函数名
def car():
time.sleep(2)
print('小汽车跑起来') car()

带参数的装饰器

总所周知函数是可以传参数的,那么装饰器装饰的函数怎么传参数呢

import time
def car_time(fun): # 此处的fun = car
def inner(a):
start = time.time()
ret = fun(a) # 参数需要fun(a)执行,这里用ret接收car的返回值
stop = time.time()
times = stop - start
print('汽车用时:',times)
return ret # 此处将返回值返回
return inner @car_time
def car(a):
time.sleep(2)
print('小汽车跑起来',a) car('hello')
# 分析可知道。这个car = cat_time(car), car()其实是调用inner函数

  小汽车跑起来 hello
  汽车用时: 2.000110387802124

上述是加一个参数的函数,如果我们想加多个,甚至是列表,接受指定键值对呢。所以产生了默认的

装饰器公式

def car_time(fun):          # 装饰器函数,fun是被装饰的函数
def inner(*args,**kwargs):  # 接受传进来的任意参数
     pass             # 被装饰函数之前要做的事
ret = fun(*args,**kwargs) # 执行 装饰函数 + 参数
     pass             # 被装饰函数之后要做的事
return ret
return inner # @car_time
def car(): # 此处传参
pass car = car_time(car)
car()            # 此处传参

day11.装饰器初识的更多相关文章

  1. python 全栈开发,Day11(函数名应用,闭包,装饰器初识,带参数以及带返回值的装饰器)

    一.函数名应用 函数名是什么?函数名是函数的名字,本质:变量,特殊的变量. 函数名(),执行此函数. python 规范写法 1. #后面加一个空格,再写内容,就没有波浪线了. 2.一行代码写完,下面 ...

  2. python3 装饰器初识 NLP第三条

    还是先抄一条NLP假设... 三,有效果比有道理更重要   光说做法有道理或者正确而不顾是否有效果,是在自欺欺人. 在三赢(我好,人好,世界好)的原则基础上追求效果,比坚持什么是对的更有意义. 说道理 ...

  3. python之装饰器初识

    一.@abstractmethod 1.抽象类的作用:规范编程模式 多人开发.复杂的需求.后期的扩展 是一种用来帮助我们完成规范化的手段 2.如何定义抽象类 1,from abc import ABC ...

  4. day11 装饰器---函数的使用方法

    这个是一个难点,以后面试会经常出现的,要搞懂! 装饰器升级版,进阶内容1: def outer(flag): def wrapper(func): def inner(*args,**kwargs): ...

  5. Day 12 开放封闭原则,装饰器初识

    nonlocal关键字 # 作用:将 L 与 E(E中的名字需要提前定义) 的名字统一​# 应用场景:如果想在被嵌套的函数中修改外部函数变量(名字)的值​# 案例:​def outer():    n ...

  6. day11:装饰器

    1,引子,计算函数的运行时间: import time def func(): time.sleep(0.01) # 为了计算运行时间差的时候有值 print("func") de ...

  7. python基础一 day11 装饰器复习

    # 复习# 讲作业# 装饰器的进阶 # functools.wraps # 带参数的装饰器 # 多个装饰器装饰同一个函数# 周末的作业 # 文件操作 # 字符串处理 # 输入输出 # 流程控制 # 装 ...

  8. 1.16 Python基础知识 - 装饰器初识

    Python中的装饰器就是函数,作用就是包装其他函数,为他们起到修饰作用.在不修改源代码的情况下,为这些函数额外添加一些功能,像日志记录,性能测试等.一个函数可以使用多个装饰器,产生的结果与装饰器的位 ...

  9. python 装饰器-初识

    一.装饰器的形成过程 1.函数无参数,无返回值 import time def f1(): # 无参数,无返回值 time.sleep(1) print("Hello, World!&quo ...

随机推荐

  1. luogu P2071 座位安排

    这个题可以被分为两部分 1.匈牙利算法(板子) 2.邻接表存图(好像这不能称为第二部分) 每一排能坐两个人,那就把一排拆成两个点, 用匈牙利算法求最大匹配 每个人都只想坐两排,说明每个人只会连四条边 ...

  2. Linux 安装node.js和npm教程

    前言:最近想做一款移动端的网站,在网上找了下,想用vue.js来提供技术支持,看了下安装教程,发现都是用npm来安装的,没办法,只能去装个npm了,之前没有装过这个包管理工具,这也是第一次安装吧,记录 ...

  3. vue---组件间通信

    vue中比较重要的就是组件了.而组件随处可复用的特性,使得组件通信非常重要.那么组件之间通讯方式有哪些呢? 第一种:父子组件通讯: 如果是 html页面 中全局注册的组件 和 实例中局部注册的组件 H ...

  4. C++: sprintf浮点数精度控制;

    错误的写法: char buf[100]; int num = 10; sprintf(buf, "%.2f", num); ///这种做法是不对的, 按照压栈顺序, 在压入num ...

  5. Entity Framework入门教程(13)---EF中的高并发

    EF中的高并发 这里只介绍EF6中database-first开发方案的高并发解决方案,code-first开发方案中的高并发会在以后的EF CodeFirst系列中介绍. EF默认支持乐观并发:我们 ...

  6. git 重命名本地分支,并提交到远程

    1.重命名 git branch -m oldBranchName newBranchName 2.删除远程分支:git push origin :oldBranchName 3.将重命名过的分支提交 ...

  7. pymysql常见问题

    1.Python中pymysql出现乱码的解决方法 一般来说,在使用mysql最麻烦的问题在于乱码. 查看mysql的编码: show variables like 'character_set_%' ...

  8. django - 总结 - cnblog 知识点

    1.图像预览 点击头像------>点击input img和input重合; img在label,input-->display:none $("#avatar").c ...

  9. JavaScript类型判断详解(Object.prototype.toString.call()方法进行数据类型的可靠判断)

    前言 在编写一些类库中,我们经常需要判断一些未知的用户的输入和配置,故而需要进行一系列的类型判断.故而总结下JS是如何进行类型判断的 typeof typeof操作符返回一个字符串,表示未经计算的操作 ...

  10. JQuery对象关系图

    上图转自:http://www.cnblogs.com/haogj/archive/2010/04/19/1715762.html 自定义函数示例: $.fn.jAccordionunfold = f ...