python - 编写可重用代码

标签 python

我发现自己经常不得不为了不同的目的来回反复更改和调整旧代码,但偶尔为了实现两个版本前的相同目的。

其中一个例子是处理素数的函数。有时我需要的是一个包含 n 个素数的列表。有时我需要的是第 n 个素数。也许我会在接下来的工作中遇到第三个需求。

尽管我必须执行相同的过程但只是返回不同的值,但我可以采用任何方式。我认为一定有比不断更改相同代码更好的方法来做到这一点。我想出的可能的替代方案是:

  1. 返回元组或列表,但这看起来有点困惑,因为其中将包含各种数据类型,包括数千个项目的列表。

  2. 使用输入语句来引导代码,但我更希望它在我单击“运行”时为我做所有事情。

  3. 了解如何利用类功能返回类属性并在我需要的地方访问它们。这对我来说似乎是最干净的解决方案,但我不确定,因为我对此还是个新手。

  4. 只需为每个可重用函数制作五个版本。

我不想成为一个糟糕的程序员,那么哪个选择才是正确的选择呢?或者也许有一些我可以做但我没有想到的事情。

最佳答案

模块化、可重用的代码

你的问题确实很重要。这在程序员的日常生活中很重要。问题是:

我的代码可以重用吗?

如果不是,您将遇到代码冗余,在不止一个地方有相同的代码行。这是错误的最佳起点。想象一下你想以某种方式改变行为,例如,因为你发现了一个潜在的问题。然后你在一个地方改变它,但是你会忘记第二个位置。特别是当您的代码达到 1,000、10,0000 或 100,000 行代码时。

SRP 中进行了总结,Single-Responsibilty-Principle .它指出每个类(也适用于函数)应该只有一个决定,它“应该只做一件事”。如果一个函数做不止一件事,您应该将它分解成更小的 block ,更小的任务。

每次遇到(或编写)超过 10 或 20 行(真实)代码的函数时,您都应该持怀疑态度。此类功能很少坚持这一原则。

对于您的示例,您可以将其标识为单独的任务:

  1. 一个一个地生成素数(生成意味着对我来说使用yield)
  2. 收集 n 个素数。使用 1. 并将它们放入列表中
  3. 获取第 n 个素数。使用 1.,但不保存每个数字,只等待第 n。不像 2. 那样消耗那么多内存。
  4. 查找素数对:使用 1.,记住前一个数,如果与当前数的差为 2,则得出这对数
  5. 收集所有质数对:使用 4. 并将它们放入列表中
  6. ...
  7. ...

该列表是可扩展的,您可以在任何级别重用它。每个功能的代码不会超过 10 行,您不会每次都重新发明轮子。

将它们全部放入一个模块中,并在每个脚本中使用它来解决与素数相关的欧拉问题。

一般来说,我为我的欧拉问题脚本创建了一个小型库。您真的可以习惯在“Project Euler”中编写可重用的代码。

关键字参数

您没有提到的另一个选项(据我所知)是使用可选关键字参数。如果您认为小的原子函数太复杂(虽然我真的坚持您应该习惯它),您可以添加一个关键字参数来控制返回值。例如,在一些 scipy 函数中有一个参数 full_output,它接受一个 bool。如果为 False(默认),则仅返回最重要的信息(例如,优化值),如果为 True,还会返回一些补充信息,例如,优化执行得如何以及需要多少次迭代才能收敛。

您可以定义一个参数 output_mode,可能的值有 "list""last" 等等。

推荐

坚持使用小的、可重用的代码块。习惯这一点是您可以在“欧拉计划”中学到的最有值(value)的东西之一。

备注

如果您尝试实现我为可重用函数建议的模式,您可能会在第 1 点立即遇到问题:如何为此创建生成器样式的函数?例如,如果您使用筛分法。但这还不算太糟糕。

关于python - 编写可重用代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14767077/

相关文章:

python - 动态创建的类是否会像其他对象一样被销毁?

python - 为什么在 python 中对 asyncio 服务器的多个请求的时间会增加?

python - 使用根据另一列的值更改的组 ID 创建新列

python - Linux 屏幕上的 Flash 字符

python - 当我尝试使用网络摄像头时出错(Python)

python - Django 无法在 DATABASES 'default' 为空时运行测试

python - 需要至少一个 MultiFieldPanel 对象 [wagtail]

带有回调函数的 Python 记录器

python:不支持 OpenCV 图像深度 (CV_64F)

python - hvplot 和 Holoplot 之间的区别