Python——抽象类、接口、泛函数、适配器模式

目录

一、type()函数

二、元类

控制类的创建行为

三、抽象类

四、接口

五、泛函数

六、适配器模式 Adapter

一、type()函数

  • 并非仅仅返回对象的类型
  • Python使用type()函数创建类对象
    函数和类不是编译时定义的,而是在运行时动态创建
  • type()函数依次传入3个参数
    • 类名称
    • 继承的父类集合(tuple)
    • 属性(数据或方法)字典
def say_hello(self):
	print(f"hi,I am {self.name}")

def __init__(self,name):
	self.name=name

People=type('People',(object,),dict(say_hello=say_hello,__init__=__init__))
p=People('zjc')
p.say_hello()

hi,I am zjc

二、元类

控制类的创建行为


• 先定义metaclass,然后创建类,最后创建实例
• 类可以看成metaclass创建的“实例”
元类的定义
• metaclass的类名总是以Metaclass结尾
• metaclass是类的模板,所以必须从type类型派生
元类的使用
• 通过关键字参数metaclass来指定元类来创建类
 

def add(self,value):
	self.append(value)

class ListMetaClass(type):  #定义元类
	def __new__(cls,name,bases,attrs):
		attrs['add']=add
		return type.__new__(cls,name,bases,attrs)

class Mylist(list,metaclass=ListMetaClass):#创建类,可以看做是元类的实例
	pass

l=Mylist()
l.add(1)
l.add(2)
print(l)

[1, 2]
  • 有时需要动态定义类
    • Object Relational Mapping(ORM)
    • 关系数据库的一行映射为一个实例对象,也就是一
    个类对应一个表
    • “透明化”数据库相关的操作
    • 类需要动态定义

三、抽象类

特殊的类,只能被继承,不能被实例
从不同的类中抽取相同的属性和行为

  • 抽象类与普通类的区别
    – 抽象类中有抽象方法
    – 不能被实例化,只能被继承
    – 子类必须实现抽象方法
import abc #借助abc模块实现抽象类

class Fruit(metaclass=abc.ABCMeta):#class Fruit(abc.ABC)
	@abc.abstractmethod
	def harvest(self):
		pass

	@abc.abstractmethod
	def grow(self):
		pass

class Apple(Fruit):  #子类必须实现基类的方法,否则装饰器会报错
	
	def harvest(self):
		print("从树上摘")

	def grow(self):
		print("种苹果树")

	def juice(self):
		print("做苹果汁")

class Watermelon(Fruit):  #继承抽象类
	def harvest(self):
		#super().harvest()
		print("从地里摘")

	def grow(self):
		print("用种子种")

@Fruit.register
class Orange: #注册抽象类
	def harvest(self):
		print("从树上摘")
	
	def grow(self):
		print("种橘子树")

#f=Fruit()
a=Apple()
a.grow()
w=Watermelon()
w.harvest()

o=Orange()
o.grow()

print(isinstance(o,Fruit))
print(issubclass(Orange,Fruit))
print([sc.__name__ for sc in Fruit.__subclasses__()]) #no orange
种苹果树
从地里摘
种橘子树
True
True
['Apple', 'Watermelon']
[<class '__main__.Apple'>, <class '__main__.Watermelon'>]

四、接口

python中没有专门的支持
任何方法都只是一种规范,具体的功能需要子类实现
与抽象类的区别

  • 抽象类中可以对一些抽象方法做出基础实现
  • 接口中所有方法只是规范,不做任何实现

五、泛函数

  • 函数对不同的参数类型会提供不同的处理方式
  • 通过装饰器来实现
  • 类似于重载机制

六、适配器模式 Adapter

将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容性问题
目标类 Target
定义客户所需的接口,可以是一个抽象类或接口,也可以是具体类
适配器类 Adapter
转换器,通过调用另一个接口对Adaptee和Target进行适配
适配者类 Adaptee
被适配类,包括了客户期待的业务方法
 

import abc
class Computer:
	def __init__(self,name):
		self._name=name

	@property
	def name(self):
		return self._name

	@name.setter
	def name(self,value):
		self._name=value

	def __str__(self):
		return 'the {} computer'.format(self._name)

	def execute(self):
		print('execute a computer program')

class Human:
	def __init__(self,name):
		self._name=name
	def __str__(self):
		return '{} is an human'.format(self._name)
	def speak(self):
		print('hello word from human')

class Synthesizer:
	def __init__(self,name):
		self._name=name
	def __str__(self):
		return 'the {} synthesizer'.format(self._name)
	def play(self):
		print('play a synthesizer')

class Target(metaclass=abc.ABCMeta):
	@abc.abstractmethod
	def execute(self):
		pass

class HumanAdapter(Target):
	def __init__(self,human):
		self.human=human

	def execute(self):
		self.human.speak()

class SynthesizerAdapter(Target):
	def __init__(self,syn):
		self.syn=syn
	def execute(self):
		self.syn.play()

#另一种实现策略
class Adapter:
	def __init__(self,adp_obj,adp_methods):
		self.obj=adp_obj
		self.__dict__.update(adp_methods)

	def __str__(self):
		return str(self.obj)

def main():

	objects=[Computer('mac')]
	syn=Synthesizer('yamaha')
	h=Human('zjc')

	objects.append(HumanAdapter(h))
	objects.append(SynthesizerAdapter(syn))
	for obj in objects:
		obj.execute()
	print()

	objects2=[Computer('mac')]
	objects2.append(Adapter(syn,dict(execute=syn.play)))
	objects2.append(Adapter(h,dict(execute=h.speak)))
	for obj in objects2:
		obj.execute()

if __name__=='__main__':main()
execute a computer program
hello word from human
play a synthesizer

execute a computer program
play a synthesizer
hello word from human

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值