python入门基础-函数装饰器的理解

1.装饰器

# 知乎某大神是这么比喻装饰器的:内裤可以用来遮羞,但是到了冬天他就没有办法为我们御寒,聪明的人于是发明了长裤,有了长裤后宝宝再也不冷了,
# 装饰器就像我们这里说的长裤,在不影响内裤作用的前提下,给我们的身子提供了保暖的功效。
#
# 大神是将程序中原本的函数比喻成内裤,而装饰器比喻成了长裤,这样在寒冬里它们结合一起使用就给所有人带来了温暖。
#
# 装饰器本质上是一个python函数,它可以让其它函数在不改动代码的情况下增加额外的功能,并且装饰器的返回值也是一个函数对象。
# 在很多的应用场景中我们都可以用到装饰器,比如:插入日志、性能测试、事务处理等,正因为有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码,并且继续的重用。
# 那python的装饰器可以概括理解为:装饰器的作用就是为已经存在的对象增加格外的功能,并且不改变原函数的调用方式。

2.装饰器的过程

#首先我们看一段代码例子。

def func():
    print(‘hello word!‘)

func()  #我们调用函数后,可以正常打印出来 hello Word!

#比如现在我们有了一个新的需求,要在函数中增加打印函数的执行时间,那添加后的代码就是下面这段了。

import time     #加载time模块
def func():
    start = time.time() #声明变量记录函数开始执行的时间
    print(‘hello word!‘)
    end = time.time()       #声明变量记录函数结束执行的时间
    result = end  - start   #声明变量用于接收整个函数运行所耗时间
    print(result)       #打印出来函数执行的总体耗时,当前现在函数中没有什么过多的复杂代码,所以基本不存在耗时多少

#对于上面的需求我们已经实现了,但是我们是改变原函数体的结构实现的,这样在正常的开发环境中肯定是不行的,所以代码优化成下面这种。

import time

def timer():
    start = time.time()
    func()
    end = time.time()
    result = start - end
    print(result)

def func():
    print(‘hello word!‘)

timer()

#这样的话,我们就在不改变原函数体的结构情况下,增加了一项打印函数执行耗时的功能,难道这就是装饰器了?NO、NO、NO 还请继续往下看

2.1简单的装饰器

#前面我们也在没有更改原函数体的基础上增加了函数执行耗时的打印,那为什么不叫装饰器呢?因为随便没有改变函数体的结构,
# 但是我们改变了函数名的调用,之前由func()去调用就可以打印hello word,现在是调用timer()函数才能打印,所以我们的代码需要更进一步的调整。

import time

def timer(f): #实际f是func函数名
    def inner():
        start = time.time()
        f()   #实际调用的是func()
        end = time.time()
        result = start - end
        print(result)
    return inner  #将inner函数名返回

def func():
    print(‘hello word!‘)

func = timer(func)      #此时是 func = inner
func()      #此时实际调用的函数是  inner()

#那上面这行代码就可以称之为一个简单的函数体了,但是也不是很完美,因为真实的环境中肯定存在很多的函数,在大多函数都需增加函数执行耗时功能的时候。
#我们不可能在没有个函数调用前,都提前像 func = timer(func)这种声明,所以我们就要牵出另一个强大的功能“@语法糖
#@符号是装饰器的语法糖,在定义函数的时候使用,可以避免再一次赋值操作,就是说用了@语法糖可以节省上面的func = timer(func)这步操作。

import time

def timer(f):   #参数f 就是 func 或 func2 函数名
    def inner():
        start = time.time()
        f()     #实际调用的是 func 或 func2函数
        end = time.time()
        result = start - end
        print(result)
    return inner    #将inner函数名返回
@timer   #此时是 func = inner
def func():
    print(‘hello word!‘)

@timer      #此时是 func2 = inner
def func2():
    print(‘is func2‘)

func()
func2()

#上面通过@语法糖节省了func2 = inner这个过程,以后就可以在需要增加打印耗时的函数上面声明语法糖就可以了。
#上面的原函数调用都没有带上实参,那如果原函数带上了不同的实参,上面的方法肯定行不通了,所以我们需要进一步升级,这里又要用一个强大的功能了。
#要用的功能就是 *args 和 **kwargs 两个动态参数,并且要结合在一起使用,这样就可以天下无敌了

import time

def timer(f):   #参数f 就是 func 或 func2 函数名
    def inner(*args,**kwargs):
        start = time.time()
        f(*args,**kwargs)     #实际调用的是 func 或 func2函数
        end = time.time()
        result = start - end
        print(result)
    return inner    #将inner函数名返回
@timer   #此时是 func = inner
def func(a,b):
    print(‘hello word!‘,a,b)

@timer      #此时是 func2 = inner
def func2(a,b,c,d):
    print(‘is func2‘,a,b,c,d)

func(1,2)
func2(1,2,3,4)

#那上面的这个装饰器基本可以算作完善了

3.开放封闭原则

#函数在什么时候是开放的和什么时候是关闭的呢?听我娓娓道来
#(1)对扩展是开放的
    #为什么要对扩展开放呢?
    #任何一个程序,不可能在设计之初就已经想好了所有功能,而且后面不需要做任何的更新和修改,所以我们必须允许代码的扩展和添加新功能。

