多态与鸭子和反射

 

一、多态

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):
   @abc.abstractmethod
   def eat(self):
       pass
   @abc.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

   @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.__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:
   @staticmethod
   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()

 

posted @ 2019-12-04 18:42  薛定谔的量子猫  阅读(134)  评论(0编辑  收藏  举报