第一步 : 了解装饰器

  装饰器模式,重点在于装饰,装饰的核心仍是被装饰的对象。

  举一个栗子:我今天穿了一件短袖,但是突然一阵风,短袖没办法为我御寒,我想到的办法是将短袖变得更厚更长,但是改造之后,它就不是一件真正的短袖了。

      于是有了长袖的诞生,将长袖套在短袖外面,既可挡风又可御寒,妈妈再也不用担心我感冒了。短袖是短袖,长袖是长袖,相互独立。

      装饰器就像我们的长袖,在不影响短袖改造的情况下,达到了挡风御寒的效果。

  装饰器的应用场景:插入日志、性能测试、事务处理、缓存等。

第二步 : 定义一个基础函数(短袖)

def short_T():
## 定义一个基础函数
print("穿了一件短袖") short_T()

第三步:写一个测试函数执行时间的函数(长袖)

import time

def long_T(func):
## 定义一个测试函数执行时间的函数(装饰函数)
def inner():
start_time = time.time()
short_T
poor = time.time() - start_time
print("函数的执行时间为:%d s"%poor)
return inner def short_T():
print("穿了一件短袖") short_T = long_T(short_T()) ## =====>装饰器实质:装饰函数的参数是被装饰函数的对象()
short_T()

执行顺序:

1、python解释器开始执行后,引入time模块;

2、先读函数long_T,再读函数short_T(将函数名放在内存,但不执行);

3、执行调用者等号右边long_T(short_T),执行long_T函数,并将参数short_T传入函数;

4、读函数inner,将inner函数的返回值inner赋值给调用者short_T(则short = inner),执行inner()函数(则short_T = inner());

5、计算开始时间,(传入参数为:short_T,则func() = short_T()),执行short_T函数,打印“穿了一件函数”;

6、计算函数结束与开始时间的差值,并打印差值,函数执行完毕。

第四步 : 使用语法糖(@)装饰函数(换一件好看的长袖)

'''
使用语法糖(@被装饰函数)来代替 short_T = long_T(short_T()
'''

import time

def long_T(func):
## 定义一个测试函数执行时间的函数
def inner():
start_time = time.time()
func()
poor = time.time() - start_time
print("函数的执行时间为:%d s"%poor)
return inner @long_T
def short_T():
## 定义一个基础函数
print("穿了一件短袖") short_T()

第五步 : 装饰器--hold住所有参数的装饰器

import time

def long_T(func):
## 定义一个测试函数执行时间的函数
def inner(*args,**kwargs): ## 添加万能参数
start_time = time.time()
func(*args,**kwargs) ## 添加万能参数
poor = time.time() - start_time
print("函数的执行时间为:%d s"%poor)
return inner @long_T
def short_T(a,b): ## 无论传多少参数,装饰器都能接收
## 定义一个基础函数
print("%s和%s穿了一件短袖"%(a,b)) short_T("小白","小黑")

第六步 : 装饰器--有返回值的装饰器

import time

def long_T(func):
## 定义一个测试函数执行时间的函数
def inner(*args,**kwargs):
start_time = time.time()
ret = func(*args,**kwargs) ## 接收返回的值
poor = time.time() - start_time
print("函数的执行时间为:%d s"%poor)
return ret                  ## 返回接收的值给接收者
return inner @long_T
def short_T(a,b):
## 定义一个基础函数
return("%s和%s穿了一件短袖"%(a,b)) print(short_T("小白","小黑"))            ## 打印返回的值

装饰器模板:

def wrapper(func):
def inner(*args,**kwargs):
## 执行函数前操作
ret = func(*args,**kwargs)
## 执行函数后操作
return ret
return inner

开放封闭原则

  1、对扩展是开放的:任何一个程序,做到完美,总是经过不断的迭代来升级更新,所有我们必须允许代码扩展,添加新功能;

  2、对修改的封闭的:其一,开发写的函数,有交付给其他人去使用,如果进行修改,很可能影响其他正在使用函数的用户;

             其二,在原有功能上修改函数,很有可能牵一发而动全身,引发其他部分的bug。

  装饰器遵循了开放封闭原则

 1) 获取装饰器函数的函数名和注释信息:

def wrapper(func):
def inner(*args,**kwargs):
'''执行函数前操作'''
ret = func(*args,**kwargs)
'''执行函数后操作'''
return ret
return inner @wrapper
def f1():
''' 注释信息 '''
print(f1.__name__) ## 获取函数名
print(f1.__doc__) ## 获取函数注释信息 f1() # ==== inner() 运行结果: inner
执行函数前操作

2)获取被装饰器函数的函数名和注释信息:

from functools import wraps         ## 引入模块
def wrapper(func):
@wraps(func)               ## 放在最内层函数正上方
def inner(*args,**kwargs):
'''执行前操作'''
ret = func(*args,**kwargs)
'''执行后操作'''
return ret
return inner @wrapper
def name():
'''注释信息'''
print(name.__name__)
print(name.__doc__)
name() 运行结果:

  name
  注释信息

