1.什么是多态?
多态指同一类型的事物的,不同形态。
2.多态的目的:
多态也称之为多态性,目的是为了在不知道对象具体类型的情况下统一对象🙆调用方法的规范。
先抽象,再继承。
父类:定制一套统一的规范。
子类:遵循父类的统一的的规范。
注意:在python中不会强制限制子类必须遵循父类的规范,所以出现了抽象类。
class Animal: def eat(self): pass def speak(self): passclass Pig(Animal): def eat(self): print('一口没') def speak(self): print('哼哼哼')class Cat(Animal): def eat(self): print('慢慢吃') def speak(self): print('喵喵喵')class Dog(Animal): def eat(self): print('还有吗') def speak(self): print('汪汪汪')animal = Pig()animal1 = Cat()animal2 = Dog()animal.eat()animal1.eat()animal2.eat()animal.speak()animal1.speak()animal2.speak()多态就是为了规范子类的格式让整个程序看起来规范。
二、抽象类
1.什么是抽象类:
在python中内置的abc模块中,有一个抽象类。
2.抽象类的作用:
让子类必须遵循父类的编程规范。
3.如何实现抽象
父类需要继承abc模块中,metaclass=abc.ABCMeta
在父类的方法中,需要装饰上abc.abstractmethod
注意:在python中不推荐使用抽象类
子类必须按照父类的方法编写规范,缺一不可(只要父类中有及格抽象方法,子类就必须要定义几个。
import abcclass Animal(metaclass=abc.ABCMeta): @abc.abstractmethod def eat(self): pass @abc.abstractmethod def speak(self): passclass Pig(Animal): def run(self): pass def eat(self): print('吧唧吧唧') def speak(self): print('还有吗')print(Pig.__dict__)print(Animal.__dict__)pig_obj =Pig()强制要求子类按照父类规范编写不然会报错
三、鸭子类型
1.什么是鸭子类型:
不同的对象,只要长得像鸭子,动作行为像鸭子,那他就是鸭子。
鸭子类型是多态的一种表现形式。
2.为什么要有鸭子类型:
不同的对象,先抽象出相同的类型的方法,给他们定制一套同意的规范。
所有的类,在定义时都按照统一的规范进行编写。
多态的三种表现方式:
继承父类:
耦合度高,程序的可扩展性低
继承抽象类:
耦合度极高,程序的可扩展性极低
鸭子类型:
耦合度低,程序的可扩展性高
注意:在python中,强烈推荐使用鸭子类型。
多态炫技:class Cat: def eat(self): print('刺啦刺啦') def speak(self): print('喵喵喵?')class Dog: def eat(self): print('啊呜啊呜') def speak(self): print('汪呜呜呜~~~')cat = Cat()dog =Dog()def SPEAK(animal): animal.speak()def EAT(animal): animal.eat()SPEAK(dog)EAT(dog)#定义一个长度计算函数str1 = 'ssssssss ssssss'def LEN(obj): return obj.__len__()print(LEN(str1))print(len(str1))
classmethod 与staticmethod
classmethod:
是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为‘类的绑定方法’
staticmethod:
翻译:静态方法
是一个装饰器,在给类内部定义方法中装饰,将类内部的方法变为‘非绑定方法’
对象的绑定方法:
由对象来调用,由谁来调用,会将谁(对象)当作第一个参数传入。
类的绑定方法:
由类来调动,由谁来调动(类),会将谁(类)当作第一个参数传入。
非绑定方法:
可以由对象或类来调用,谁来调用都是一个普通方法(普通函数),方法需要传入几个参数,就得传入几个。
class DB: __date = 'tank is very handsome' def __init__(self, user, pwd, role): self.user = user self.pwd = pwd self.role = role @classmethod def init(cls,user,pwd,role): return cls(user,pwd,role) @classmethod def check_db(cls,user,pwd,role): obj = cls(user,pwd,role) if obj.user == 'tank' and obj.pwd == '123' and obj.role == 'admin': print('检验通过') print(cls.__date) return cls.__dateDB.check_db('tank','123','admin')db_obj = DB('tank','123','admin')print(db_obj.__class__)
uuid用于随机生成一串世界上独一无二的字符串import uuidprint(uuid.uuid4())class Foo: @staticmethod def func(res): print(res)obj = Foo()
isinstance与issubclass
都是python内置的模块
isinstance:判断一个对象是否是李刚一个类的实例。
如果是:True
如果不是:False
passclass Boo: passfoo_obj =Foo()boo_obj =Boo()print(isinstance(foo_obj,Foo))Trueprint(isinstance(boo_obj,Boo))False
issubclass:判断一个类是否是另一个类的子类。
如果是:True
如果不是:False
class Father: passclass Sub(Father): passclass Foo: passprint(issubclass(Sub,Father)) Trueprint(issubclass(Foo,Father)) False
反射
反射指的是通过'字符串'对对象的属性进行操作。
hasatter:通过字符串判断对象的属性或方法是否存在。
class Foo: def __init__(self,x,y): self.x =x self.y = yfoo_obj =Foo(10,20)print(hasattr(foo_obj,'x'))print(hasattr(foo_obj,'y'))print(hasattr(foo_obj,'z'))
getattr:通过字符串获取对象属性或方法
res = getattr(foo_obj,'z','返回值') print(res) 返回值
setatter:通过字符串设置对象属性或方法
setattr(foo_obj,'z','300') print(hasattr(foo_obj,'z')) True
delatter:通过字符串删除对象的属性或方法
delattr(foo_obj,'x') print(hasattr(foo_obj,'x')) False
***均为python内置的方法
栗子: class Filecountrol: def run(self): while True: user_input = input('输入上传(unload)或下载(download)功能').strip() if hasattr(self,user_input):#判断用户输入法的是否存在 func = getattr(self,user_input) #调用用户输入的方法 func() else: print('输入有误') def upload(self): print('文件正在上传') def download(self): print('文件正在下载') file_control_obj = Filecountrol() file_control_obj.run()