type 和 class
type 一个对象的时候,结果总是这个对象所属的类
那么类是什么类型?
所有的类的类型都是type
type 是所有类型的鼻祖
type( 类名 ) = type
类也是被创造出来的 可以由python解释器创造 也可以由特殊的方法创造
常规创造的类 总是有几个特性
能够实例化 能有属性 能有方法一些有特殊需求的类
所有的用class常规语法创造出来的类 都是type类型
元类
能帮你创造出不同寻常的类
可以实现特殊的需求 例如 不能实例化 只能有一个实例
抽象类
类的约束
不同的类,要使用的方法相同,但如果有一个类的方法名字写错了 调用方法的时候会很麻烦
class Wechatpay: def __init__(self,name,money): self.name = name self.money = money def pay(self): print('%s通过微信支付了%s元'%(self.name,self.money)) class Alipay: def __init__(self,name,money): self.name = name self.money = money def pay(self): print('%s通过支付宝支付了%s元'%(self.name,self.money)) class ApplePay: def __init__(self,name,money): self.name = name self.money = money def fuqian(self): print('%s通过apple pay支付了%s元' % (self.name, self.money)) # 归一化设计 def pay(person): person.pay() wcp = Wechatpay('alex',2000000) pay(wcp) ali = Alipay('alex',2000000) app = ApplePay('alex',2000000) pay(app) 代码的规范没有建立起来
所以此时我们要用到对类的约束,对类的约束有两种:
1. 提取⽗类. 然后在⽗类中定义好⽅法. 在这个⽅法中什么都不⽤⼲. 就抛⼀个异常就可以了. 这样所有的⼦类都必须重写这个⽅法. 否则. 访问的时候就会报错.
2. 使⽤元类来描述⽗类. 在元类中给出⼀个抽象⽅法. 这样⼦类就不得不给出抽象⽅法的具体实现. 也可以起到约束的效果.
先用第一种方式解决:
class Payment: """ 此类什么都不做,就是制定一个标准,谁继承我,必须定义我里面的方法。 """ def pay(self,money): raise Exception("你没有实现pay方法") class QQpay(Payment): def pay(self,money): print('使用qq支付%s元' % money) class Alipay(Payment): def pay(self,money): print('使用阿里支付%s元' % money) class Wechatpay(Payment): def fuqian(self,money): print('使用微信支付%s元' % money) def pay(obj,money): obj.pay(money) a = Alipay() b = QQpay() c = Wechatpay() pay(a,100) pay(b,200) pay(c,300)
第二种方法:
引入抽象类的概念处理
from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): # 抽象类 @abstractmethod # 如果我必须要实现pay方法,那么我需要给pay加一个装饰器 def pay(self): pass # 创建的这个pay并没有内容, # 之所以写一个pay是为了提醒所有子类你一定要实现一个pay方法 # 如果子类没有使用这两个方法,就会报错 @abstractmethod def back(self): pass class Wechatpay(Payment): def __init__(self,name,money): self.name = name self.money = money def pay(self): print('%s通过微信支付了%s元'%(self.name,self.money)) def back(self): print('退款') class Alipay(Payment): def __init__(self,name,money): self.name = name self.money = money def pay(self): print('%s通过支付宝支付了%s元'%(self.name,self.money)) def back(self): print('退款') class ApplePay(Payment): def __init__(self, name, money): self.name = name self.money = money def pay(self): print('%s通过apple pay支付了%s元' % (self.name, self.money)) def back(self): print('退款') w = Wechatpay('alex',200) w.pay()
from abc import ABCMeta,abstractmethod class Payment(metaclass=ABCMeta): # 抽象类 接口类 规范和约束 metaclass指定的是一个元类 @abstractmethod def pay(self):pass # 抽象方法 class Alipay(Payment): def pay(self,money): print('使用支付宝支付了%s元'%money) class QQpay(Payment): def pay(self,money): print('使用qq支付了%s元'%money) class Wechatpay(Payment): # def pay(self,money): # print('使用微信支付了%s元'%money) def recharge(self):pass def pay(a,money): a.pay(money) a = Alipay() a.pay(100) pay(a,100) # 归一化设计:不管是哪一个类的对象,都调用同一个函数去完成相似的功能 q = QQpay() q.pay(100) pay(q,100) w = Wechatpay() pay(w,100) # 到用的时候才会报错 # 抽象类和接口类做的事情 :建立规范 # 制定一个类的metaclass是ABCMeta, # 那么这个类就变成了一个抽象类(接口类) # 这个类的主要功能就是建立一个规范
总结
约束. 其实就是⽗类对⼦类进⾏约束. ⼦类必须要写xxx⽅法. 在python中约束的⽅式和⽅法有两种:
1. 使⽤抽象类和抽象⽅法, 由于该⽅案来源是java和c#. 所以使⽤频率还是很少的
2. 使⽤⼈为抛出异常的⽅案. 并且尽量抛出的是NotImplementError. 这样比较专业, ⽽且错误比较明确.(推荐)
接口类
java中没有多继承的类
所以抽象类 只能是所有的子类只有一个规范
于是发明了接口 接口可以多继承
在python中没有接口专用语法
只是通过类的多继承 模仿接口效果
抽象类是单继承的规范 接口类是多继承的规范
from abc import ABCMeta,abstractmethod class NormalAnnimal(metaclass=ABCMeta): @abstractmethod def eat(self):pass @abstractmethod def drink(self):pass class FlyAnimal(metaclass=ABCMeta): @abstractmethod def fly(self):pass class SwimAnimal(metaclass=ABCMeta): @abstractmethod def swim(self):pass class WalkAnimal(metaclass=ABCMeta): @abstractmethod def walk(self):pass class Frog(NormalAnnimal,SwimAnimal,WalkAnimal): def eat(self): pass class Tiger(NormalAnnimal,SwimAnimal,WalkAnimal):pass class Swan(NormalAnnimal,FlyAnimal,SwimAnimal,WalkAnimal):pass class Parrot(NormalAnnimal,FlyAnimal,WalkAnimal): def talk(self): pass