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

简介:

0.说明

         

        在自己好好总结并对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的源代码。

        在GitHub上给出了10个理解装饰器的例子,可以参考一下:https://github.com/xpleaf/decorator

相关文章
|
2天前
|
Java Python
全网最适合入门的面向对象编程教程:50 Python函数方法与接口-接口和抽象基类
【9月更文挑战第18天】在 Python 中,虽无明确的 `interface` 关键字,但可通过约定实现类似功能。接口主要规定了需实现的方法,不提供具体实现。抽象基类(ABC)则通过 `@abstractmethod` 装饰器定义抽象方法,子类必须实现这些方法。使用抽象基类可使继承结构更清晰、规范,并确保子类遵循指定的方法实现。然而,其使用应根据实际需求决定,避免过度设计导致代码复杂。
|
2天前
|
设计模式 监控 数据安全/隐私保护
探索Python中的装饰器:从基础到高级应用
Python的装饰器是一种强大而灵活的工具,它允许开发者在不修改现有函数代码的情况下,增加或修改函数的行为。本文将深入探讨装饰器的基本概念、实际应用以及如何利用装饰器编写更加高效和可维护的代码。通过具体的代码示例,我们将揭示装饰器在软件开发中的巨大潜力。
|
4天前
|
Python
全网最适合入门的面向对象编程教程:Python函数方法与接口-函数与方法的区别和lamda匿名函数
【9月更文挑战第15天】在 Python 中,函数与方法有所区别:函数是独立的代码块,可通过函数名直接调用,不依赖特定类或对象;方法则是与类或对象关联的函数,通常在类内部定义并通过对象调用。Lambda 函数是一种简洁的匿名函数定义方式,常用于简单的操作或作为其他函数的参数。根据需求,可选择使用函数、方法或 lambda 函数来实现代码逻辑。
|
2天前
|
缓存 Python
探索Python中的装饰器:原理与应用
本文深入探讨了Python中装饰器的概念,从基本定义到实际应用进行了系统性的阐述。通过实例展示了如何利用装饰器来增强函数功能,同时详细解释了其背后的运行机制和实现原理。此外,文章还讨论了装饰器在软件开发中的实际应用场景,为读者提供了实用的编程技巧和最佳实践。
|
3天前
|
缓存 开发者 Python
探索Python中的装饰器
本文将深入探讨Python中一个高级且强大的功能——装饰器。我们将从基本概念开始,逐步解析其工作原理及实际应用。通过具体示例,读者将能够理解如何使用装饰器来扩展函数功能,以及如何利用这一特性优化代码结构。无论是新手还是经验丰富的开发者,都能从中获取有价值的见解。
16 5
|
3天前
|
Python
探索Python编程中的装饰器
【9月更文挑战第18天】本文将深入探讨Python中的一项强大功能——装饰器。通过简化的实例,我们会了解如何创建和使用装饰器来增强函数的功能,同时保持代码的整洁性和可读性。
12 3
|
3天前
|
设计模式 Python
探索Python中的装饰器:从基础到高级应用
本文深入探讨了Python中装饰器的使用,包括其基本定义、实际应用以及如何创建自定义装饰器。通过具体示例,我们将揭示装饰器在函数编程中的强大功能和灵活性,帮助读者更好地理解和运用这一技术。
16 3
|
3天前
|
存储 数据处理 索引
Python列表操作的方法总结
通过掌握上述方法,你可以有效地操作Python列表,完成各种数据处理任务。列表的灵活性和多功能性使其成为Python编程中不可或缺的工具。
12 1
|
3天前
|
缓存 数据安全/隐私保护 Python
探索Python中的装饰器
在本文中,我们将深入探讨Python装饰器的概念、应用及其背后的原理。通过具体的代码示例,您将学会如何使用装饰器来扩展函数功能,而无需永久性地修改它们。我们还将了解不同类型的装饰器,包括一元和二元装饰器,并学习如何创建和使用自定义装饰器。预计阅读时间:5分钟。
|
2天前
|
设计模式 Python
探索Python中的装饰器:从基础到高级应用
本文深入探讨了Python中装饰器的概念、使用方法以及实际应用。通过具体示例,阐述了装饰器如何增强函数功能,实现代码复用和逻辑分离,旨在帮助读者理解并有效利用这一强大工具。
11 0