多态与鸭子和反射
1.什么是多态?
多态指同一类型的事物的,不同形态。
2.多态的目的:
多态也称之为多态性,目的是为了在不知道对象具体类型的情况下统一对象🙆调用方法的规范。
先抽象,再继承。
父类:定制一套统一的规范。
子类:遵循父类的统一的的规范。
注意:在python中不会强制限制子类必须遵循父类的规范,所以出现了抽象类。
class Animal:
def eat(self):
pass
def speak(self):
pass
class 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 abc
class Animal(metaclass=abc.ABCMeta):
abstractmethod .
def eat(self):
pass
abstractmethod .
def speak(self):
pass
class 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
def init(cls,user,pwd,role):
return cls(user,pwd,role)
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.__date
DB.check_db('tank','123','admin')
db_obj = DB('tank','123','admin')
print(db_obj.__class__)
uuid用于随机生成一串世界上独一无二的字符串
import uuid
print(uuid.uuid4())
class Foo:
def func(res):
print(res)
obj = Foo()
isinstance与issubclass
都是python内置的模块
isinstance:判断一个对象是否是李刚一个类的实例。
如果是:True
如果不是:False
pass
class Boo:
pass
foo_obj =Foo()
boo_obj =Boo()
print(isinstance(foo_obj,Foo))True
print(isinstance(boo_obj,Boo))False
issubclass:判断一个类是否是另一个类的子类。
如果是:True
如果不是:False
class Father:
pass
class Sub(Father):
pass
class Foo:
pass
print(issubclass(Sub,Father)) True
print(issubclass(Foo,Father)) False
反射
反射指的是通过'字符串'对对象的属性进行操作。
hasatter:通过字符串判断对象的属性或方法是否存在。
class Foo:
def __init__(self,x,y):
self.x =x
self.y = y
foo_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()
作者:刘浩
出处:http://home.cnblogs.com/u/cyfdtz/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。