多态、抽象、鸭子、绑定与非绑定、反射与内置方法

一、多态

1、什么是多态?

指的是同一种类型的事物有多种形态。

2、多态的目的:

多态也称为多态性,目的是为了在不知道对象具体类型的情况下,统一对象调用方法的规范。比如:名字。

多态的编写形式之一就是继承

        先抽象,再继承

父类:定制一套统一的规范

子类:遵循父类的统一规范

注意:在python中不会强制限制子类必须遵循父类的规范,所以出现了抽象类。

3、多态的三种表现形式:

     继承父类 ****

                耦合度高,程序的可扩展性低

     继承抽象类 ***

                耦合度极高,程序的可扩展性极低

     鸭子类型: *****

               耦合度低,程序的可扩展性高

注意: 在python中,强烈推荐使用鸭子类型。

# # 动物类
# class Animal:
#
#     # 方法 吃
#     def eat(self):
#         pass
#
#     # 方法 叫
#     def speak(self):
#         pass
# # 猪类
# class Pig(Animal):
#     def eat(self):
#         print('bia唧...')
#
#     def speak(self):
#         print('哼哼哼...')
#
#
# # 猫类
# class Cat(Animal):
#     def eat(self):
#         print('咬ji 咬ji....')
#
#     def speak(self):
#         print('喵喵喵...')
#
#
# # 狗类
# class Dog(Animal):
#     def eat(self):
#         print('舔 ji 舔ji...')
#
#     def speak(self):
#         print('汪汪汪...')
#
#
# animal1 = Dog()
# animal2 = Pig()
# animal3 = Cat()
#
# # 让动物们叫起来
# animal1.speak()
# animal2.speak()
# animal3.speak()

 

二、抽象类

1、什么是抽象类?

在python内置的abc模块中,有一个抽象类。

2.作用:

让子类必须遵循父类的编写规范。

3、如何实现:

父类需要继承abc模块中,metaclass=abc.ABCMeta

在父类的方法中,需要装饰上abc.abstracmethod

注意:在python中不推荐使用抽象类。子类必须按照父类的方法编写规范,缺一不可。(只要父类中有几个抽象方法,子类就必须要定义几个)

 

import abc
class Animal(metaclass=abc.ABCMeta):

    @abc.abstractmethod
    def eat(self):
        pass
    @abc.abstractmethod
    def speak(self):
        pass

class Cat(Animal):
    def eat(self):
        print('bajibaji')

    def speak(self):
        print('miaomiao')

class Dog(Animal):
    def eat(self):
        print('tian')

    def speak(self):
        print('wang')

    def buck(self):
        print('wang')

dog = Dog()
cat = Cat()

 

三、鸭子

1.什么是鸭子类型?

不同的对象,只要长得像鸭子,动作行为像鸭子,那它就是鸭子!

鸭子类型是多态的一种表现形式。

2.为什么要有鸭子类型?

不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范。 所有的类,在定义时都按照统一的规范进行编写。

 3、优缺点:

优点:耦合度低,可扩展性高

缺点:容易造成代码冗余

注意: 在python中,强烈推荐使用鸭子类型。

# 猪类
class Pig:
    def eat(self):
        print('bia唧...')

    def speak(self):
        print('哼哼哼...')


# 猫类
class Cat:
    def eat(self):
        print('咬ji 咬ji....')

    def speak(self):
        print('喵喵喵...')


# 狗类
class Dog:
    def eat(self):
        print('舔 ji 舔ji...')

    def speak(self):
        print('汪汪汪...')

 

四、绑定与非绑定

绑定 classmethod:

是一个python内置的装饰器,给在类内部方法中装饰,将类内部的方法变为类的绑定方法。

类的绑定方法:

由类来调用,由谁来调用,会将谁(类)当作第一个参数传入。

 

class DB:
    __data = '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):  # cls --》指的是类
    #     # 在类方法内部调用类产生一个实例 ---》 对象
    #     return cls(user, pwd, role)

    # 查看数据方法
    @classmethod
    def check_db(cls, user, pwd, role):  # cls --》指的是类

        # 在类方法内部调用类产生一个实例 ---》 对象
        obj = cls(user, pwd, role)

        # 1.查看数据前,必须要通过校验
        if obj.user == 'tank' and obj.pwd == '123' and obj.role == 'admin':
            print('检验通过..')
            print(cls.__data)


DB.check_db('tank', '123', 'admin')

# db_obj = DB('tank', '123', 'admin')
# db_obj.check_db()
# __class__: 查看当前对象的类
# print(db_obj.__class__)

 

非绑定方法staticmethod:

可以由对象或类来调用,谁来调用都是一个普通方法(普通函数),方法需要传入几个参数,就得传入几个。

class Foo:
    @staticmethod
    def func(self):
        print(self)

obj = Foo()
# obj.func()  #此时已经是非绑定,self不再是对象,self变成一个参数,必须传参
#TypeError: func() missing 1 required positional argument: 'self'
obj.func(123)  #123  此时对象调用非绑定方法
Foo.func(123)   #123  此时类调用非绑定方法

 

 

五、反射与内置方法

1、内置方法:

isinstance 与issubclass是python内置的模块。

isinstance:判断一个对象是否是另一个类的实例。  结果:True or False

issunclass:判断一个类是否是另一个类的子类。  结果:True or False

 

isinstance:

class Foo:
    pass

class Bar:
    pass

obj = Foo()
print(isinstance(obj, Foo))  #True
print(isinstance(obj, Bar))  #False

issunclass:

class Foo:
    pass

class Bar(Foo):
    pass

class Sub:
    pass

# print(issubclass(Bar, Foo))  #True
print(issubclass(Sub, Foo))  #False

 

2、反射

反射:指的是通过 字符串 对 对象的属性 进行操作。

hasattr: 通过 字符串 判断 对象的属性或方法是否存在。 结果:True or False

getattr:  通过 字符串 获取 对象的属性或方法。

setattr:  通过 字符串 设置 对象的属性或方法。

delattr:  通过 字符串 删除 对象的属性或方法。

class Foo:
    def __init__(self,x, y):
        self.x = x
        self.y = y

obj = Foo(10,20)
#hasattr
print(hasattr(obj, 'x'))  #True
print(hasattr(obj, 'z'))  #False


#getattr
print(getattr(obj, 'x'))  #10
print(getattr(obj, 'z'))  #AttributeError: 'Foo' object has no attribute 'z'
print(getattr(obj, 'z','设置默认返回值可以不报错'))  #设置默认返回值可以不报错


#setsttr
# 为obj设置一个属性z,值为30
setattr(obj, 'z', 30)
print(getattr(obj,'z')) #30
#修改原x的值
setattr(obj, 'x', 30)
print(getattr(obj,'x')) #30


#delsttr
delattr(obj,'z')
print(hasattr(obj, 'z'))  #False

反射应用:

class FileControl:

    def run(self):
        while True:

            ## 让用户输入上传或下载功能的命令:
            uinput = input('请输入上传 upload 或 下载 download 功能:').strip()

            # 通过用户输入的字符串判断方法是否存在,然后调用相应的方法
            if hasattr(self, uinput):
                func = getattr(self, uinput)
                func()
            else:
                print('输入有误')

    def upload(self):
        print('文件正在上传')

    def download(self):
        print('文件正在下载')

file_obj = FileControl()
file_obj.run(

 

posted @ 2019-11-28 16:18  小猪皮蛋  阅读(153)  评论(0编辑  收藏  举报