Python装饰器原理与基本用法分析

本文实例讲述了Python装饰器原理与基本用法。分享给大家供大家参考,具体如下:

装饰器:

意义:在不能改变原函数的源代码,和在不改变整个项目中原函数的调用方式的情况下,给函数添加新的功能

由于不允许改变函数的源代码,在忽略调用方式的情况下,我们可能会有以下结果:

def decorator(func):
  func()
  print("logging")
def test1():
  print("test1")
def test2():
  print("Test2")
decorator(test1)
decorator(test2)

但这改变了原本的调用方式,原本是test1(),现在是decorator(test1)

那么如果我们为了使调用方式不变,是否可以使装饰好的函数decorator的返回值是一个我们需要的函数,再赋值给原来的函数名呢?

于是:

def timmer1(func):
  def warpper():
    start_time = time.time()
    func()
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
   return warpper
test3=timmer1(test3)

好像上面这段代码并没有改变原来的调用方式,调用原来的test3,相当于运行timmer1中的warpper

如果对于无参数的函数来说,上面的代码已经实现了我们的目的,但对于带参数的函数,上面的代码没有传入参数,所以仍然需要修改

于是:

def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    func(*args,**kwargs)
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper

在上上面的代码中,由于实质上,test3已经等于wrapper,所以可以直接使用,test3(参数)来传入参数,为了处理参数不确定数量问题,可以使用可变长度参数

上面代码还存在一个问题,无法获取原本函数中的返回值,那么我们还需要加上一些东西:

import time
def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    res=func(*args,**kwargs)
    return res
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper

使用一个变量记录下原函数的返回值。

这样我们就实现了装饰器的基本功能。

补充:

python提供了一个功能:

@装饰器名
def 目标装饰函数名():
  pass
#上面的效果是 目标装饰函数名=装饰器(目标装饰函数名)

所以在需要替换原函数的时候,可以在目标装饰函数定义的上一行加上@装饰器名

所以上面的代码会变成:

def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    func(*args,**kwargs)
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper
@timmer2
def test7():
  print("test7")
@timmer2
def test6(x):
  print(x)
test7()
test6(2)
import time
def timmer2(func):
  def warpper(*args,**kwargs):
    start_time = time.time()
    res=func(*args,**kwargs)
    return res
    stop_time=time.time()
    print("the func run time is %s"%(stop_time-start_time))
  return warpper
@timmer2
def test4():
  print("test4 run")
  return "test4 done"
test4()
print("--------")
print(test4())

第二个补充:

可以一个函数,可以使用多个装饰器

比如:

@装饰器1

@装饰器2

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python面向对象程序设计入门与进阶教程》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python编码操作技巧总结》及《Python入门与进阶经典教程》

希望本文所述对大家Python程序设计有所帮助。

(0)

