同步于CSDN ;音尘杂记
主要介绍了在python中,抽象类的定义、多态的概念、类中属性的封装以及类中常见的修饰器。
1. 抽象类 与Java一样,Python也有抽象类的概念,抽象类是一个特殊的类。其特殊之处在于
只能被继承,不能被实例化;
子类必须完全覆写(实现)其“抽象方法”和“抽象属性”后才能被实例化。
可以有两种实现方式: 利用NotImplementedError实现和利用abctractmethod实现
1.1 NotImplementedError
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Payment (object ): def pay (self ): raise NotImplementedError class ChildPay (Payment ): def pay (self ): print ("TestPay pay" ) def payed (self, money ): print ("Payed: {}" .format (money)) if __name__ == '__main__' : child_pay = ChildPay() child_pay.payed(20 )
1.2 abctractmethod
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 from abc import ABCMeta, abstractmethodclass Payment (metaclass=ABCMeta): def __init__ (self, name ) self.name = name @abstractmethod def pay (self, money ): pass @abstractmethod def get (self, money ): print ("Payment get {}" .format (money)) def total (self, money ): print ("Payment total {}" .format (money)) class ChildPay (Payment ): def pay (self, money ): print ("ChildPay pay {}" .format (money)) def get (self, money ): print ("ChildPay get {}" .format (money)) if __name__ == '__main__' : child_pay = ChildPay("safly" ) child_pay.pay(100 ) child_pay.get(200 ) child_pay.total(400 )
2. 多态概念 向不同的对象发送同一条消息(obj.func(): 是调用了obj的方法func, 又称向obj发送了一条消息func),不同的对象在接受时会产生不同的行为(即不同的处理方法)。
也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的对象可以执行不同的函数。
例: 男生.放松了(), 女生.放松了(),男生是打篮球,女生是看综艺,虽然二者消息一样,但是处理方法不同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 from abc import ABCMeta, abstractmethodclass Base (metaclass=ABCMeta): @abstractmethod def relax (self ): pass class Boy (Base ): def relax (self ): print ("playing basketball" ) class Girl (Base ): def relax (self ): print ("watching TV" ) if __name__ == '__main__' : boy = Boy() girl = Girl() boy.talk() girl.talk()
3. __属性封装 3.1 私有静态属性、私有方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 class Dog (object ): __kind = "private kind" def get_kind (self ): return Dog.__kind def __func (self ): print ("__func" ) def func (self ): self.__func() if __name__ == '__main__' : d = Dog() print (d.get_kind()) print (d.func())
3.2 私有对象属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Dog (object ): def __init__ (self, name, weight ): self.name = name self.__weight = weight def get_weight (self ): return self.__weight if __name__ == '__main__' : room = Dog("doggy" , 5 ) print (room.name) print (room.get_weight())
3.3 私有属性不被继承
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class DogParent (object ): __private = 'PRIVATE' def __init__ (self, name ): self.__name = name def __func (self ): print ("__DogParent func" ) class DogChild (DogParent ): def get_private (self ): return DogParent.__private if __name__ == '__main__' : dog_parent = DogParent("Tom" ) print (dir (dog_parent)) print ("-------------" ) dog_child = DogChild("Tommy" ) print (dir (dog_child))
4. 类中的常见修饰器 主要介绍最常见的装饰器,classmethod, staticmethod和property
4.1 classmethod @classmethod 不需要self参数,但是classmethod方法的第一个参数是需要表示自身类的cls 参数;不管是从类本身调用还是从实例化后的对象调用,都用第一个参数把类传进来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class DogParent (object ): __private = 'PRIVATE' def __init__ (self, name ): self.__name = name def __func (self ): print ("__DogParent func" ) @classmethod def change_name (cls, new_name ): cls.__name = new_name @classmethod def get_name (cls ): return cls.__name def change_name2 (self, new_name ): self.__name = new_name def get_name2 (self ): return self.__name if __name__ == '__main__' : DogParent.change_name(DogParent, "Tom2" ) print (DogParent.get_name(DogParent)) DogParent.change_name2("Tom3" ) print (DogParent.get_name2())
4.2 staticmethod staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用普通的函数一样;这样有一个好处:
有利于我们代码的优雅,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class DogParent (object ): __private = 'PRIVATE' def __init__ (self, name ): self.__name = name def __func (self ): print ("__DogParent func" ) @classmethod def change_name (cls, new_name ): cls.__name = new_name @classmethod def get_name (cls ): return cls.__name def change_name2 (self, new_name ): self.__name = new_name def get_name2 (self ): return self.__name @staticmethod def set_nickname (nickname ): print ("nickname: {}" .format (nickname)) if __name__ == '__main__' : DogParent.set_nickname("tom's nickname~" )
4.3 property @property 把一个方法伪装成一个属性,这个属性的值,是这个方法的返回值;这个方法不能有参数,类不能调用,只能对象调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 class Person (object ): def __init__ (self, name, height, weight ): self.name = name self.height = height self.weight = weight @property def bmi (self ): return self.weight / (self.height ** 2 ) @property def method (self ): print ("method" )
其实,property的作用不仅于此。简单点讲,@property的本质其实就是实现了get,set,delete三种方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Person (object ): def __init__ (self, name, nickname ): self.name = name self.nickname = nickname @property def nickname (self ): print ("nickname: {}" .self.nickname) @property.setter def nickname (self, new_nickname ): self.nickname = new_nickname print ("new nickname: {}" .format (new_nickname)) @property.deleter def nickname (self ): del Person.nickname print ("deleted nickname" ) if __name__ == '__main__' : person = Person("Tom" , 'tommmy' ) person.nickname() person.nickname = 'new_tommmy' del person.nickname
Gitalking ...