python鸭制作类代码_python鸭子类型(多态)抽象基类(abc模块)

什么是多态

多态,按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。

多态的目的:就是指不同的对象的,同状态下的,做出的不同表现形式

python中的鸭子类型

python中没有多态,但是可以用鸭子类型实现多态。

鸭子类型主要原因:python中参数是无类型的

init () 是一个最典型的鸭子类型 ( 多态)

class Cat(object):

def say(self):

print("i am a cat")

class Dog(object):

def say(self):

print("i am a fish")

class Company(object):

def __init__(self, employee_list):

self.employee = employee_list

def __getitem__(self, item):

return self.employee[item]

def __len__(self):

return len(self.employee)

company = Company(["tom", "bob", "jane"])

class Duck(object):

def say(self):

print("i am a duck")

animal_list = [Cat, Dog, Duck]

for animal in animal_list:

animal().say()

dog = Dog()

a = ["bobby1", "bobby2"]

b = ["bobby2", "bobby"]

name_tuple = ["bobby3", "bobby4"]

name_set = set()

name_set.add("bobby5")

name_set.add("bobby6")

a.extend()

print(a)

接口类不能被实例化

在python里没有接口类这种数据类型,没有接口类专门的语法

但是 可以通过继承abc模块实现接口的功能

from abc import ABCMeta,abstractmethod

class Payment(metaclass=ABCMeta): # 接口类

@abstractmethod

def pay(self,money):

pass

class Wechatpay(Payment): # 根据接口类的规范编程

def pay(self,money):

print('微信支付了%s元'%money)

p = Wechatpay()

p.pay(6)

#我们去检查某个类是否有某种方法

class Company(object):

def __init__(self, employee_list):

self.employee = employee_list

def __len__(self):

return len(self.employee)

com = Company(["bobby1","bobby2"])

print(hasattr(com, "__len__"))

class A:

pass

class B:

pass

#我们在某些情况之下希望判定某个对象的类型

from collections.abc import Sized

isinstance(com, Sized)

b = B()

print(isinstance(b, A))

# print(len(com))

#我们需要强制某个子类必须实现某些方法

#实现了一个web框架,集成cache(redis, cache, memorychache)

#需要设计一个抽象基类, 指定子类必须实现某些方法

#如何去模拟一个抽象基类

import abc

from collections.abc import *

class CacheBase(metaclass=abc.ABCMeta):

@abc.abstractmethod

def get(self, key):

pass

@abc.abstractmethod

def set(self, key, value):

pass

# class CacheBase():

# def get(self, key):

# raise NotImplementedError

# def set(self, key, value):

# raise NotImplementedError

#

class RedisCache(CacheBase):

def set(self, key, value):

pass

# redis_cache = RedisCache()

# redis_cache.set("key", "value")

二. 接口隔离原则

from abc import ABCMeta,abstractmethod

class FlyAnimal(metaclass=ABCMeta):

@abstractmethod

def fly(self):

print(11111)

class SwimAnimal(metaclass=ABCMeta):

@abstractmethod

def swim(self): pass

class WalkAnimal(metaclass=ABCMeta):

@abstractmethod

def walk(self): pass

class Swan(SwimAnimal,WalkAnimal,FlyAnimal):

# 飞

def fly(self):pass

# 游泳

def swim(self):pass

# 走

def walk(self):pass

class Qq(SwimAnimal,WalkAnimal):

def swim(self):pass

# 走

def walk(self):pass

class Bird(FlyAnimal,WalkAnimal):

# 飞

def fly(self):pass

# 走

def walk(self):pass

Swan()

接口隔离原则

三. 抽象类

抽象类 规范一个类的类

在python里 抽象类和接口类 没区别

在java里 有区别

java的接口规定里面的方法一定不能实现(一句代码也不能写)

抽象类 单继承

无论接口类 还是抽象类 其实都是一种面向对象编程的开发规范

只是在接口类或者抽象类中 去约束继承它的子类必须实现某些方法

对于java代码来说:如果发生多继承(类似上面接口隔离原则) 那么一定是接口类 且里面的方法都不能实现

如果在方法里有了实现 那么一定是单继承 的抽象类

但是对于python来说 就没有这些约束

因为python没有接口的概念

对于类的继承 没有多继承的限制

实际上abc模块是帮我实现抽象类的方法,只是我们用它来模仿接口类的效果了

在python中,只要metaclass = ABCMeta 定义了抽象方法(@abctractmethod)

这个类就不能被实例化

你可以说他是一个抽象类

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值