Python深入讲解系列之装饰器

简介: Python深入讲解系列之装饰器

装饰函数和方法
我们先定义两个简单的数学函数,一个用来计算平方和,一个用来计算平方差:

复制代码

get square sum

def square_sum(a, b):
return a2 + b2
//代码效果参考:https://v.youku.com/v_show/id_XNjQwMDM5ODgwNA==.html

get square diff

def square_diff(a, b):
return a2 - b2

print(square_sum(3, 4))
print(square_diff(3, 4))
复制代码
在拥有了基本的数学功能之后,我们可能想为函数增加其它的功能,比如打印输入。我们可以改写函数来实现这一点:

复制代码

modify: print input

get square sum

def square_sum(a, b):
print("intput:", a, b)
return a2 + b2

get square diff

def square_diff(a, b):
print("input", a, b)
return a2 - b2
//代码效果参考:https://v.youku.com/v_show/id_XNjQwNjg1MDc3Ng==.html

print(square_sum(3, 4))
print(square_diff(3, 4))
复制代码
我们修改了函数的定义,为函数增加了功能。

现在,我们使用装饰器来实现上述修改:

复制代码
def decorator(F):
def new_F(a, b):
print("input", a, b)
return F(a, b)
return new_F

get square sum

@decorator
def square_sum(a, b):
return a2 + b2

get square diff

@decorator
def square_diff(a, b):
return a2 - b2

print(square_sum(3, 4))
print(square_diff(3, 4))
复制代码
装饰器可以用def的形式定义,如上面代码中的decorator。装饰器接收一个可调用对象作为输入参数,并返回一个新的可调用对象。装饰器新建了一个可调用对象,也就是上面的new_F。new_F中,我们增加了打印的功能,并通过调用F(a, b)来实现原有函数的功能。

定义好装饰器后,我们就可以通过@语法使用了。在函数square_sum和square_diff定义之前调用@decorator,我们实际上将square_sum或square_diff传递给decorator,并将decorator返回的新的可调用对象赋给原来的函数名(square_sum或square_diff)。 所以,当我们调用square_sum(3, 4)的时候,就相当于:

square_sum = decorator(square_sum)
square_sum(3, 4)
我们知道,Python中的变量名和对象是分离的。变量名可以指向任意一个对象。从本质上,装饰器起到的就是这样一个重新指向变量名的作用(name binding),让同一个变量名指向一个新返回的可调用对象,从而达到修改可调用对象的目的。

与加工函数类似,我们可以使用装饰器加工类的方法。

如果我们有其他的类似函数,我们可以继续调用decorator来修饰函数,而不用重复修改函数或者增加新的封装。这样,我们就提高了程序的可重复利用性,并增加了程序的可读性。

含参的装饰器
在上面的装饰器调用中,比如@decorator,该装饰器默认它后面的函数是唯一的参数。装饰器的语法允许我们调用decorator时,提供其它参数,比如@decorator(a)。这样,就为装饰器的编写和使用提供了更大的灵活性。

复制代码

a new wrapper layer

def pre_str(pre=''):

# old decorator
def decorator(F):
    def new_F(a, b):
        print(pre + "input", a, b)
        return F(a, b)
    return new_F
return decorator

get square sum

@prestr('^^')
def square_sum(a, b):
return a2 + b2

get square diff

@pre_str('T_T')
def square_diff(a, b):
return a2 - b2

print(square_sum(3, 4))
print(square_diff(3, 4))
复制代码
上面的pre_str是允许参数的装饰器。它实际上是对原有装饰器的一个函数封装,并返回一个装饰器。我们可以将它理解为一个含有环境参量的闭包。当我们使用@prestr('^^')调用的时候,Python能够发现这一层的封装,并把参数传递到装饰器的环境中。该调用相当于:

square_sum = prestr('^^') (square_sum)

装饰类
在上面的例子中,装饰器接收一个函数,并返回一个函数,从而起到加工函数的效果。在Python 2.6以后,装饰器被拓展到类。一个装饰器可以接收一个类,并返回一个类,从而起到加工类的效果。

复制代码
def decorator(aClass):
class newClass:
def init(self, age):
self.total_display = 0
self.wrapped = aClass(age)
def display(self):
self.total_display += 1
print("total display", self.total_display)
self.wrapped.display()
return newClass

@decorator
class Bird:
def init(self, age):
self.age = age
def display(self):
print("My age is",self.age)

eagleLord = Bird(5)
for i in range(3):
eagleLord.display()

相关文章
|
12天前
|
缓存 监控 程序员
Python中的装饰器:优雅而强大的函数修饰工具
在Python编程中,装饰器是一种强大的工具,能够在不修改原函数代码的情况下,为函数添加新的功能或行为。本文将深入探讨Python中装饰器的使用方法和实际应用,帮助读者更好地理解和利用这一重要的编程概念。
|
5天前
|
设计模式 缓存 监控
深入理解Python中的装饰器
装饰器是Python中的一项强大的功能,但对初学者来说可能会有些难以掌握。本文将通过具体的例子和详细的解释,帮助读者更好地理解和应用Python中的装饰器,从而提升代码的可读性和复用性。
|
5天前
|
测试技术 开发者 Python
Python中的装饰器:提升函数的灵活性和可重用性
在Python编程中,装饰器是一种强大的工具,它可以在不修改函数本身的情况下,动态地扩展函数的功能。本文将介绍装饰器的工作原理及其在实际开发中的应用,帮助读者更好地理解和利用这一特性。
|
3天前
|
开发者 Python
Python进阶:深入剖析闭包与装饰器的应用与技巧
Python进阶:深入剖析闭包与装饰器的应用与技巧
|
9天前
|
数据安全/隐私保护 Python
Python装饰器是高阶函数,用于在不修改代码的情况下扩展或修改函数行为。它们提供可重用性、模块化和无侵入性的功能增强。
【6月更文挑战第20天】Python装饰器是高阶函数,用于在不修改代码的情况下扩展或修改函数行为。它们提供可重用性、模块化和无侵入性的功能增强。例如,`@simple_decorator` 包装`my_function`,在调用前后添加额外操作。装饰器还能接受参数,如`@logged("INFO", "msg")`,允许动态定制功能。
16 6
|
12天前
|
程序员 测试技术 开发者
Python中的装饰器:优雅而强大的函数修饰工具
装饰器是Python中一种强大而优雅的工具,它可以在不修改原函数代码的情况下,对函数进行增强、扩展或者修改。本文将深入探讨Python中装饰器的基本概念、使用方法以及实际应用,帮助读者更好地理解和运用装饰器这一重要的编程技巧。
|
14天前
|
存储 缓存 Python
野生的Python装饰器案例
野生的Python装饰器案例
|
14天前
|
开发者 Python
Python进阶--装饰器
Python进阶--装饰器
|
18天前
|
缓存 开发者 Python
Python中的装饰器应用及性能优化
本文探讨了Python中装饰器的作用以及如何应用装饰器来提高代码的可读性和灵活性。同时,我们还将介绍一些性能优化的技巧,帮助开发者更好地理解和利用装饰器来提升Python程序的执行效率。
|
20天前
|
缓存 测试技术 Python
Python中的装饰器:优雅而强大的函数修饰工具
在Python编程中,装饰器是一种强大的工具,它可以让我们在不改变函数结构的情况下,对函数进行修饰和扩展。本文将深入探讨Python中装饰器的作用、原理及实际运用,帮助读者更好地理解和运用这一技术。