zoukankan      html  css  js  c++  java
  • CSIC_716_20191128【多态、绑定与非绑定方法、isinstance与issubclass 】

    多态

    what: 同一个事物有不同的形态。

    多态的目的:在不知道对象具体类型的情况下,统一对象调用方法的规范。(通俗讲,即规定实现同样功能的方法,一定要起同样的名字)。

    多态的表现形式之一就是继承,先抽象再继承。

    多态的父类:定制一套统一的规范,子类中重写该方法,并使用这个方法名。

    python中不会强制限制子类一定要用父类规定的方法名,所以出现了抽象类。

    抽象类

    what:python中内置了abc模块中有抽象类   import abc

    抽象类的作用:让子类必须遵循父类的编写规范。

    抽象类不可以被实例化

    如何实现抽象类:请看代码

    # _*_ coding: gbk _*_
    # @Author: Wonder
    import abc
    
    
    class Father(metaclass=abc.ABCMeta):  # 定义时候要加上metaclass = abc.ABCMeta
    
        @abc.abstractmethod  # 被@abc.abstractmethod装饰的方法,必须在子类中重写,否则会报错。
        def bark(self):
            print('barking......')
    
        @abc.abstractmethod
        def run(self):
            print('running......')
    
        def dance(self):
            print('dancing......')
    
    class Sub(Father):
        def poke(self):
            print('poking......')
        def bark(self): # 重写父类方法,不写会报错
            print('sub barking......')
        def run(self):
            print('sub running......')
    
    test = Sub()
    test.run()
    test.bark()
    test.dance()
    test.poke()
    

     注意点:1.父类名后要加上 classmeta = abc.ABCMeta  2.父类方法上要加上@abc.abstractmethod  3.子类务必遵循父类方法的编写规范进行重写,缺一不可。

    鸭子类型

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

    针对不同的对象,根据特点先抽象出相同的方法,再制定一套统一的编写规范

    在定义类时,类中的方法都按照统一的规范进行编写。

    鸭子类型取消了继承,也取消了抽象类,全凭自觉按照规范编写。这样耦合度就很低。

    鸭子类型可以封装出若干个统一的对外的接口,调用相似事物的相同方法,例如:

    # _*_ coding: gbk _*_
    # @Author: Wonder
    class Dog:
        def bark(self):
            print('dog barking')
    
    
    class Cat:
        def bark(self):
            print('cat barking')
    
    
    class Bird:
        def bark(self):
            print('bird barking')
    
    
    def BARK(animal):  # 封装统一对外接口
        animal.bark()
    
    
    dog = Dog()
    cat = Cat()
    bird = Bird()
    
    BARK(dog)
    BARK(cat)
    BARK(bird)
    

      

    总结:

    多态的三种表现形式:

    >>>继承父类        中度耦合(父类给了规范,但子类可以自由发挥,不用父类的规范)

    >>>继承抽象类      高耦合(父类给了规范,并严格限制子类按照规范重写override)

    >>>鸭子类型          低耦合(没有继承,类中的方法名 全凭自觉 按照规范编写)

    绑定方法classmethod和非绑定方法staticmethod

    classmethod和staticmethod都是pyhton内置的装饰器

    classmethod用来标识 类中的某个方法是类的绑定方法。由类来调用,自动传入方法的第一个参数是类。

    之前学过类中不加修饰的方法是对象的绑定方法,对象调用这些方法时,会将自身作为第一个参数传入方法,当成self。

     (这一条不知道能否这么总结)  如果对象调用类的绑定方法,第一个传入的值是对象所在的类,子类生成的对象可以调用父类和子类的绑定方法。

    # _*_ coding: gbk _*_
    # @Author: Wonder
    '''
    classmethod: 类的绑定方法,只有类可以使用,子类也可以使用。
    '''
    
    
    class Father:
        __key = 'secret'
    
        def __init__(self, name):
            self.name = name
    
        @classmethod
        def call(cls, x, y, z):
            return x + y, y + z
    
        @classmethod
        def info(cls, key):
            if key == 'wonder':
                return cls.__key, cls
            return 'FUCK_NO'
    
    
    class Sub(Father):
        __key = 1990
        pass
    
    
    sub_obj = Sub('name')  # 子类实例化一个对象
    print(sub_obj.__class__)  #查看对象所属的类为 <class '__main__.Sub'>
    res = sub_obj.info('wonder')
    print(res)  # ('secret', <class '__main__.Sub'>) 此处需要注意,cls.__key一定找当前类中的,不可以跨类。
    print(Father.call(1, 2, 3))  # (3, 5)
    print(Sub.call(4, 5, 6))  # (9, 11)
    print(Father.info('won'))  # FUCK_NO
    print(Sub.info('wonder'))  # ('secret', <class '__main__.Sub'>)
    

     非绑定方法

    非绑定方法,相当于在类中定义了一个函数,没有自动传参功能,类和对象都可以使用。

    # _*_ coding: gbk _*_
    # @Author: Wonder
    class Foo:
        @staticmethod
        def rap(name):
            print(f'您的狗名为{name}')
    
    foo_obj = Foo()
    foo_obj.rap('阿黄')
    Foo.rap('阿黑')
    

      

    isinstance 判断一个对象是否是一个类的实例

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

    class A:
        pass
    
    
    class B(A):
        pass
    
    
    class C:
        pass
    
    
    print(isinstance(A(), A))  # True
    print(isinstance(B(), A))  # True
    print(isinstance(A(), B))  # False
    print(isinstance(B(), B))  # True
    
    print(issubclass(C, A))  # False
    print(issubclass(B, A))  # True
    

      

    补充

    uuid模块

    import uuid
    print(uuid.uuid4())  # a64b11d5-a3f1-46a2-b752-08fc8949457a
    

    uuid.uuid4( )  uuid4是一个纯随机数,与机器无关, 相重的几率很小。通常生成用户id用这个。

  • 相关阅读:
    MySQL同步故障:" Slave_SQL_Running:No" 两种解决办法
    mysql运维-slave_skip_errors
    linux 的mysql 主从备份
    linux 查看和设置主机名
    mysql连接数
    红帽6.9搭建yum源的2种方式(HTTP和本地)
    linux 重启服务器命令
    Linux开机启动顺序启动顺序及配置开机启动
    在Windows Server 2012的Task Scheduler里面配置自动发送邮件
    "Cannot find one of more components. Please reinstall the application"--安装VS2013之后不能正常打开的处理办法
  • 原文地址:https://www.cnblogs.com/csic716/p/11950426.html
Copyright © 2011-2022 走看看