• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
孙龙 程序员
少时总觉为人易,华年方知立业难
博客园    首页    新随笔    联系   管理    订阅  订阅
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)
这个类就不能被实例化
你可以说他是一个抽象类

 

  

 

 

 

 

 

 

 

 

  

本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/9350692.html

posted on 2018-07-22 16:57  孙龙-程序员  阅读(713)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3