python 内部有许多内建装饰器, 它们都有特别的功能, 下面对其归纳一下.
python 装饰器介绍
参考: https://www.cnblogs.com/cwp-bg/p/9547797.html
python 自带装饰器
staticmethod
staticmethod 装饰器的功能是去除类的方法默认第一个参数是类的实例, 使得该方法成为一个普通的函数, staticmethod 是一个类, 属于类装饰器.
- class Person(object):
- def eat(self):
- print('eat thing')
- @staticmethod
- def go(): # 不再传递 self
- print('go')
- classmethod
类定义时, 内部的方法默认是类的实例对象的方法, classmethod 装饰器使得定义的方法变成类方法, 类方法的第一个参数是类本身; 调用类方法不需要创建类的实例. classmethod 也是一个类, 所以 classmethod 是一个类装饰器.
- class Person(object):
- _num_ear = 2
- def eat(self):
- print('eat thing')
- @classmethod
- def go(cls):
- print(cls._num_ear)
- print('go')
- if __name__ == '__main__':
- Person.go() # 无需创建实例, 直接调用.
- property
对于一个类的属性, python 的访问是没有限制的, 但有时候我们需要对属性的访问加以限制, property 装饰器就是干这个的.
property 是一个类, 它有三个方法, deleter,setter,getter, 有两种使用方式.
- class Person(Animal):
- _num_ear = 2
- def __init__(self):
- self._name = 'xiaoming'
- self.age = 20
- def get_name(self):
- print('get name')
- return self._name
- def set_name(self, name):
- print('set name')
- self._name = name
- def delete_name(self):
- print('del name')
- del self._name
- name = property(get_name, set_name, delete_name, doc='name of person')
- if __name__ == '__main__':
- p = Person()
- print(p.name) # 会调用 get_name
- p.name = 'xxxx' # 会调用 set_name
- del p.name # 会调用 delete_name
property 可以手动指定限制的函数, 有四个参数, 但是这样显得比较麻烦, 可以使用装饰器的形式.
- class Person(Animal):
- _num_ear = 2
- @property
- def name(self):
- return self._name
- @name.setter
- def name(self, nm):
- self._name = nm
- @name.deleter
- def name(self):
- del self._name
- if __name__ == '__main__':
- p = Person()
- print(p.name)
- p.name = 'xxxx'
- del p.name
一个函数被 property 装饰后返回的是 property 对象, 只有 fget 参数的函数可以被 property, 因为装饰器只接受一个参数; 另外的属性设置和删除需要直观调用响应的方法.
abstractmethod
python 的抽象类和 java 不一样, java 的抽象类不能实例化, 同时抽象方法子类必须实现, 否则报错! 但是 python 抽象类默认是可以实例化的, 也可以这样说, 如果我们对抽象类定义: 本身不能实例化, 子类必须实现抽象方法; 那么我们一般写的基类都不是抽象类. 如果想要实现 java 中的抽象类的效果该怎么办呢? 使用 abstractmethod 装饰器, 含义是抽象方法.
一个类中的任何方法被 abstractmethod 装饰后, 这个类不能实例化并且子类必须实现被 abstractmethod 装饰的方法.
- from abc import abstractmethod,ABCMeta
- class Animal(metaclass=ABCMeta):
- @abstractmethod
- def eat(self):
- pass
- class Person(Animal):
- _num_ear = 2
- def eat(self):
- print('eat thing')
- @classmethod
- def go(cls):
- print(cls._num_ear)
- print('go')
如果需要定义一个类是抽象类, 那么它需要继承 ABCMeta 而不是 object, 这样 abstractmethod 装饰器才会起作用. 其起作用的原理是将一个方法的__isabstractmethod__属性设置为 True, 这样解释器就会检查子类是否实现了抽象方法.
参考
- https://docs.python.org/3/library/collections.html
- https://blog.csdn.net/Liveor_Die/article/details/78953745
来源: https://www.cnblogs.com/cwp-bg/p/9555201.html