#(1)对修改是封闭的
    #为什么要对修改封闭呢?
    #因为我们写一个函数,很有可能影响其他已经在使用这个函数的用户,所以对修改函数是封闭的。

#装饰器完美的遵循了这个开放封闭原则。

4.装饰器的主要功能和固定结构

#(1)装饰器的主要功能
#在不改变函数调用方式的基础上在函数的前后添加功能。

#(2)装饰器的固定格式
def timer(func):    #装饰器函数,func是被装饰的函数名
    def inner(*args,**kwargs):
        ‘‘‘在被装饰函数之前要做的操作‘‘‘
        ret = func(*args,**kwargs)  #调用被装饰的函数
        ‘‘‘在被装饰函数之后要做的操作‘‘‘
        return ret
    return inner

原文地址:https://www.cnblogs.com/jason-lv/p/8137328.html

时间: 2024-08-04 22:14:16

python入门基础-函数装饰器的理解的相关文章

python语法基础-函数-装饰器-长期维护

###############    装饰器的初成和开放封闭原则    ############## # 装饰器 # 装饰器非常重要,面试Python的公司必问, # 原则:开放封闭原则 # # 需求:计算程序执行的时间, import time def func(): start = time.time() time.sleep(0.01) print(123) end = time.time() print(end-start) func() # 这种写法如果有100个函数,你都要加一遍这是

Python作用域-->闭包函数-->装饰器

1.作用域: 在python中,作用域分为两种:全局作用域和局部作用域. 全局作用域是定义在文件级别的变量,函数名.而局部作用域,则是定义函数内部. 关于作用域,我要理解两点:a.在全局不能访问到局部定义的变量 b.在局部能够访问到全局定义的变量,但是不能修改全局定义的变量(当然有方法可以修改) 下面我们来看看下面实例: x = 1 def funx(): x = 10 print(x) # 打印出10 funx() print(x) # 打印出1 如果局部没有定义变量x,那么函数内部会从内往外

python之我对装饰器的理解

从一开始学习python的时候,就一直不是很理解装饰器是个什么东东,再看了很多篇博文和自己动手敲了好多代码后,算是略有了解. 我理解的装饰器是: 在不改变原有函数调用的情况下,对其进行包装,使其变成另外一种函数来使用,一般的用途是 插入日志.性能测试.事务处理等. def host_restrict(tags=[], names=[]):     def decorator(f):         @functools.wraps(f)         def decorated(*args, 

python 内置函数 装饰器

一.内置函数 1.compile compile(source, filename, mode[, flags[, dont_inherit]]) 用来编译一段字符串的源码,结果可以生成字节码或者AST(抽像语法树),字节码可以使用函数exec()来执行,而AST可以使用eval()来继续编译. >>> str = "for i in range(0,10): print(i)" >>> c = compile(str,'','exec') >

python之闭包函数 装饰器 作业

一:编写函数,(函数执行的时间是随机的) import randomdef t(): time.sleep(random.randrange(1,3)) print('hello')二:编写装饰器,为函数加上统计时间的功能 import timeimport randomdef timebe(func): def wrapper(*args,**kwargs): start_time=time.time() res = func(*args, **kwargs) end_time=time.ti

C++函数装饰器

今天在网上看到一个python实现的函数装饰器,尝试用C++11实现了一下,最后很粗糙的完成了,代码如下. 函数装饰器:接受一个函数.将此函数进行一些装饰,成为另一个函数.新生产的函数具有原函数的功能,另外还会做一些其他的功能.返回新函数. 由于Python中一切皆对象,把类型也当成对象看待,把函数的参数和返回值也当成对象看待,所以很容易就实现出来.而c++是一门静态类型语言,编译器做类型检查,执行期间没有类型相关的信息(除了RTTI).所以实现起来比较麻烦,只能使用模板.函数指针.可变参数.函

python入门(六)装饰器的理解

装饰器用于拓展原有函数功能的一种函数比如: def helloWorld(fun) def out() print ("======start========") fun() print ("=====end======") return out @helloWorld def back () print ("let's go") back() 运行结果: ======start======== let's go =====end====== b

Python 函数装饰器入门

原文链接: --> A guide to Python's function decorators Python功能强劲,语法表现力强,尤其装饰器深深的吸引着我.在设计模式中,装饰器可以在不使用子类的情况下,动态的改变函数,方法以及类的功能.这个功能非常有用,特别在你想扩展函数的功能同时又不想改变原有的函数.的确,我们任意的实现装饰器设计模式,但是,python通过提供简单的语法和特性让装饰器的实现变的如此简单. 在本文中,我将用一组例子来深入浅入python 函数装饰器的功能,所有的例子都是在

python基础 带参数以及返回值的函数装饰器

1 #带参数以及返回值的函数装饰器,上一篇博客记录了无参数函数装饰器写法以及使用方案,当函数有参数以及返回值时需要将装饰器进行如下修稿 2 def timer(fun): 3 def deco(*args,**kwargs): #被装饰函数实际是执行deco,所以在此将被装饰函数参数进行传递 4 start_time = time.time() 5 res = fun(*args,**kwargs) #将被装饰函数的返回值接收 6 stop_time = time.time() 7 return