一、类的内置装饰器
在介绍装饰器的时候介绍了装饰器函数实际就是3个函数组成的闭包。装饰器函数的功能是给被装饰的函数额外的功能。在类中,也可以使用一些内置的装饰器用来给类方法提供额外的功能。
常见的类方法的内置装饰器函数有3种(必须掌握):
@property:简化方法的访问,像访问属性一样访问函数
@classmethod:定义类方法,可以通过类.方法直接访问方法,而不用实例的对象去访问。简化实例化过程。
@staticmethod:静态方法,可以理解为单纯的在类中定义一个与该类完全无关的方法。
实例1:定义类并使用类的内置装饰器装饰方法
class Animal(): leg = 1 def __init__(self,name,food): self.name = name self.food = food @property ##属性方式访问方法:dog.legs,不能dog.legs() def legs(self): print("Animal all have {} head".format(Animal.leg)) @classmethod ##类方法,可以直接通过类访问实例。Class.say(instance) def say(cls,self): print('My name is {0}, I like eat {1}'.format(self.name,self.food)) @staticmethod ##静态方法,就是一个函数,可以和实例,类无关系 def count(): print("Just a funtion and no relation with class") dog = Animal('hashiqi','bone') cat = Animal('duanweimao','fish') dog.legs Animal.say(dog) Animal.say(cat) dog.count()
输出:
Animal all have 1 head
My name is hashiqi, I like eat bone
My name is duanweimao, I like eat fish
Just a funtion and no relation with class
总结:
@property 装饰过的函数返回的不再是一个函数,而是一个property对象
装饰过后的方法不再是可调用的对象,可以看做数据属性直接访问。
@staticmethod (静态方法)把没有参数的函数装饰过后变成可被实例调用的函数,
函数定义时是没有参数的,可以不接收参数
@classmethod (类方法)把装饰过的方法变成一个classmethod类对象,既能能被类调用又能被实例调用。
注意参数是cls代表这个类本身。用实例的方法只能被实例调用。
一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。
这有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁
实例2:类的@staticmethod或@classmethod方法不仅可以直接使用类调用,也可以使用实例调用
class Fish(object): def __init__(self, name): self.name = name def bubble(self): print("{0}吐一串泡泡!".format(self.name)) def swam(self): print("{0}游得很快!".format(self.name)) class Turbot(Fish): def __init__(self, name): super(Turbot, self).__init__(name) def run(self): super(Turbot, self).swam() @classmethod def bala(cls): print("balala") @staticmethod def kala(): print("kala") class Whale(Fish): def __init__(self, name): super(Whale, self).__init__(name) fish = Turbot('多宝鱼') fish.bala() ##实例调用:@classmethod fish.kala() ##实例调用:@staticmethod Turbot.bala() ##类调用:@classmethod Turbot.kala()##类调用:@staticmethod
输出:
balala
balala
kala
kala
可以看出对于@staticmethod或@classmethod可以无需实例化直接使用方法,但是也可以通过实例访问