python之内置装饰器使用
2019-07-24

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._nameif __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,ABCMetaclass Animal(metaclass=ABCMeta): @abstractmethod def eat(self): passclass 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