热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

python函数装饰器用法实例详解

这篇文章主要介绍了python函数装饰器用法,以实例形式较为详细的分析了Python函数装饰器的常见使用技巧,需要的朋友可以参考下
本文实例讲述了python函数装饰器用法。分享给大家供大家参考。具体如下:

装饰器经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,
有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

#! coding=utf-8 
import time 
def timeit(func): 
  def wrapper(a): 
    start = time.clock() 
    func(1,2) 
    end =time.clock() 
    print 'used:', end - start 
    print a 
  return wrapper 
@timeit
# foo = timeit(foo)完全等价, 
# 使用之后,foo函数就变了,相当于是wrapper了 
def foo(a,b): 
  pass 
#不带参数的装饰器 
# wraper 将fn进行装饰,return wraper ,返回的wraper 就是装饰之后的fn 
def test(func): 
  def wraper(): 
    print "test start" 
    func() 
    print "end start" 
  return wraper 
@test 
def foo(): 
  print "in foo" 
foo() 

输出:

test start 
in foo 
end start 

装饰器修饰带参数的函数:

def parameter_test(func): 
  def wraper(a): 
    print "test start" 
    func(a) 
    print "end start" 
  return wraper 
@parameter_test 
def parameter_foo(a): 
  print "parameter_foo:"+a 
#parameter_foo('hello') 

输出:

>>> 
test start 
parameter_foo:hello 
end start 

装饰器修饰不确定参数个数的函数:

def much_test(func): 
  def wraper(*args, **kwargs): 
    print "test start" 
    func(*args, **kwargs) 
    print "end start" 
  return wraper 
@much_test 
def much1(a): 
  print a 
@much_test 
def much2(a,b,c,d ): 
  print a,b,c,d 
much1('a') 
much2(1,2,3,4) 

输出:

test start 
a 
end start 
test start 
1 2 3 4 
end start 

带参数的装饰器,再包一层就可以了:

def tp(name,age): 
  def much_test(func): 
    print 'in much_test' 
    def wraper(*args, **kwargs): 
      print "test start" 
      print str(name),'at:'+str(age) 
      func(*args, **kwargs) 
      print "end start" 
    return wraper 
  return much_test 
@tp('one','10') 
def tpTest(parameter): 
  print parameter 
tpTest('python....') 

输出:

in much_test 
test start 
one at:10 
python.... 
end start 

class locker: 
  def __init__(self): 
    print("locker.__init__() should be not called.") 
  @staticmethod 
  def acquire(): 
    print("locker.acquire() called.(这是静态方法)") 
  @staticmethod 
  def release(): 
    print("locker.release() called.(不需要对象实例") 
def deco(cls): 
  '''cls 必须实现acquire和release静态方法''' 
  def _deco(func): 
    def __deco(): 
      print("before %s called [%s]." % (func.__name__, cls)) 
      cls.acquire() 
      try: 
        return func() 
      finally: 
        cls.release() 
    return __deco 
  return _deco 
@deco(locker) 
def myfunc(): 
  print(" myfunc() called.") 
myfunc() 

输出:

>>> 
before myfunc called [__main__.locker].
locker.acquire() called.(这是静态方法)
 myfunc() called.
