python如何实现分卷压缩_Python进阶——如何实现一个装饰器?

本文深入探讨了Python装饰器的实现和原理,包括闭包、装饰器的定义及其在日志记录、性能监控等方面的应用。通过装饰器,开发者可以不修改原方法代码,增加额外功能,如记录方法执行时间、执行次数和实现本地缓存等。文章还介绍了如何创建带参数的装饰器以及使用类来实现装饰器,进一步提高了装饰器的灵活性和适用性。
摘要由CSDN通过智能技术生成

de65b86712c1e9ad054688b51f8ada1c.png
阅读本文大约需要 10 分钟。

在 Python 开发中,我们经常会看到使用装饰器的场景,例如日志记录、权限校验、本地缓存等等。

使用这些装饰器,给我们的开发带来了极大的便利,那么一个装饰器是如何实现的呢?

这篇文章我们就来分析一下,Python 装饰器的使用及原理。

一切皆对象

在介绍装饰器前,我们需要理解一个概念:在 Python 开发中,一切皆对象

什么意思呢?

就是我们在开发中,无论是定义的变量(数字、字符串、元组、列表、字典)、还是方法、类、实例、模块,这些都可以称作对象

怎么理解呢?在 Python 中,所有的对象都会有属性和方法,也就是说可以通过「.」去获取它的属性或调用它的方法,例如像下面这样:

# coding: utf8

i = 10 # int对象
print id(i), type(i)
# 140703267064136, <type 'int'>

s = 'hello' # str对象
print id(s), type(s), s.index('o')
# 4308437920, <type 'str'>, 4

d = {
    'k': 10} # dict对象
print id(d), type(d), d.get('k')
# 4308446016, <type 'dict'>, 10

def hello(): # function对象
    print 'Hello World'
print id(hello), type(hello), hello.func_name, hello()
# 4308430192, <type 'function'>, hello, Hello World

hello2 = hello  # 传递对象
print id(hello2), type(hello2), hello2.func_name, hello2()
# 4308430192, <type 'function'>, hello, Hello World

# 构建一个类
class Person(object):

    def __init__(self, name):
        self.name = name

    def say(self):
        return 'I am %s' % self.name

print id(Person), type(Person), Person.say
# 140703269140528, <type 'type'>, <unbound method Person.say>

person = Person('tom')  # 实例化一个对象
print id(person), type(person),
# 4389020560, <class '__main__.Person'>
print person.name, person.say, person.say()
# tom, <bound method Person.say of <__main__.Person object at 0x1059b2390>>, I am tom

我们可以看到,常见的这些类型:intstrdictfunction,甚至 classinstance 都可以调用 idtype 获得对象的唯一标识和类型。

例如方法的类型是 function,类的类型是 type,并且这些对象都是可传递的。

对象可传递会带来什么好处呢?

这么做的好处就是,我们可以实现一个「闭包」,而「闭包」就是实现一个装饰器的基础。

闭包

假设我们现在想统计一个方法的执行时间,通常实现的逻辑如下:

# coding: utf8

import time

def hello():
    start = time.time() # 开始时间
    time.sleep(1)       # 模拟执行耗时
    print 'hello'
    end = time.time()   # 结束时间
    print 'duration time: %ds' % int(end - start) # 计算耗时

hello()

# Output:
# hello
# duration time: 1s

统计一个方法执行时间的逻辑很简单,只需要在调用这个方法的前后,增加时间的记录就可以了。

但是,统计这一个方法的执行时间这么写一次还好,如果我们想统计任意一个方法的执行时间&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值