zoukankan      html  css  js  c++  java
  • 多态与反射

    一、多态

    1.什么是多态

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

    例如,猪,狗,猫都是动物,都有叫声这个技能,但是狗是“汪汪汪”,猪是“哼哼哼”,猫是“喵喵喵”。它们之间的叫声不同,也就有了不同的区分

     1 # 动物类
     2 class Animal:
     3 
     4     # 方法 叫
     5     def speak(self):
     6         pass
     7 # 猪类
     8 class Pig(Animal):
     9 
    10     def speak(self):
    11         print('哼哼哼...')
    12 
    13 
    14 # 猫类
    15 class Cat(Animal):
    16 
    17     def speak(self):
    18         print('喵喵喵...')
    19 
    20 
    21 # 狗类
    22 class Dog(Animal):
    23 
    24     def speak(self):
    25         print('汪汪汪...')
    26 
    27 
    28 animal1 = Dog()
    29 animal2 = Pig()
    30 animal3 = Cat()
    31 
    32 # 让动物们叫起来
    33 animal1.speak()
    34 animal2.speak()
    35 animal3.speak()

    2.多态作用

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

    多态的表现 “形式之一” 就是继承:
    - 先抽象,再继承

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

    二、抽象类

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

    1.什么是抽象类

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

    2.抽象类的作用

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

    3.怎么实现抽象类

    - 父类需要继承abc模块中,metaclass=abc.ABCMeta
    - 在父类的方法中,需要装饰上 abc.abstractmethod

    注意: 在python中不推荐使用抽象类。

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

     1 import abc
     2 
     3 class Animal(metaclass= abc.ABCMeta):
     4     @abc.abstractmethod
     5     def eat(self):
     6         pass
     7 
     8     @abc.abstractmethod
     9     def speak(self):
    10         pass
    11 
    12 
    13 class Dog(Animal):
    14     def eat(self):
    15         print('')
    16 
    17     def speak(self):
    18         print('汪汪汪')
    19 
    20 
    21 dog_obj = Dog()
    22 dog_obj.speak()

    三、鸭子类型

    1.什么是鸭子类型

    不同的对象,只要长得像鸭子,动作行为像鸭子,那它就是鸭子。鸭子类型是多态的一种表现形式。

    2.鸭子类型作用

    不同对象,先抽象出相同类型的方法,给他们定制一套统一的规范。所有的类,在定义时都按照统一的规范进行编写。降低程序的耦合度。提升了程序的可扩展性

     1 # 猪类
     2 class Pig:
     3     def eat(self):
     4         print('bia唧...')
     5 
     6     def speak(self):
     7         print('哼哼哼...')
     8 
     9 
    10 # 猫类
    11 class Cat:
    12     def eat(self):
    13         print('咬ji 咬ji....')
    14 
    15     def speak(self):
    16         print('喵喵喵...')
    17 
    18 
    19 # 狗类
    20 class Dog:
    21     def eat(self):
    22         print('舔 ji 舔ji...')
    23 
    24     def speak(self):
    25         print('汪汪汪...')
    26 
    27 
    28 def animal_speak(animal):
    29     animal.speak()
    30 
    31 
    32 dog = Dog()
    33 pig = Pig()
    34 cat = Cat()
    35 animal_speak(dog)
    36 animal_speak(pig)
    37 animal_speak(cat)
    1 # 自定义统计长度
    2 def my_len(obj):
    3     return obj.__len__()
    4 
    5 str1 = '123456789'
    6 list1 = [1, 2, 3, 4, 5]
    7 print(my_len(str1))
    8 print(my_len(list1))

    小结:

    - 多态的三种表现形式:
      - 继承父类 :
        - 耦合度高,程序的可扩展性低

      - 继承抽象类:
        - 耦合度极高,程序的可扩展性极低

      - 鸭子类型:
        - 耦合度低,程序的可扩展性高

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

    四、classmethod 和 staticmethod

    classmethod与staticmethod都是python解释器内置的装饰器

    1.classmethod

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

     1 # classmethod
     2 class DB:
     3     __data = 'abc'
     4     def __init__(self, user, pwd):
     5         self.user = user
     6         self.pwd = pwd
     7 
     8 
     9     @classmethod
    10     def check(cls, user, pwd):
    11         obj = cls(user, pwd)
    12         if obj.user == 'aaa' and obj.pwd == '123':
    13             print('验证通过...')
    14             print(cls.__data)
    15 
    16 DB.check('aaa', '123')

    2.staticmethod

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

     1 # staticmethod
     2 class Foo:
     3     @staticmethod
     4     def print_info(self):
     5         print(self)
     6 
     7 obj = Foo()
     8 
     9 # 对象调用非绑定方法
    10 obj.print_info(123)
    11 
    12 # 类调用非绑定方法
    13 Foo.print_info(1234)

    小结

    - 对象的绑定方法:
      - 由对象来调用,由谁来调用,会将谁(对象)当做第一个参数传入。

    - 类的绑定方法:
      - 由类来调用,由谁来调用,会将谁(类)当做第一个参数传入。

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

    五、isinstance 和 issubclass

    1.isinstance

    判断一个对象是否是另一个类的实例。
    - 如果是: True,且这个对象也是该类的父类的一个实例
    - 如果不是: False

     1 class Foo:
     2     pass
     3 
     4 class Sub(Foo):
     5     pass
     6 
     7 class Oth:
     8     pass
     9 
    10 o_obj = Oth()
    11 s_obj = Sub()
    12 
    13 # isinstance
    14 print(isinstance(s_obj, Sub))   # True
    15 print(isinstance(s_obj, Foo))   # True
    16 print(isinstance(s_obj, Oth))   # False

    2.issubclass

    判断一个类是否是另一个类的子类。
    - 如果是: True
    - 如果不是: False

     1 class Foo:
     2     pass
     3 
     4 class Sub(Foo):
     5     pass
     6 
     7 class Oth:
     8     pass
     9 
    10 o_obj = Oth()
    11 s_obj = Sub()
    12 
    13 # issubclass
    14 print(issubclass(Sub, Foo))     # True
    15 print(issubclass(Sub, Oth))     # False

    六、反射

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

    1.hasattr

    通过 “字符串” 判断对象的属性或方法是否存在。

    2.getattr

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

    3.setattr

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

    4.delattr

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

     1 class Foo:
     2     def __init__(self, x, y):
     3         self.x = x
     4         self.y = y
     5 
     6 obj = Foo(10, 20)
     7 print(obj.__dict__)
     8 
     9 # hasattr
    10 print(hasattr(obj, 'x'))    # True
    11 print(hasattr(obj, 'z'))    # Flase
    12 
    13 # getattr
    14 print(getattr(obj, 'x'))    # 10
    15 # 若属性不存在,则返回默认值
    16 print(getattr(obj, 'z', '不存在返回值'))    # 不存在返回值
    17 
    18 # setattr
    19 setattr(obj, 'x', 30)
    20 print(obj.__dict__)     # {'x': 30, 'y': 20}
    21 setattr(obj, 'z', '123')
    22 print(obj.__dict__)     # {'x': 30, 'y': 20, 'z': '123'}
    23 
    24 # delattr
    25 delattr(obj, 'z')
    26 print(obj.__dict__)     # {'x': 30, 'y': 20}
     1 # 反射应用
     2 class FileControl:
     3 
     4     def run(self):
     5         while True:
     6             cmd = input('输入要进行功能(upload ---> 上传   download ---> 下载):').strip()
     7             if hasattr(self, cmd):
     8                 func = getattr(self, cmd)
     9                 func()
    10             else:
    11                 print('输入不合法')
    12 
    13     @staticmethod
    14     def upload():
    15         print('上传数据中...')
    16 
    17     @staticmethod
    18     def download():
    19         print('下载数据中...')
    20 
    21 
    22 obj = FileControl()
    23 obj.run()
  • 相关阅读:
    第二阶段个人冲刺总结01
    软件工程学习进度表13
    软件工程学习进度表12
    个人博客(09)
    个人博客(07)
    个人博客(08)
    poj1562 DFS入门
    poj3278 BFS入门
    数组单步运算
    十天冲刺
  • 原文地址:https://www.cnblogs.com/hexianshen/p/11950425.html
Copyright © 2011-2022 走看看