一、Python多态
1.对象多态
对象多态:在继承体系中,定义时的类型和运行时的类型不一样,此时就构成多态
以下是Python伪代码实现Java或C的多态:
class A(object):
def test(self):
print('A test')
class B(A):
def test(self):
print('B test')
class C(A):
def test(self):
print('C test')
def go(a):
"""
接收A类或其子类实例
:param a:
:return:
"""
a.test()
if __name__ == '__main__':
go(A())
go(B())
go(C())
执行结果:
由此可见,go函数接收A类或其子类对象,无论是传递A类对象、B类对象、C类对象,方法都可以正常执行, 此时便构成了对象的多态。
2.类多态
类多态:指通过@classmethod形式多态地构造对象,而不是使用Python默认的__init__构造器
需求:实现一套MapReduce流程,用于统计目录下所有文件的总行数,代码如下:
"""
知识要点:
1.接口 抽象 继承
2.生成器
3.map reduce
4.多线程
5.通过@classmethod形式批量创建对象
"""
import os
import threading
class GenericInputData(object):
"""
通用输入抽象类 抽象方法由子类实现
"""
def read(self):
raise NotImplementedError
@classmethod
def generate_inputs(cls, config):
raise NotImplementedError
class FileInputData(GenericInputData):
"""
文件输入类
"""
def __init__(self, path):
super().__init__()
self.path = path
def read(self):
return open(self.path, 'r', encoding='utf-8').read()
@classmethod
def generate_inputs(cls, config):
dir_path = config['dir_path']
for file_name in os.listdir(dir_path):
yield cls(os.path.join(dir_path, file_name))
class GenericWorker(object):
"""
通用Worker抽象类 抽象方法由子类实现
"""
def __init__(self, input_data):
self.input_data = input_data
self.result = None
def map(self):
raise NotImplementedError
def reduce(self, other):
raise NotImplementedError
@classmethod
def generate_workers(cls, input_class, config):
for input_data in input_class.generate_inputs(config):
yield cls(input_data)
class LineCountWorker(GenericWorker):
"""
统计文件换行符Worker类
"""
def map(self):
content = self.input_data.read()
self.result = content.count('\n')
def reduce(self, other):
self.result += other.result
def execute(workers):
threads = [threading.Thread(target=w.map) for w in workers]
for thread in threads:
thread.start()
thread.join()
first, rest = workers[0], workers[1:]
for other in rest:
first.reduce(other)
return first.result
def map_reduce(input_class, worker_class, config):
gen_workers = worker_class.generate_workers(input_class, config)
workers = list(gen_workers)
return execute(workers)
if __name__ == '__main__':
result = map_reduce(FileInputData, LineCountWorker, {'dir_path': 'temp'})
print(result)
由此可见,在Python中,不仅可以通过__init__构造器创建对象,也可以通过@classmethod形式多态地构建对象。