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函数并为其指定短名称
- 为算术运算的组合定义辅助函数
- 将操作分解为更小的部分,并在每条线上放置一个
我希望你能明智地选择其中的哪一个,避免哪一个以及其他补救措施的建议。
- 为算术运算的组合定义辅助函数
- 将操作分解为更小的部分,并在每条线上放置一个
这两个想法都很好——符合PEP8背后的意图,也符合Python风格。事实上,每当有人建议修改PEP 8以提供更多关于长队的信息时,一半的回答通常是"如果你超过了底线,你可能在一个表达中做得太多了"。
而且,更普遍地说,分解代码并为合理的操作提供合理的名称总是一个好主意。
当然,在不知道所有这些东西到底代表什么的情况下,我只能猜测如何将它们分开,但我认为这样的东西会非常可读和有意义:
cost = opts["weightcost_pretrain"].dot(net["weights"][ix1][ix2])
weight = lrate * (CD / nCases - cost)
net["weights"][ix1][ix2] += weight
我认为风格指南总是适用的-我每天都在科学工作中使用Python,发现如果我把长行分解成逻辑组件和合理的变量名,或者使用了一个函数,我可以更容易地阅读代码,几个月后就可以毫不费力地返回代码。
我会做一些更像这样的事情:
weights = net["weights"][ix1][ix2]
opts_arr = opts["weightcost_pretrain"]
weights += lrate * (CD / nCases - opts_arr.dot(weights))
Python"简洁"的另一种说法是,Python在语法上很密集,我发现阅读和理解一长串Python比阅读和理解Java更难(尤其是当使用第三方库中隐藏低级逻辑的高级函数时,如NumPy)。