对Python装饰器的个人理解方法

简介:

  在自己好好总结并对Python装饰器的执行过程进行分解之前,对于装饰器虽然理解它的基本工作方式,但对于存在复杂参数的装饰器(装饰器和函数本身都有参数),总是会感到很模糊,即使这会弄懂了,下一次也很快忘记,其实本质上还是没有多花时间去搞懂其中的细节问题。

        虽然网络上已经有很多这样的文章,但显然都是别人的思想,因此自己总是记不牢,所以花点时间自己好好整理一下。

        最近在对《Python核心编程》做总结,收获了不少,下面分享一下我自己对于Python装饰器的理解,后面还提供了一个较为复杂的Python装饰器的执行过程的分解,可以参考一下。




1.Python装饰器的出现


         在没有装饰器之前,如果要在类中定义一个静态方法,需要使用下面的方法:

1
2
3
class  MyClass( object ):
     def  staticFoo():
         staticFoo  =  staticmethod (staticFoo)

        即要在该静态方法中加入类似staticmethod()内建函数将该方法转换为静态方法,这显然非常麻烦,而有了装饰器之后,就可以写成下面这样:

1
2
3
4
class  MyClass( object ):
     @ staticmethod
     def  staticFoo():
         pass

        这样就简洁很多了。




2.Python装饰器类型与理解


(1)无参数装饰器    

  • 一个装饰器

        下面的情况:

1
2
3
@f
def  foo():
     pass

        其实就相当于:

1
2
3
def  foo():
     pass
foo  =  g(foo)
  • 多个装饰器

        下面的情况:

1
2
3
4
@g
@f
def  foo():
     pass

        就相当于:

1
2
3
def  foo():
     pass
foo  =  g(f(foo))


(2)含参数装饰器

  • 带有参数的一个装饰器

        下面的情况:

1
2
3
@decomaker (deco_args)
def  foo():
     pass

        就相当于:

1
2
3
def  foo():
     pass
foo  =  decomaker(deco_args)(foo)

        用这样的思想去理解就非常好理解了:decomaker()用deco_args做了些事并返回函数对象,而该函数对象正是以foo作为其参数的装饰器

        下面多个装饰器的例子也是按这样的思想去理解。

  • 带有参数的多个装饰器

        下面的情况:

1
2
3
4
@deco1 (deco_arg)
@deco2 ()
def  foo():
     pass

        就相当于:

1
2
3
def  foo():
     pass
foo  =  deco1(deco_arg)(deco2(foo))




3.Python装饰器执行过程的手动分解


        OK,有了上面的理论基础,理解下面一个较为复杂的装饰器就很容易了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from  functools  import  wraps
 
def  log(text):
     def  decorator(func):
         @wraps(func)                     #it works like:wraper.__name__ = func.__name__
         def  wrapper( * args,  * * kwargs):
             print  '%s %s():'  %  (text, func.__name__)
             return  func( * args,  * * kwargs)
         return  wrapper
     return  decorator
 
 
@log ( 'Hello' )
def  now(area):
     print  area,  '2016-01-23'
     
 
now( 'Beijing' )
print  'The name of function now() is:' , now.__name__

        执行如下:

1
2
3
4
/ usr / bin / python2. 7  / home / xpleaf / PycharmProjects / decorator_test / dec10.py
Hello now():
Beijing  2016 - 01 - 23
The name of function now()  is : now

对于该程序的执行过程,可以分析如下:

1.先执行log('Hello')函数,此时返回了一个新的函数,只不过其中的text变量被替换为'Hello',所以用来装饰now函数的新的装饰器如下:

1
2
3
4
5
6
def  decorator(func):
     @wraps(func)                     #it works like:wraper.__name__ = func.__name__
     def  wrapper( * args,  * * kwargs):
         print  '%s %s():'  %  ( 'Hello' , func.__name__)
         return  func( * args,  * * kwargs)
     return  wrapper

2.所以此时的now函数,就相当于:

1
now  =  decorator(now)

3.即now就相当于:

1
2
3
4
def  now( * args,  * * kwargs):
     print  '%s %s():'  %  ( 'Hello' , old_now.__name__)
     return  old_now( * args,  * * kwargs)
# 现在的函数名称变为了now而不是wrapper,是因为使用了wraps装饰器

   所以,输出的结果也就非常好理解了。

        关于wraps,它也是一个装饰器,使用它的作用是,被我们用自定义装饰器修改后的函数,它的函数名称,即func.__name__跟原来是一样的,而它的工作原理正如上面所提及的,即:

1
wraper.__name__  =  func.__name__

        也就是说,使用wraps可以不改变原来函数的属性,当然,上面只是简单说明了一下其工作原理,详细的可以参考wraps的源代码。




本文转自 xpleaf 51CTO博客,原文链接:http://blog.51cto.com/xpleaf/1763567,如需转载请自行联系原作者

相关文章
|
29天前
|
调度 Python
微电网两阶段鲁棒优化经济调度方法(Python代码实现)
微电网两阶段鲁棒优化经济调度方法(Python代码实现)
|
25天前
|
程序员 测试技术 开发者
Python装饰器:简化代码的强大工具
Python装饰器:简化代码的强大工具
151 92
|
1月前
|
Python
Python字符串center()方法详解 - 实现字符串居中对齐的完整指南
Python的`center()`方法用于将字符串居中,并通过指定宽度和填充字符美化输出格式,常用于文本对齐、标题及表格设计。
|
2月前
|
安全 Python
Python语言中常用的文件操作方法探讨
通过上述方法的结合使用,我们可以构筑出强大并且可靠的文件操作逻辑,切实解决日常编程中遇到的文件处理问题。
157 72
|
3月前
|
Python
掌握Python装饰器:轻松统计函数执行时间
掌握Python装饰器:轻松统计函数执行时间
247 76
|
28天前
|
机器学习/深度学习 数据采集 算法
【CNN-BiLSTM-attention】基于高斯混合模型聚类的风电场短期功率预测方法(Python&matlab代码实现)
【CNN-BiLSTM-attention】基于高斯混合模型聚类的风电场短期功率预测方法(Python&matlab代码实现)
|
3月前
|
存储 机器学习/深度学习 人工智能
稀疏矩阵存储模型比较与在Python中的实现方法探讨
本文探讨了稀疏矩阵的压缩存储模型及其在Python中的实现方法,涵盖COO、CSR、CSC等常见格式。通过`scipy.sparse`等工具,分析了稀疏矩阵在高效运算中的应用,如矩阵乘法和图结构分析。文章还结合实际场景(推荐系统、自然语言处理等),提供了优化建议及性能评估,并展望了稀疏计算与AI硬件协同的未来趋势。掌握稀疏矩阵技术,可显著提升大规模数据处理效率,为工程实践带来重要价值。
155 58
|
2月前
|
数据管理 开发工具 索引
在Python中借助Everything工具实现高效文件搜索的方法
使用上述方法,你就能在Python中利用Everything的强大搜索能力实现快速的文件搜索,这对于需要在大量文件中进行快速查找的场景尤其有用。此外,利用Python脚本可以灵活地将这一功能集成到更复杂的应用程序中,增强了自动化处理和数据管理的能力。
160 0
|
4月前
|
Python
Python技术解析:了解数字类型及数据类型转换的方法。
在Python的世界里,数字并不只是简单的数学符号,他们更多的是一种生动有趣的语言,用来表达我们的思维和创意。希望你从这个小小的讲解中学到了有趣的内容,用Python的魔法揭示数字的奥秘。
114 26

热门文章

最新文章

推荐镜像

更多