专栏首页不仅仅是python(三十七) 初遇python之Decorators装饰器

(三十七) 初遇python之Decorators装饰器

各位读者大大们大家好,今天学习python的Decorators装饰器,并记录学习过程欢迎大家一起交流分享。

新建一个python文件命名为py3_decorators.py,在这个文件中进行操作代码编写:

#Decorators装饰器
#装饰器是一种动态改变函数功能的方法。
#例如,如果您想在运行函数时记录日志信息,
#您可以使用装饰器添加此功能
#而无需修改原始函数的源代码

#首先定义一个函数
def outer_function():
  msg = 'Hello'
  def inner_function():
    print(msg)
  return inner_function()

#调用函数
outer_function()
#打印结果为:Hello
#将上面的函数做下调整传递参数
def outer_function(msg):
  def inner_function():
    print(msg)
  return inner_function

#初始化函数
hi_func = outer_function('Hi')
bye_func = outer_function('Bye')
#调用
hi_func()
bye_func()
#接下来写一个作为装饰器的函数
#参数为一个原始的函数
#执行这个原始函数 并返回
def decorator_function(original_function):
  def wrapper_function():
    print('wrapper_function在{}之前执行'.format(original_function.__name__))
    return original_function()
  return wrapper_function
#定义一个函数作为原始函数
def display():
  print('display function ran')

#给display函数添加装饰器
decorator_display = decorator_function(display)
#调用函数
decorator_display()
#wrapper_function在display之前执行
#display function ran
#使用装饰器语法的形势执行上边的原始函数
@decorator_function
def display():
  print('display function ran')
#直接调用display函数
display()  
#wrapper_function在display之前执行
#display function ran
#熟悉java的童鞋应该知道
#装饰器实际类似于java中的annotation注解
#继续修改装饰器函数添加参数
def decorator_function(original_function):
  def wrapper_function(*args,**kwargs):
    print('wrapper_function在{}之前执行'.format(original_function.__name__))
    return original_function(*args,**kwargs)
  return wrapper_function
#定义一个带参数函数
#并添加装饰器
@decorator_function
def display_info(name,age):
  print('display_info run with{},{}'.format(name,age))
#调用函数
display_info('TBag',28)
#wrapper_function在display_info之前执行
#display_info run withTBag,28
#创建一个装饰器类:
class decorator_cls():
  def __init__(self,original_function):
    self.original_function = original_function

  def __call__(self,*args,**kwargs):
      print('__call__ 在{}之前执行'.format(self.original_function.__name__))
      return self.original_function(*args,**kwargs)

@decorator_cls
def display():
  print('display function ran')
display()  
#__call__ 在display之前执行
#display function ran
@decorator_cls
def display_info(name,age):
  print('display_info run with{},{}'.format(name,age))
#调用函数
display_info('TBag',28)
#__call__ 在display_info之前执行
#display_info run withTBag,28

#下面写两个自定义的装饰器函数
#一个用来记录日志
#一个用来记录函数执行的时间
def my_logger(original_function):
  #导入日志模块
  #后面文章会细讲
  #这里只做了解
  import logging
  logging.basicConfig(filename='{}.log'.format(original_function.__name__),level=logging.INFO)

  def wrapper(*args,**kwargs):
    logging.info('Ran with args:{} and kwargs:{}'.format(args,kwargs))
    return original_function(*args,**kwargs)
  return wrapper

def my_timer(original_function):
  import time

  def wrapper(*args,**kwargs):
    t1 = time.time()
    result = original_function(*args,**kwargs)
    t2 = time.time() - t1
    print('{} ran in {} sec'.format(original_function.__name__,t2))
  return wrapper
#使用日志装饰器
@my_logger
def display_info(name,age):
  print('display_info run with {},{}'.format(name,age))
#调用函数
display_info('TBag',28)
display_info('Mc',18)
#运行后会生成一个日志文件
#display_info.log
#并记录日志信息