locker.release() called.(不需要对象实例
>>> 

class mylocker: 
  def __init__(self): 
    print("mylocker.__init__() called.") 
  @staticmethod 
  def acquire(): 
    print("mylocker.acquire() called.") 
  @staticmethod 
  def unlock(): 
    print(" mylocker.unlock() called.") 
class lockerex(mylocker): 
  @staticmethod 
  def acquire(): 
    print("lockerex.acquire() called.") 
  @staticmethod 
  def unlock(): 
    print(" lockerex.unlock() called.") 
def lockhelper(cls): 
  '''cls 必须实现acquire和release静态方法''' 
  def _deco(func): 
    def __deco(*args, **kwargs): 
      print("before %s called." % func.__name__) 
      cls.acquire() 
      try: 
        return func(*args, **kwargs) 
      finally: 
        cls.unlock() 
    return __deco 
  return _deco 
class example: 
  @lockhelper(mylocker) 
  def myfunc(self): 
    print(" myfunc() called.") 
  @lockhelper(mylocker) 
  @lockhelper(lockerex) 
  def myfunc2(self, a, b): 
    print(" myfunc2() called.") 
    return a + b 
if __name__=="__main__": 
  a = example() 
  a.myfunc() 
  print(a.myfunc()) 
  print(a.myfunc2(1, 2)) 
  print(a.myfunc2(3, 4))

输出:

before myfunc called.
mylocker.acquire() called.
 myfunc() called.
 mylocker.unlock() called.
before myfunc called.
mylocker.acquire() called.
 myfunc() called.
 mylocker.unlock() called.
None
before __deco called.
mylocker.acquire() called.
before myfunc2 called.
lockerex.acquire() called.
 myfunc2() called.
 lockerex.unlock() called.
 mylocker.unlock() called.
3
before __deco called.
mylocker.acquire() called.
before myfunc2 called.
lockerex.acquire() called.
 myfunc2() called.
 lockerex.unlock() called.
 mylocker.unlock() called.
7

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

推荐阅读
  • Python 异步编程:深入理解 asyncio 库(上)
    本文介绍了 Python 3.4 版本引入的标准库 asyncio,该库为异步 IO 提供了强大的支持。我们将探讨为什么需要 asyncio,以及它如何简化并发编程的复杂性,并详细介绍其核心概念和使用方法。 ... [详细]
  • 本文详细介绍 Go+ 编程语言中的上下文处理机制,涵盖其基本概念、关键方法及应用场景。Go+ 是一门结合了 Go 的高效工程开发特性和 Python 数据科学功能的编程语言。 ... [详细]
  • 本文介绍了在安装或运行 Python 项目时遇到的 'ModuleNotFoundError: No module named setuptools_rust' 错误,并提供了解决方案。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 如何在PHPcms网站中添加广告
    本文详细介绍了在PHPcms网站后台添加广告的方法,涵盖多种常见的广告形式,如百度广告和Google广告,并提供了相关设置的步骤。同时,文章还探讨了优化网站流量的SEO策略。 ... [详细]
  • 本文详细介绍了如何使用Python编写爬虫程序,从豆瓣电影Top250页面抓取电影信息。文章涵盖了从基础的网页请求到处理反爬虫机制,再到多页数据抓取的全过程,并提供了完整的代码示例。 ... [详细]
  • 本文介绍如何使用 Python 编写程序,检查给定列表中的元素是否形成交替峰值模式。我们将探讨两种不同的方法来实现这一目标,并提供详细的代码示例。 ... [详细]
  • 本文将介绍由密歇根大学Charles Severance教授主讲的顶级Python入门系列课程,该课程广受好评,被誉为Python学习的最佳选择。通过生动有趣的教学方式,帮助初学者轻松掌握编程基础。 ... [详细]
  • 在哈佛大学商学院举行的Cyberposium大会上,专家们深入探讨了开源软件的崛起及其对企业市场的影响。会议指出,开源软件不仅为企业提供了新的增长机会,还促进了软件质量的提升和创新。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • 探讨一个显示数字的故障计算器,它支持两种操作:将当前数字乘以2或减去1。本文将详细介绍如何用最少的操作次数将初始值X转换为目标值Y。 ... [详细]
  • 在Ubuntu 16.04 LTS上配置Qt Creator开发环境
    本文详细介绍了如何在Ubuntu 16.04 LTS系统中安装和配置Qt Creator,涵盖了从下载到安装的全过程,并提供了常见问题的解决方案。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 本文详细解析了如何使用Python语言在STM32硬件平台上实现高效的编程和快速的应用开发。通过具体的代码示例,展示了Python简洁而强大的特性。 ... [详细]
  • 本文详细解析了Python中的os和sys模块,介绍了它们的功能、常用方法及其在实际编程中的应用。 ... [详细]
author-avatar
袁甲2012_498
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有