zoukankan      html  css  js  c++  java
  • 多态 抽象类 鸭子类型 classmethod 和 staticmethod isinstance 和 issubclass 反射

    1.多态

    1.什么是多态?

    ​ -多态指的同一种类型的事物的不同形态。

    2.多态的目的:

    ​ -'多态'也成为'多态性',目的是为了再不知道对象的具体类型情况下,统一对象的调用方法的规范(比如写字)

    ​ -多态的表现形式之一就是 继承

    ​ -先抽象,在继承

    ​ 父类:定制一套统一的规范,(比如:方法统一)

    ​ 子类:遵循父类的统一的规范。(比如子类遵循父类方法名统一的)

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

    #动物类
    class Animal:######这个就是统一的规范
        #方法吃
        def eat(self):
            pass
        #方法 叫
        def speak(self):
            pass
    
        #猪类
    class Pig(Animal):
        def eat(self):####这个就是根据父类的规范来操作的
            print('baiji...')
    
        def speak(self):
            print('哼哼哼...')
    
    #猫
    class Cat(Animal):
        def eat(self):
            print('yaojiyaoji')
    
        def speak(self):
            print('喵喵...')
    
    #狗类
    class Dog(Animal):
        def eat(self):
            print('tianjitianji')
    
        def speak(self):
            print('汪汪...')
    
    animal1 = Dog()
    animal2 = Cat()
    animal3 = Pig()
    animal1.eat()
    

    下面这个是一个反面的教材,这个就是个错误的

    class Animal:######这个就是统一的规范
        #方法吃
        def eat(self):
            pass
        #方法 叫
        def speak(self):
            pass
    
        #猪类
    class Pig(Animal):
        def eat(self):
            print('baiji...')
    
        def speak(self):
            print('哼哼哼...')
    
    #猫
    class Cat(Animal):
        def chi(self):######和父类的规范要求不一样
            print('yaojiyaoji')
    
        def tell(self):
            print('喵喵...')
    
    #狗类
    class Dog(Animal):
        def chi_1(self):######和父类的规范要求不一样
            print('tianjitianji')
    
        def jiao(self):
            print('汪汪...')
    

    2.抽象类

    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('biajiji')
    
        def speak(self):
            print('哼哼...')
    
    print(Pig.__dict__)
    print(Animal.__dict__)
    pig_obj = Pig()
    
    

    3.鸭子类型

    1.什么是鸭子类型?

    ​ -不同的对象,只要长的像鸭子,动作行为像鸭子,那他就是鸭子

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

    2.为什么有鸭子类型?

    ​ -不同的对象,先抽象出相同类型的方法,给他们制定一套统一的规范。

    ​ -所有的类,在定义时都按照统一的规范进行编写

    ​ -在定义之前,先定义一套鸭子类型规范

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

    ​ 1.继承父类

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

    ​ 2.继承抽象类

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

    ​ 3.鸭子类型‘

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

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

    #猪类
    class Pig:
        def eat(self):
            print('biajiji')
    
        def speak(self):
            print('哼哼...')
    
    #猫类
    class Cat:
        def eat(self):
            print('yaojiyaoji...')
    
        def speak(self):
            print('miaomiao...')
    
    #狗类
    class Dog:
        def eat(self):
            print('tianjitianji...')
    
        def speak(self):
            print('汪汪...')
    
        - 鸭子类型规范::
                - eat_fish:
                - swimming:
    
            - class Duck1:####这个就是鸭子类型 
                def eat_fish(self):
                    pass
    
                def swimming(self):
                    pass
    
            - class HCY:
                def eat_fish(self):
                    pass
    
                def swimming(self):
                    pass
    

    以上的是鸭子类型,这个类型跟继承父类,比没有父类的规范要求

    跟抽象类的比,没有父类的导入模块的要求

    多态的炫技
    #猪类
    class Pig:
        def eat(self):
            print('biajiji...')
    
        def speak(self):
            print('hengheng...')
    
    #猫类
    class Cat:
        def eat(self):
            print('hengheng...')
    
        def speak(self):
            print('miaomiao...')
    
    #狗类
    class Dog:
        def eat(self):
            print('tianjitianji')
    
        def speak(self):
            print('wangwang...')
    
    dog = Dog()
    pig = Pig()
    cat = Cat()
    #多态之炫技
    def SPEAK(animal):
        animal.speak()
    
    SPEAK(dog)
    SPEAK(cat)
    >>>>>>>>>>>>>>>>>
    wangwang...
    miaomiao...
    
    
    str1 = 'tank is very handsome!'
    def Len(obj):
        return obj.__len__()
    print(Len(str1))###具体的一个字符串是一个对象,对象自己的内置方法
    
    print(len(str1))
    >>>>>>>>>>>>>>>>>
    22
    22
    

    4.classmethod 和staticmethod

    -都是python解释器内置的装饰器

    classmethod:

    ​ -是一个装饰器,给在类内部定义方法中装饰,将类内部方法变为“类的绑定方法”

    staticmethod

    ​ -翻译:静态方法

    ​ -是一个装饰器,给在类内部定义方法中装饰,将类内部的方法变为“非绑定方法”

    对象的绑定方法:

    ​ -由对象来调用,由谁来调用,会将对象当作第一个参数传入;

    类的绑定方法:

    ​ -由类来调用,由谁来调用,会将类作为第一个参数来传入;

    非绑定方法:

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

    1.classmethod

    #校验查看隐私的信息
    class DB:
        __data = 'tank is very handsome!'
        def __init__(self,user,pwd,role):
            self.user = user
            self.pwd = pwd
            self.role = role
    
    
        def check_db(self):
    
            if self.user == 'tank' and self.pwd == '123' and self.role == 'admin':
                print('检验通过')
                print(self.__class__.__data)
                return self.__class__.__data
    ##__class__ 查看当前对象的类
    
    db_obj = DB('tank','123','admin')
    db_obj.check_db()
    >>>>>>>>>>>>>>>>>>>
    检验通过
    tank is very handsome!
    
    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):
            obj = cls(user,pwd,role)#这个是类的实例化产生一个对象
    
        #查看数据前,必须通过校验
            if obj.user == 'tank'and obj.pwd == '123'and obj.role == 'admin':
                print('校验通过')
                print(cls.__data)
                return cls.__data
    
    DB.check_db('tank','123','admin')
    >>>>>>>>>>>>>>>>>
    校验通过
    tank is very handsome!
    

    import uuid :用于产生随机字符串的模块

    ​ -具体是由时间戳及某种算法组合而成,会产生一串世界上独一无二字符串

    ​ -print(uuid.uuid4()) #####产生的是一串字符串

    2.staticmethod

    class Foo:
    
        @staticmethod #####变成一种非绑定的方法
        def func(res):
            print(res)
    
    obj = Foo()
    #对象调用非绑定方法
    obj.func(123)
    ###结果是123
    Foo.func(1234)
    >>>>>>>>
    1234
    
    
    如果没有@staticmethod
    class Foo:
    
       
        def func(res):
            print(res)
            
     Foo.func(1234)#####类调用的就是一个普通的函数 res需要一个实参
    >>>>>>>>>>>>>
    1234
    
    class Foo:
    
         
        def func(self,res):
            print(res)
    
    obj = Foo()
    #对象调用非绑定方法
    obj.func(123)   ####对象的调用的是把自身作为第一个值传入,需要2个参数self,res
    >>>>>>>>>>>>
    123
    

    5.isinstance issubclass

    -这两个都是python的内置模块

    -isinstance :判断一个对象是否是另一个类的实例。

    ​ -如果是:True

    ​ -如果不是:False

    -issubclass:判断一个类是否是另一个类的子类

    ​ -如果是:True

    ​ -如果不是:False

    class Foo:
        pass
    
    class Goo:
        pass
    goo_obj = Goo()
    
    foo_obj = Foo()
    print(isinstance(foo_obj,Foo))
    print(isinstance(goo_obj,Foo))
    >>>>>>>>>>>>>>>>
    True
    False
    
    class Foo:
        pass
    class Goo(Foo):
        pass
    class Hoo:
        pass
    
    print(issubclass(Goo,Foo))
    print(issubclass(Hoo,Foo))
    >>>>>>>>>>>>>>>
    True
    False
    

    6.反射

    -反射指的是通过’字符串''对对象的属性进行操作

    ​ -hasattr :通过'字符串'判断对象的属性或方法是否存在

    ​ -getattr:通过'字符串'获取对象的属性或者方法

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

    ​ -delattr: 通过'字符串'删除对象的属性或者方法

    注意:反射的4个方法是python的内置的

    ###hasattr
    class Foo:
        def __init__(self,x,y):
            self.x = x
            self.y = y
    foo_obj = Foo(10,20)
    #hasattr
    print(hasattr(foo_obj,'x'))
    print(hasattr(foo_obj,'y'))
    print(hasattr(foo_obj,'z'))
    >>>>>>>>>>>>>>>>>>>>>>>
    True
    True
    False
    
    ###getattr
    class Foo:
        def __init__(self,x,y):
            self.x = x
            self.y = y
    foo_obj = Foo(10,20)
    
    res = getattr(foo_obj,'x')
    print(res)
    res1 = getattr(foo_obj,'z','默认值')###z不存在,可以在后面加一个默认值,字符串类型的
    print(res1)
    >>>>>>>>>>>>>>
    10
    123
    
    ####setattr
    class Foo:
        def __init__(self,x,y):
            self.x = x
            self.y = y
    foo_obj = Foo(10,20)
    setattr(foo_obj,'z',30)  #这个setattr的有过这个字符串有值 再设置就会更新,如果是没有值的  会新创建一个属性
    print(hasattr(foo_obj,'z'))
    >>>>>>>>>>>>>>>>>>>>>>
    True
    
    ###delattr
    class Foo:
        def __init__(self,x,y):
            self.x = x
            self.y = y
    foo_obj = Foo(10,20)
    delattr(foo_obj,'x')
    print(hasattr(foo_obj,'x'))
    >>>>>>>>>>>>>>
    False
    
    
    
    
    ##反射的应用
    #反射的应用
    class FileControl:
        def run(self):
            while True:
                user_input = input('请输入upload 或者download:').strip()
                if hasattr(self,user_input):
                    func = getattr(self,user_input)
                    func()
                    break
                else:
                    print('输入有误')
    
        def upload(self):
            print('文件正在上传...')
    
        def download(self):
            print('文件正在下载...')
    filecontrol_obj = FileControl()
    filecontrol_obj.run()
    >>>>>>>>>>>>>>>>>>
    请输入upload 或者download:sffjf
    输入有误
    请输入upload 或者download:dfgf
    输入有误
    请输入upload 或者download:a1223
    输入有误
    请输入upload 或者download:download
    文件正在下载...
    Process finished with exit code 0
    
  • 相关阅读:
    __init__.py文件的作用
    is is not == !=之间的区别
    使用七牛上传头像
    flask的request的用法
    Mac各个文件夹表示的意思
    sqlalchemy的基本的使用
    将Cygwin Emacs设为Windows explorer默认打开程序
    使用Stardict命令行版本sdcv
    坚持使用GNU/Linux
    在Windows上创建同样的Linux操作环境
  • 原文地址:https://www.cnblogs.com/bs2019/p/11958136.html
Copyright © 2011-2022 走看看