彩虹然

rainbow-ran

Python3.7之多态与多态性

一、多态

Python中多态是指一类事物有多种形态。比如动物有多种形态,人,狗,猫,等等。文件有多种形态:文本文件,可执行文件。

二、多态性

1.什么是多态性?

多态性是指在不考虑实例类型的情况下使用实例,多态性分为静态多态性和动态多态性

静态多态性:如任何类型都可以用运算符+进行运算

动态多态性:如下

import abc


class Animals(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def talk(self):
        pass


class People(Animals):
    def talk(self):
        print('People is talking')


class Cat(Animals):
    def talk(self):
        print('Cat is miaomiao')


class Dog(Animals):
    def talk(self):
        print('Dog is wangwang')


cat1 = Cat()
dog1 = Dog()
peo1 = People()
# peo、dog、pig都是动物,只要是动物肯定有talk方法
# 于是我们可以不用考虑它们三者的具体是什么类型,而直接使用
peo1.talk()
dog1.talk()
peo1.talk()


# 定义一个统一的接口来访问
def func(obj):
    obj.talk()


func(cat1)

2.为什么要用多态性?

①增加了程序的灵活性

以不变应万变,不论对象千变万化,使用者都是同一种形式去调用,如func(animal)

②增加了程序额可扩展性

通过继承animal类创建了一个新的类,使用者无需更改自己的代码,还是用func(animal)去调用

class Pig(Animals):  # 属于动物的另外一种形态:猪
    def talk(self):
        print('Pig is huohuo')


pig = Pig()


# 统一接口,对于使用者来说,自己的代码根本无需改动
def func(obj):
    obj.talk()


func(pig)  # 甚至连调用方式都无需改变,就能调用出pig的talk功能

三、鸭子类型

在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。

例如,在不使用鸭子类型的语言中,我们可以编写一个函数,它接受一个类型为"鸭子"的对象,并调用它的"走"和"叫"方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的"走"和"叫"方法。如果这些需要被调用的方法不存在,那么将引发一个运行时错误。任何拥有这样的正确的"走"和"叫"方法的对象都可被函数接受的这种行为引出了以上表述,这种决定类型的方式因此得名。
鸭子类型通常得益于不测试方法和函数中参数的类型,而是依赖文档、清晰的代码和测试来确保正确使用。

class Duck():
    def walk(self):
        print('I walk like a duck')
    def swim(self):
        print('i swim like a duck')

class Person():
    def walk(self):
      print('this one walk like a duck') 
    def swim(self):
      print('this man swim like a duck')

可以很明显的看出,Person类拥有跟Duck类一样的方法,当有一个函数调用Duck类,并利用到了两个方法walk()swim()。我们传入Person类也一样可以运行,函数并不会检查对象的类型是不是Duck,只要他拥有walk()swim()方法,就可以正确的被调用。
再举例,如果一个对象实现了__getitem__方法,那python的解释器就会把它当做一个collection,就可以在这个对象上使用切片,获取子项等方法;如果一个对象实现了__iter__next方法,python就会认为它是一个iterator,就可以在这个对象上通过循环来获取各个子项。

posted @ 2020-01-17 11:19  彩虹然  阅读(7990)  评论(0编辑  收藏  举报