前言

本文是自己在一个教学系列学习的总结吧,入门学习,不会有太深入的内容。

定义

课程里的叙述:

是一种高阶_函数_,用来装饰函数的器物。

自己查的内容可能不够准确:

高阶函数:处理函数的函数
装饰函数:为其他函数增加额外功能

我自己的理解为:装饰器可以让一个函数具有其他的功能。

代码示例

#装饰器
def print_datetime(func):
# 一个*代表可变参数,两个**代表关键字参数,这里的意思就是把传给wrapper的参数(无论是什么样的)都再给func()传过去
    def wrapper(*args, **kw): 
        print(datetime.now())
        func(*args, **kw) 
    return wrapper
def hello(name):
    print('Hello, I'm {}'.format(name))
middle = print_datetime(hello)
middle('Sleepking')

上述代码,print_datetime()是一个装饰器,作用是让别的函数可以输出当前日期。最后一行代码会输出一个时间和hello.i'am sleepking。

上边的实现用到了函数里的可变参数和关键字参数,之前介绍这两个概念的时候一直没有特别的明白如何使用,到这里感觉特别适合用来在高阶函数中使用(用来处理函数)。

这个例子中,装饰器(函数)其实返回了一个函数,我感觉可能所有的基本上都是这样,将本来的函数变成了一个多功能的函数

一个更简单的调用方式

#先定义一个装饰器
def print_datetime(func):
def wrapper(*args, **kw): 
        print(datetime.now())
        func(*args, **kw) 
    return wrapper
#通过@装饰器名称方式将装饰器的功能加到后边定义的函数里。
@print_datetime
def hello(name):
    print('Hello, I'm {}'.format(name))
hello('Tom') 
# 上边的调用相当于使用wrapper('Tom')

property 装饰器

我所看课程直接就介绍了property装饰器,但是我个人感觉里面讲的让我不容易理解,不得已自己又去查了一些内容。最后把自己认为目前自己需要知道的内容总结如下:

  • @property装饰器的作用是让你能以调用属性的方式使用你在类中定义的函数。
  • @property本身又创建了另一个装饰器,@xxx.setter xxx为被装饰的函数,一般都说用来设置属性,其实你可以干任何事情,但这里的被装饰的函数名一定要和@property装饰的函数名一致
  • 类中任何函数都可被此装饰,一般来说用在类属性的get,set函数中

代码示例

class User:
    def __init__(self,name,email):
        self.name = name
        self.email = email
    def get_name(self):
        return self.name
    def set_name(self):
        self.name = name
    @property
    def get_email(self):
        return self.email
#上边可以用xx.get_email 调用
    @property
    def print_word(self):
        print('ko you {}'.format(self.name))
    @print_word.setter
    def print_word(self,word):
        print('ko you {}'.format(word))
#定义了setter就可以给函数赋值因为‘变为’了属性 print_word() = 'ok'

这里自己一开始一直不理解,最后发现,不理解的原因是自己一直以为这个装饰器只能用来对类属性之类的进行操作。但其实这个装饰器的作用就是把一个方法变为属性一样调用,因为变成类似属性了,所以会有一个xxx.setter的另一个装饰器(属性可以赋值之类的)。

思考

这里是因为自己是入门级别的原因吧,觉得这个做法有点绕。

函数本来是实现一个功能,用了装饰器实现了更多功能,除非这两个功能之间有什么紧密的联系,否则为什么不调用两个函数呢?可能还是没能真正了解这个概念的精髓吧。

个人感觉还是看官网的各种教程比较好,奈何自己的英语水平不行,所以只好作罢了。