#使用时间装饰器
import time
@my_timer
def display_info(name,age):
  #为了测试效果这里休眠1秒
  time.sleep(1)
  print('display_info run with {},{}'.format(name,age))
#调用函数
display_info('yale',18)
#display_info run with yale,18
#display_info ran in 1.0000569820404053 sec

#我们给display_info
#同时添加记录日志和时间测试装饰器
@my_logger
@my_timer
def display_info(name,age):
  #为了测试效果这里休眠1秒
  time.sleep(1)
  print('display_info run with {},{}'.format(name,age))
#调用函数
display_info('yale',18)

###接下来看带参数的装饰器函数
def prefix_decorator(prefix):
    def decorator_function(original_function):
        def wrapper_function(*args, **kwargs):
            print(prefix, '执行之前', original_function.__name__)
            result = original_function(*args, **kwargs)
            print(prefix, '执行之后', original_function.__name__, '\n')
            return result
        return wrapper_function
    return decorator_function


@prefix_decorator('LOG:')
def display_info(name, age):
    print('display_info ran with arguments ({}, {})'.format(name, age))


display_info('John', 25)
display_info('Travis', 30)

#LOG: 执行之前 display_info
#display_info ran with arguments (John, 25)
#LOG: 执行之后 display_info 

#LOG: 执行之前 display_info
#display_info ran with arguments (Travis, 30)
#LOG: 执行之后 display_info 

今天初学python的Decorators装饰器学习就到这里!

关注公号

下面的是我的公众号二维码图片,欢迎关注。

yale记公众号

本文分享自微信公众号 - yale记(python_yale_learning),作者:yale记

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • (八) 初遇python甚是喜爱之Functions函数操作

    各位读者大大们大家好,今天学习python的Functions函数操作,并记录学习过程欢迎大家一起交流分享。

    亚乐记
  • (二十七) 初遇python OOP面向对象编程-继承

    各位读者大大们大家好,今天学习python的面向对象编程-继承,并记录学习过程欢迎大家一起交流分享。

    亚乐记
  • web爬虫-Selenium IDE安装使用

    今天将学习使用一个非常有用的浏览器插件Selenium IDE,用于网站的测试和自动化,这里以谷歌浏览器作为测试。

    亚乐记
  • Hexo+Next指定文章隐藏侧栏

    近期在幕布的活动比较多,想新增一个幕布的作品集页面,所以就依葫芦画瓢,新建一个幕布作品集的页面。

    你好我是森林
  • 聊聊flink Table的OrderBy及Limit

    flink-table_2.11-1.7.0-sources.jar!/org/apache/flink/table/api/table.scala

    codecraft
  • typecho强制https

    Apache下: 打开(如果没有则新建).htaccess,粘贴进以下rewrite代码

    徐大嘴
  • Django messages 消息(中)

    Django 在 django.contrib.messages 中提供三个内建的存储类:

    小团子
  • 挑战者纷至沓来!微信战略藐视,战术还得重视?

    2019年1月15日是互联网的大日子:前快播CEO王欣创办的马桶MT、抖音旗下的多闪和罗永浩的聊天宝,一共三款社交App同日发布,成为古老的社交市场难得一见的奇...

    罗超频道
  • 推荐系统中重要却又容易被忽视的问题有哪些

    在个性化推荐系统中的绕不开的经典问题有哪些介绍了推荐下中不可避免都会遇到的问题,这里介绍一些不可忽视的一些内容。

    abs_zero
  • 前沿 | 罗切斯特大学最新研究成果:AI可以预测我们说什么

    大多数的人可以对自己将要说的话做到完全保密,直到他们张嘴说话的那一秒。但是现在,计算机可以通过寻找你的大脑中与你将要说的话相关的大脑活动形式,迅速地预测你在想什...

    AI科技评论

扫码关注云+社区

领取腾讯云代金券