9

Python 的风格最佳实践是否适用于科学编码?

我发现很难保持科学 Python 代码的可读性。

例如,建议对变量使用有意义的名称,并通过避免import *. 因此,例如:

    import numpy as np
    normbar = np.random.normal(mean, std, np.shape(foo))

但是这些建议可能会导致一些难以阅读的代码,尤其是考虑到 79 个字符的行宽。比如我刚才写了下面的操作:

net["weights"][ix1][ix2] += lrate * (CD / nCases - opts["weightcost_pretrain"].dot(net["weights"][ix1][ix2]))

我可以跨行跨越表达式:

net["weights"][ix1][ix2] += lrate * (CD / nCases - 
     opts["weightcost_pretrain"].dot(net["weights"][ix1][ix2]))

但这似乎并没有好多少,我不确定第二行缩进多深。当双缩进到嵌套循环中时,这些类型的行继续变得更加棘手,并且一行上只有 50 个字符可用。

我应该接受科学 Python 看起来很笨重,还是有办法避免像上面的例子那样出现线条?

一些潜在的方法是:

  • 使用较短的变量名
  • 使用较短的字典键名
  • 直接导入 numpy 函数并为其分配短名称
  • 为算术运算的组合定义辅助函数
  • 将操作分解成更小的部分,并在每一行放置一个

我将不胜感激任何关于追求和避免哪些方面的智慧,以及对其他补救措施的建议。

4

2 回答 2

3
  • 为算术运算的组合定义辅助函数
  • 将操作分解成更小的部分,并在每一行放置一个

这些都是好主意——符合 PEP 8 背后的意图,以及一般的 Pythonic 风格。事实上,每当有人建议修改 PEP 8 以提供有关长行的更多信息时,一半的回答通常是“如果你超出了行数限制,那么你可能在一个表达式中做的太多了”。

而且,更一般地说,分解代码并为合理的操作赋予合理的名称总是一个好主意。

当然,在不知道所有这些东西到底代表什么的情况下,我只能猜测如何将它们分开,但我认为这样的东西会非常易读和有意义:

cost = opts["weightcost_pretrain"].dot(net["weights"][ix1][ix2])
weight = lrate * (CD / nCases - cost)
net["weights"][ix1][ix2] += weight
于 2013-08-08T20:24:21.413 回答
2

我认为风格指南总是适用的——我每天都使用 Python 进行科学工作,发现如果我将长行分成逻辑组件和合理的变量名称,或使用函数。

我会做更多这样的事情:

weights = net["weights"][ix1][ix2]
opts_arr = opts["weightcost_pretrain"]
weights += lrate * (CD / nCases - opts_arr.dot(weights))

Python“简洁”的另一种说法是 Python 在语法上很密集,我发现阅读和理解一长串 Python 比一长串 Java 更难(尤其是在使用来自 3rd 方库的高级函数时)隐藏低级逻辑,如 NumPy)。

于 2013-08-08T20:26:10.360 回答