使用singledispatch在Python中追溯地添加方法

开发 后端
在本系列中,我们将介绍七个可以帮助你解决常见 Python 问题的 PyPI 库。今天,我们将研究 singledispatch,这是一个能让你追溯地向 Python 库添加方法的库。

[[266244]]

在我们覆盖 7 个 PyPI 库的系列文章中了解更多解决 Python 问题的信息。

Python 是当今使用最多流行的编程语言之一,因为:它是开源的,它具有广泛的用途(例如 Web 编程、业务应用、游戏、科学编程等等),它有一个充满活力和专注的社区支持它。这个社区是我们在 Python Package Index(PyPI)中提供如此庞大、多样化的软件包的原因,用以扩展和改进 Python。并解决不可避免的问题。

在本系列中,我们将介绍七个可以帮助你解决常见 Python 问题的 PyPI 库。今天,我们将研究 singledispatch,这是一个能让你追溯地向 Python 库添加方法的库。

singledispatch

想象一下,你有一个有 Circle、Square 等类的“形状”库。

Circle 类有半径、Square 有边、Rectangle 有高和宽。我们的库已经存在,我们不想改变它。

然而,我们想给库添加一个面积计算。如果我们不会和其他人共享这个库,我们只需添加 area 方法,这样我们就能调用 shape.area() 而无需关心是什么形状。

虽然可以进入类并添加一个方法,但这是一个坏主意:没有人希望他们的类会被添加新的方法,程序会因奇怪的方式出错。

相反,functools 中的 singledispatch 函数可以帮助我们。

  1. @singledispatch
  2. def get_area(shape):
  3. raise NotImplementedError("cannot calculate area for unknown shape",
  4. shape)

get_area 函数的“基类”实现会报错。这保证了如果我们出现一个新的形状时,我们会明确地报错而不是返回一个无意义的结果。

  1. @get_area.register(Square)
  2. def _get_area_square(shape):
  3. return shape.side ** 2
  4. @get_area.register(Circle)
  5. def _get_area_circle(shape):
  6. return math.pi * (shape.radius ** 2)

这种方式的好处是如果某人写了一个匹配我们代码的形状,它们可以自己实现 get_area

  1. from area_calculator import get_area
  2.  
  3. @attr.s(auto_attribs=True, frozen=True)
  4. class Ellipse:
  5. horizontal_axis: float
  6. vertical_axis: float
  7.  
  8. @get_area.register(Ellipse)
  9. def _get_area_ellipse(shape):
  10. return math.pi * shape.horizontal_axis * shape.vertical_axis

调用 get_area 很直接。

  1. print(get_area(shape))

这意味着我们可以将大量的 if isintance()/elif isinstance() 的代码以这种方式修改,而无需修改接口。下一次你要修改 if isinstance,你试试 `singledispatch!

在本系列的下一篇文章中,我们将介绍 tox,一个用于自动化 Python 代码测试的工具。 

责任编辑:庞桂玉 来源: Linux中国
相关推荐

2017-04-12 11:16:08

Python终端编程

2010-03-10 11:11:16

Python编程

2021-04-12 16:18:24

CPUFetchLinuxCPU

2015-09-15 13:12:35

脚本UbuntuLinux内核

2010-03-10 19:18:10

Python scri

2010-03-15 15:30:35

Python模块

2022-11-03 11:19:22

2011-06-14 17:51:47

QListview Qt MVC

2013-12-19 15:01:03

LinuxLinux进程

2013-11-06 15:35:49

LinuxLinux进程

2022-03-01 21:25:30

对象代码Proxy

2014-12-03 10:27:06

BYODBYOD安全移动设备

2020-04-10 10:22:12

Java判空编程语言

2023-10-08 15:41:35

2021-07-02 06:34:53

Go语言sysmon

2020-09-25 11:30:20

Java判空代码

2010-07-27 12:28:56

Flex Remote

2018-10-11 09:40:53

前端JavaScript编程语言

2012-03-07 11:17:19

AndroidPhoneGap插件

2021-01-07 09:35:49

Pythontqdm进度
点赞
收藏

51CTO技术栈公众号