# -*- encoding: utf-8 -*-
import functools
import os
from threading import Thread
'''
第24条: 以@classmethod形式的多态去通用地构建对象
关键:
1 python类的多态
多态含义: 继承体系的多个类能以自己的方式实现某个方法。
这些类都满足相同的接口但有不同的功能。
局限: python只能有一个__init__构造方法,可以用@classmethod
来初始化类的实例,等同于实现另一种类的__init__方法
2 classmethod
形式:
@classmethod
def fromData(cls, data):
......
其中第一个参数是cls,表示类的名称,用于后续创建该类的实例
3 类的多态方法举例
@classmethod
def createWorker(cls, inputClass, config):
workers = []
# 关键: inputClass.fromData是类级别的多态方法
for inputData in inputClass.fromData(config):
workers.append(cls(inputData))
return workers
分析:
这里在一个类中使用了另一个类的某个方法,我们传入的是类名,
而加入这个类有子类,传入不同的子类,实际是执行不同子类
各自的同名方法,单实现不同的功能,即一个接口,多个功能,
这就是python的多态。
4 总结
1)多态是指一个接口,多种实现。
在C++中可以用类似如下形式实现多态:
ParentClass* pointer = new SubClass1();
......
pointer->commonFunction();
期间可以给point赋予不同的子类指针。
子类指针赋值给父类指针类型,则调用该父类指针时,会根据实际
传入的子类指针而调用对应子类的方法,从而实现多态。
2) 而对于python类的多态实际就是
将类的实例作为参数传给某个方法,在该方法中调用类实例的方法,
如果该类有子类,且每个子类各自都实现了该方法,那么根据传入
的类属于不同的子类,就可以实现该同名方法不同的功能。
3) 通过@classmethod可以给python实现除__init__外的另一个构造方法
参考:
Effectiv Python 编写高质量Python代码的59个有效方法
'''
class BaseInputData(object):
def read(self):
raise NotImplementedError
@classmethod
def fromData(cls, data):
raise NotImplementedError
class PathInputData(BaseInputData):
def __init__(self, path):
super(PathInputData, self).__init__()
self.path = path
def read(self):
return open(self.path).read()
@classmethod
def fromData(cls, config):
dataDir = config.get('data_dir')
for name in os.listdir(dataDir):
yield cls(os.path.join(dataDir, name))
class BaseWorker(object):
def __init__(self, inputData):
self.inputData = inputData
self.result = None
def map(self):
raise NotImplementedError
@classmethod
def createWorker(cls, inputClass, config):
workers = []
'''
关键: inputClass.fromData是类级别的多态方法
'''
for inputData in inputClass.fromData(config):
workers.append(cls(inputData))
return workers
class LineCountWorker(BaseWorker):
def map(self):
data = self.inputData.read()
self.result = data.count('\n')
def reduce(self, other):
self.result += other.result
def execute(workers):
threads = [Thread(target=worker.map) for worker in workers ]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
first, rest = workers[0], workers[1:]
for worker in rest:
first.reduce(worker)
return first.result
def mapReduce(workerClass, inputClass, config):
workers = workerClass.createWorker(inputClass, config)
return execute(workers)
def writeFile(fileName, contentList):
content = "\n".join(contentList)
with open(fileName, "w") as fr:
fr.write(content)
def wirteFiles(fileNames):
contentList = []
for index, fileName in enumerate(fileNames):
content = str(index)
contentList.append(content)
writeFile(fileName, contentList)
def getPath(dirPath, fileName):
result = os.path.join(dirPath, fileName)
return result
def executeMapReduce():
dirPath = "./mydir"
if not os.path.exists(dirPath):
os.mkdir(dirPath)
fileNames = [ str(i) + ".txt" for i in range(11)]
partialGetPath = functools.partial(getPath, dirPath)
results = map(partialGetPath, fileNames)
print results
wirteFiles(results)
config = {"data_dir": dirPath}
result = mapReduce(LineCountWorker, PathInputData, config)
print result
assert result == 55
def process():
executeMapReduce()
if __name__ == "__main__":
process()
Effective Python 读书笔记: 第24条: 以@classmethod形式的多态去通用地构建对象
猜你喜欢
转载自blog.csdn.net/qingyuanluofeng/article/details/88914061
今日推荐
周排行