编写仍将运行数年的代码
编程语言会改变。图书馆变化。5、10甚至20年以前的某些代码可能仍会运行并产生预期的结果,而2年之后的某些代码可能会因语法错误而失败。这是部分不可避免的,因为语言会不断发展(至少大多数会这样做)。开发人员有责任维护其代码。但是有时候,稳定性是生产代码中的一个重要要求,并且代码应该只运行10年,而无需每年有人通过代码来适应语言变化。或者,我可能有一些小脚本,例如用于科学数据分析的脚本,在多年不接触它们之后我需要重新访问。例如,在气象部门,即使对于非速度必不可少的部分,也有许多可操作的Fortran代码,而代码稳定性是原因之一。一世' 我们听说过对不稳定的恐惧是他们反对迁移到Python的目的之一(当然,除了语言惯性之外,这还可能是新代码不依赖于旧代码)。当然,稳定代码的一种策略是冻结整个操作系统。但这并不总是可行的。
我以Python为例,但问题不仅限于Python。
有关Python兼容性问题的文档
对于Python,有几个文档概述了向后不兼容更改的策略。
PEP-5
根据PEP 5:
从Python过渡版本的发行到向后不兼容版本的发行,必须至少有一年的过渡期。用户将有至少一年的时间来测试他们的程序,并将其从使用已过时的结构迁移到替代结构。
我个人认为一年是很短的。这意味着我可能会编写一些代码,并且从现在起1.5年前它将不再运行。
PEP 291
PEP 291包含不完整的准则指南清单,应避免使用这些准则以保持向后兼容性。但是,它仅与Python 2.x有关。由于Python 2.7是2.x系列的最终版本,而Python 2.7仅是错误修复,因此该PEP现在仅具有历史意义。
PEP 387
向后不兼容的更改也有PEP 387。PEP 387是草案,不是官方政策。2009年6月,在Python-ideas邮件列表中对此进行了讨论。讨论的一部分重点在于开发人员如何编写可抵御语言更改的强大代码。一篇文章列出了一些关于不该做什么的建议:
随之而来的是,您可以推断出在大多数情况下可能是正确的几条规则:不要调用以开头的东西
"_"
,不要猴子打补丁,不要对除您自己以外的类中的对象使用动态类替换,不要依赖于继承层次结构的深度(例如no".__bases__[0].__bases__[0]"
),请确保您的测试在运行时不会产生任何DeprecationWarnings,将属性添加到从其他库继承的类时,请注意潜在的命名空间冲突。我不认为所有这些东西都写在一个地方。
此外,还有一些关于“矿场”(可能会更改的新功能)和“冻结区域”(实际上已保证几乎售出的API不变)的观点。引用安托万·皮特鲁(Antoine Pitrou):
我认为应该对“冻结区域”进行积极的定义(明确的公共API和明确保证的行为),而不是进行消极的定义(明确的“雷区”)。否则,我们将忘记将一些重要的东西放进雷区,并在以后需要以向后不兼容的方式更改这些东西时被咬住。
这个线程似乎没有任何结论,但是它非常接近我要寻找的核心。该线程已使用了将近四年,因此情况可能已更改或改善。什么样的代码可能会生存,而哪种代码更脆弱?
移植指南
除了上面概述的文档之外,每个Python版本还附带一个移植指南:移植到Python 3.2,移植到Python 3.3等。
有用的兼容性
PEP 3151向我介绍了有用的兼容性的概念。用我自己的话来说,可以归结为这样一个想法,即只有精心编写代码,语言开发人员才需要小心维护兼容性。它并没有真正定义有用的兼容性,但是我认为它与我在上面的PEP 387讨论中引用的想法相似。
从程序员的角度
作为一名程序员,我知道Python将来会发生变化,人们(尤其是我自己)将在几年后尝试使用一个,两个或三个次要版本的Python版本运行我的代码。并非所有的东西都兼容,实际上,很容易提出会失败的代码(我曾经遇到过说明的代码if sys.version[:3] != '2.3': print 'Wrong version, exiting'
)。我正在寻找一组有关如何执行和 不 执行哪些操作的准则,以增加我的代码将来仍可不变运行的机会。
有没有这样的指导方针?如何编写将来仍会运行的Python代码?
我的问题既涉及Python的核心,其标准库,也常用附加库,特别是numpy
,scipy
,matplotlib
。
编辑:到目前为止,两个答案与python2和python3有关。这不是我的意思。我知道从Python2迁移到Python3的工具。我的问题是关于语言的变化尚未到来。在寻找更稳定的编码准则方面,我们可以做得比水晶球更好。例如:
import module
比更具前瞻性from module import *
,因为如果module
增加一个或多个新函数/类,后者可能会破坏代码。与未使用文档的方法相比,使用未记录的方法可能无法保证未来的发展,因为未记录的内容可能表示某些内容尚不稳定。
我追求的是这种实用的编码建议。由于它是关于当下→未来的内容,因此我们可以将自己限制为Python3,因为Python2不会再改变了。