@[toc]
抽象类
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
网友评论