相关推荐

  • Python中装饰器高级用法详解

    在Python中,装饰器一般用来修饰函数,实现公共功能,达到代码复用的目的.在函数定义前加上@xxxx,然后函数就注入了某些行为,很神奇!然而,这只是语法糖而已. 场景 假设,有一些工作函数,用来对数据做不同的处理: def work_bar(data): pass def work_foo(data): pass 我们想在函数调用前/后输出日志,怎么办? 傻瓜解法 logging.info('begin call work_bar') work_bar(1) logging.info('cal

  • 深入理解python中的闭包和装饰器

    python中的闭包从表现形式上定义(解释)为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure). 以下说明主要针对 python2.7,其他版本可能存在差异. 也许直接看定义并不太能明白,下面我们先来看一下什么叫做内部函数: def wai_hanshu(canshu_1): def nei_hanshu(canshu_2): # 我在函数内部有定义了一个函数 return canshu_1*canshu_2 return

  • Python中的装饰器用法详解

    本文实例讲述了Python中的装饰器用法.分享给大家供大家参考.具体分析如下: 这里还是先由stackoverflow上面的一个问题引起吧,如果使用如下的代码: 复制代码 代码如下: @makebold @makeitalic def say():    return "Hello" 打印出如下的输出: <b><i>Hello<i></b> 你会怎么做?最后给出的答案是: 复制代码 代码如下: def makebold(fn):    

  • 基于Python 装饰器装饰类中的方法实例

    title: Python 装饰器装饰类中的方法 comments: true date: 2017-04-17 20:44:31 tags: ['Python', 'Decorate'] category: ['Python'] --- 目前在中文网上能搜索到的绝大部分关于装饰器的教程,都在讲如何装饰一个普通的函数.本文介绍如何使用Python的装饰器装饰一个类的方法,同时在装饰器函数中调用类里面的其他方法.本文以捕获一个方法的异常为例来进行说明. 有一个类Test, 它的结构如下: clas

  • Python中的各种装饰器详解

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: 复制代码 代码如下: >>> def test(func):     def _test():         print 'Call the function %s().'%func.func_name         return func()     return _test >

  • 巧用Python装饰器 免去调用父类构造函数的麻烦

    先看一段代码: 复制代码 代码如下: class T1(threading.Thread): def __init__(self, a, b, c): super(T1, self).__init__() self.a = a self.b = b self.c = c def run(self): print self.a, self.b, self.c 代码定义了一个继承自threading.Thread的class,看这句 super(T1, self).__init__() 也有些人喜欢

  • python 装饰器功能以及函数参数使用介绍

    简单的说:装饰器主要作用就是对函数进行一些修饰,它的出现是在引入类方法和静态方法的时候为了定义静态方法出现的.例如为了把foo()函数声明成一个静态函数 复制代码 代码如下: class Myclass(object): def staticfoo(): ............ ............ staticfoo = staticmethod(staticfoo) 可以用装饰器的方法实现: 复制代码 代码如下: class Myclass(object): @staticmethod

  • Python中的多重装饰器

    多重装饰器,即多个装饰器修饰同一个对象[实际上并非完全如此,且看下文详解] 1.装饰器无参数: 复制代码 代码如下: >>> def first(func):     print '%s() was post to first()'%func.func_name     def _first(*args,**kw):         print 'Call the function %s() in _first().'%func.func_name         return func

  • 实例讲解Python编程中@property装饰器的用法

    取值和赋值 class Actress(): def __init__(self): self.name = 'TianXin' self.age = 5 类Actress中有两个成员变量name和age.在外部对类的成员变量的操作,主要包括取值和赋值.简单的取值操作是x=object.var,简单的赋值操作是object.var=value. >>> actress = Actress() >>> actress.name #取值操作 'TianXin' >&g

  • 详解Python中的装饰器、闭包和functools的教程

    装饰器(Decorators) 装饰器是这样一种设计模式:如果一个类希望添加其他类的一些功能,而不希望通过继承或是直接修改源代码实现,那么可以使用装饰器模式.简单来说Python中的装饰器就是指某些函数或其他可调用对象,以函数或类作为可选输入参数,然后返回函数或类的形式.通过这个在Python2.6版本中被新加入的特性可以用来实现装饰器设计模式. 顺便提一句,在继续阅读之前,如果你对Python中的闭包(Closure)概念不清楚,请查看本文结尾后的附录,如果没有闭包的相关概念,很难恰当的理解P

  • python装饰器使用方法实例

    什么是python的装饰器? 网络上的定义:装饰器就是一函数,用来包装函数的函数,用来修饰原函数,将其重新赋值给原来的标识符,并永久的丧失原函数的引用. 最能说明装饰器的例子如下: 复制代码 代码如下: #-*- coding: UTF-8 -*-import time def foo():    print 'in foo()' # 定义一个计时器,传入一个,并返回另一个附加了计时功能的方法def timeit(func): # 定义一个内嵌的包装函数,给传入的函数加上计时功能的包装    d

  • 介绍Python的@property装饰器的用法

    在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9999 这显然不合逻辑.为了限制score的范围,可以通过一个set_score()方法来设置成绩,再通过一个get_score()来获取成绩,这样,在set_score()方法里,就可以检查参数: class Student(object): def get_score(self): return self._score def set_s

随机推荐