2022年 11月 4日

Python多态的两种实现形式

说明:仅供学习使用,请勿用于非法用途,若有侵权,请联系博主删除

作者:zhu6201976

博客:https://blog.csdn.net/zhu6201976

一、Python多态

1.对象多态

对象多态:在继承体系中,定义时的类型和运行时的类型不一样,此时就构成多态

以下是Python伪代码实现Java或C的多态:

  1. class A(object):
  2. def test(self):
  3. print('A test')
  4. class B(A):
  5. def test(self):
  6. print('B test')
  7. class C(A):
  8. def test(self):
  9. print('C test')
  10. def go(a):
  11. """
  12. 接收A类或其子类实例
  13. :param a:
  14. :return:
  15. """
  16. a.test()
  17. if __name__ == '__main__':
  18. go(A())
  19. go(B())
  20. go(C())

执行结果:

由此可见,go函数接收A类或其子类对象,无论是传递A类对象、B类对象、C类对象,方法都可以正常执行, 此时便构成了对象的多态。

2.类多态

类多态:指通过@classmethod形式多态地构造对象,而不是使用Python默认的__init__构造器

需求:实现一套MapReduce流程,用于统计目录下所有文件的总行数,代码如下:

  1. """
  2. 知识要点:
  3. 1.接口 抽象 继承
  4. 2.生成器
  5. 3.map reduce
  6. 4.多线程
  7. 5.通过@classmethod形式批量创建对象
  8. """
  9. import os
  10. import threading
  11. class GenericInputData(object):
  12. """
  13. 通用输入抽象类 抽象方法由子类实现
  14. """
  15. def read(self):
  16. raise NotImplementedError
  17. @classmethod
  18. def generate_inputs(cls, config):
  19. raise NotImplementedError
  20. class FileInputData(GenericInputData):
  21. """
  22. 文件输入类
  23. """
  24. def __init__(self, path):
  25. super().__init__()
  26. self.path = path
  27. def read(self):
  28. return open(self.path, 'r', encoding='utf-8').read()
  29. @classmethod
  30. def generate_inputs(cls, config):
  31. dir_path = config['dir_path']
  32. for file_name in os.listdir(dir_path):
  33. yield cls(os.path.join(dir_path, file_name))
  34. class GenericWorker(object):
  35. """
  36. 通用Worker抽象类 抽象方法由子类实现
  37. """
  38. def __init__(self, input_data):
  39. self.input_data = input_data
  40. self.result = None
  41. def map(self):
  42. raise NotImplementedError
  43. def reduce(self, other):
  44. raise NotImplementedError
  45. @classmethod
  46. def generate_workers(cls, input_class, config):
  47. for input_data in input_class.generate_inputs(config):
  48. yield cls(input_data)
  49. class LineCountWorker(GenericWorker):
  50. """
  51. 统计文件换行符Worker类
  52. """
  53. def map(self):
  54. content = self.input_data.read()
  55. self.result = content.count('\n')
  56. def reduce(self, other):
  57. self.result += other.result
  58. def execute(workers):
  59. threads = [threading.Thread(target=w.map) for w in workers]
  60. for thread in threads:
  61. thread.start()
  62. thread.join()
  63. first, rest = workers[0], workers[1:]
  64. for other in rest:
  65. first.reduce(other)
  66. return first.result
  67. def map_reduce(input_class, worker_class, config):
  68. gen_workers = worker_class.generate_workers(input_class, config)
  69. workers = list(gen_workers)
  70. return execute(workers)
  71. if __name__ == '__main__':
  72. result = map_reduce(FileInputData, LineCountWorker, {'dir_path': 'temp'})
  73. print(result)

由此可见,在Python中,不仅可以通过__init__构造器创建对象,也可以通过@classmethod形式多态地构建对象。