多态与鸭子和反射

一个人想着一个人 提交于 2019-12-06 12:46:48

 

一、多态

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 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):    pass​class 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()

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!