Python中怎么通过@classmethod实现多态

发布时间:2022-11-28 09:32:15 作者:iii
来源:亿速云 阅读:140

这篇文章主要介绍了Python中怎么通过@classmethod实现多态的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python中怎么通过@classmethod实现多态文章都会有所收获,下面我们一起来看看吧。

通过@classmethod 实现多态

1.概述

python中通常使用对象创建多态模式,python还支持类创建多态模式。下面通过一个例子展示它如何实现多态。

通过对象创建多态和类创建多态开发模式区别

2.类方法创建多态模式示例

2.1.普通模式

先通过一个的示例看下常规方式发开的代码没有使用多态时候存在的问题,然后在通过类多态来优化代码。

下面实现一个读取数据,然后处理数据的示例,他有两条继承体系。
输入信息体系:将输入信息的方式创建为类继承关系,可以根据读取信息的方式创建不同的InputData子类。
处理数据体系:将处理信息的方式创建类继承关系,根据对信息处理的方式创建不同的Worker子类。

然后通过mapreduce函数组合业务执行逻辑,最后输出运行结果。

# 接收输入信息类体系
class InputData:
    def read(self):
        raise NotImplementedError

class PathInputData(InputData):
    def __init__(self,path):
        super().__init__()
        self.path = path

    def read(self):
        with open(self.path) as f:
            return f.read()

# 处理信息类体系
class 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

class LineCountWorker(Worker):
    def map(self):
        data = self.input_data
        self.result = data.count('/n')

    def reduce(self, other):
        self.result += other.result

# 组合业务
import os
def generate_inputs(data_dit):
    for name in os.listdir(data_dit):
        # 读文件内容
        yield PathInputData(os.path.join(data_dit, name))

def create_workers(input_list):
    workers = []
    for input_data in input_list:
        # 处理数据
        workers.append(LineCountWorker(input_data))
    return workers

from threading import Thread
def execute(workers):
    threads = [Thread(target=w.map) for w in workers]
    for thread in threads: thread.start()
    for thread in threads: thread.join()

    first, *rest = workers
    for worker in rest:
        first.reduce(worker)
    return first.result

def mapreduce(data_dir):
    inputs = generate_inputs(data_dir)
    workers = create_workers(inputs)
    return execute(workers)

import os
import random
def write_test_files(tmpdir):
    os.makedirs(tmpdir)
    for i in range(100):
        with open(os.path.join(tmpdir, str(i)), 'w') as f:
            f.write('\n' * random.randint(0, 100))
tmpdir = 'test_inputs'
write_test_files(tmpdir)
result = mapreduce(tmpdir)
print(f'There are  {result} lines')

上面接收信息处理信息的示例存在两个问题:

这个问题最好能够通过类方法多态来解决,这种多态与实例方法多态很像,只不过他针对的是,而不是这些类的对象

2.2.类方法多态重构业务

类方法多态的实现非常简单,下面将代码中关键的点提炼出来。

class GenericInputData:
    def read(self):
        raise NotImplementedError
	# 创建一个多态的类方法,让子类实现不同的功能
    @classmethod
    def generate_inputs(cls, config):
        raise NotImplementedError

class PathInputData(GenericInputData):
    def __init__(self, path):
        super().__init__()
        self.path = path

    def read(self):
        with open(self.path) as f:
            return f.read()
	# 子类重写父类的类方法
    @classmethod
    def generate_inputs(cls, config):
        data_dir = config['data_dir']
        for name in os.listdir(data_dir):
            yield cls(os.path.join(data_dir, name))


class GenericWorker:
    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 create_workers(cls, input_class, config):
        workers = []
        for input_data in input_class.generate_inputs(config):
            workers.append(cls(input_data))
        return workers

class LineCountWorker(GenericWorker):
    def map(self):
        data = self.input_data.read()
        self.result = data.count('\n')

    def reduce(self, other):
        self.result += other.result

# 定义的形参类型为父类,实现了类方法多态
def mapreduce(worker_class, input_class, config):
    workers = worker_class.create_workers(input_class, config)
    return execute(workers)
config = {'data_dir': tmpdir}
result = mapreduce(LineCountWorker, PathInputData, config)
print(f'There are {result} lines')

通过类方法多态重构代码后,mapreduce函数支持了多态,它接收的是一个父类类型,根据传入的实际子类实现把不同的功能。当再扩展GenericInputData、GenericWorker子类后,mapreduce函数不需要修改代码,实现了左开右闭原则。

关于“Python中怎么通过@classmethod实现多态”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Python中怎么通过@classmethod实现多态”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注亿速云行业资讯频道。

推荐阅读:
  1. 如何实现classmethod装饰器?
  2. @classmethod方法怎么在Python中使用

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python @classmethod

上一篇:vue+element-ui前端怎么使用print-js实现打印功能

下一篇:Go日常开发常用第三方库和工具有哪些

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》