【python3】 函数 装饰器的更多相关文章

  1. python3 使用装饰器,及函数作为参数

    #装饰import typesdef shucai(n): print('蔬菜价格7') if type(n)==types.FunctionType: return n()+7 return n+7 ...

  2. Python--函数对象@命名空间与作用域@包函数@装饰器@迭代器@内置函数

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

  3. (转)Python3.5——装饰器及应用详解

    原文:https://blog.csdn.net/loveliuzz/article/details/77853346 Python3.5——装饰器及应用详解(下)----https://blog.c ...

  4. python3.7 装饰器

    #!/usr/bin/env python __author__ = "lrtao2010" #python3.7 装饰器 #装饰器 ''' 定义:本质就是一个函数,作用是为其他函 ...

  5. Python函数装饰器高级用法

    在了解了Python函数装饰器基础知识和闭包之后,开始正式学习函数装饰器. 典型的函数装饰器 以下示例定义了一个装饰器,输出函数的运行时间: 函数装饰器和闭包紧密结合,入参func代表被装饰函数,通过 ...

  6. Python高手之路【四】python函数装饰器

    def outer(func): def inner(): print('hello') print('hello') print('hello') r = func() print('end') p ...

  7. Python: 无参数的函数装饰器

    写带参数的函数装饰器最纠结的是需要包好多层,最外层是接收参数的函数,它返回一个接收函数的的函数.但这样有个问题是,最终包装出来的装饰器必须加()调用一下,即使没有参数也需要这样做,因为调用这个最外层函 ...

  8. Python中利用函数装饰器实现备忘功能

    Python中利用函数装饰器实现备忘功能 这篇文章主要介绍了Python中利用函数装饰器实现备忘功能,同时还降到了利用装饰器来检查函数的递归.确保参数传递的正确,需要的朋友可以参考下   " ...

  9. 【Python 函数对象 命名空间与作用域 闭包函数 装饰器 迭代器 内置函数】

    一.函数对象 函数(Function)作为程序语言中不可或缺的一部分,但函数作为第一类对象(First-Class Object)却是 Python 函数的一大特性. 那到底什么是第一类对象(Firs ...

  10. python 函数 装饰器 内置函数

    函数 装饰器 内置函数 一.命名空间和作用域 二.装饰器 1.无参数 2.函数有参数 3.函数动态参数 4.装饰器参数 三.内置函数 salaries={ 'egon':3000, 'alex':10 ...

随机推荐

  1. 某平台实时数据录入js代码的修改坑点

    在隐形内嵌函数使用的时候,很容易把这一点忘记了:内嵌函数不能修改外部函数的变量和参数 使用了mysql存储过程实现数据计算,导致高并发的时候数据库挂掉 mysql最大连接数调整到16384 之前为10 ...

  2. js中创建命名空间的几种写法

    在JavaScript中全局变量经常会引起命名冲突,甚至有时侯重写变量也不是按照你想像中的顺序来的,可以看看下面的例子: var sayHello = function() { return 'Hel ...

  3. spring batch (一) 常见的基本的概念介绍

    SpringBatch的基本概念介绍 内容来自<Spring Batch 批处理框架>,作者:刘相. 一.配置文件 在项目中使用spring batch 需要在配置文件中声明: 事务管理器 ...

  4. 【LeetCode每天一题】Edit Distance(编辑距离)

    Given two words word1 and word2, find the minimum number of operations required to convert word1 to  ...

  5. opatchauto failed with error code 42 补丁目录权限问题

    [root@WWJD1 ~]# opatchauto apply $UNZIPPED_PATCH_LOCATION/28183653 OPatchauto session is initiated a ...

  6. 2018-2019-2 网络对抗技术 20165321 Exp3 免杀原理与实践

    1. 实践内容(4分) 1.1 正确使用msf编码器(0.5分),msfvenom生成如jar之类的其他文件(0.5分),veil-evasion(0.5分),加壳工具(0.5分),使用shellco ...

  7. c++ 程序崩溃生成Dump文件

    #include "Windows.h"#include "DbgHelp.h" int GenerateMiniDump(PEXCEPTION_POINTER ...

  8. python两段多线程的例子

    记录瞬间 =====================其一===================== # coding:UTF-8 import os import threading from tim ...

  9. UDP广播-缓冲区过小

    上次介绍到了关于客户端实时刷新摄像头所识别的图片的一些方法,采用了了UDP广播的技术做处理.理论上是没有问题的,将客户端运行在不同电脑上也能很好的看到效果,运行日志也没看出啥问题,结果今天翻看日志的时 ...

  10. C#导出文本内容到word文档源码

    将做工程过程中较好的代码片段珍藏起来,下面的代码内容是关于C#导出文本内容到word文档的代码,希望能对小伙伴们也有好处.<%@ Page Language="C#" Aut ...