假设我开发了一个用Python编写的通用最终用户实用程序。以前,我只有一个版本适用于Python 2.3之后的版本。可以说,“如果需要,请下载Python,然后运行此脚本”。源控件中只有一个版本的脚本(我正在使用Git)来跟踪。
使用Python 3,这不再是必然的。在可预见的未来,我需要同时开发两个不同的版本,一个适用于Python 2.x,另一个适用于Python 3.x.从发展的角度来看,我可以想到几个选择:
我目前倾向于选项3,因为前两个会涉及很多容易出错的单调乏味。但是选项3似乎很乱,我的源代码控制系统应该为我管理补丁。
对于分发包装,有更多选项可供选择:
我再次在这里倾向于选项3,尽管我还没有尝试开发这样的存根加载器。
还有其他想法吗?
答案 0 :(得分:9)
编辑:我的原始答案基于2009年的状态,Python 2.6和3.0作为当前版本。现在,使用Python 2.7和3.3,还有其他选择。特别是,现在使用Python 2和Python 3的单个代码库是完全可行的。
请参阅Porting Python 2 Code to Python 3
原始回答:
用于移植现有的Python 2.5或2.6 Python 3.0的源代码,最好的 策略如下:
(先决条件:)从优秀的测试覆盖率开始。
端口到Python 2.6。这应该不是普通端口的工作 从Python 2.x到Python 2.(x + 1)。 确保所有测试都通过。
(仍在使用2.6 :)打开-3命令行开关。这使得 有关功能的警告 在3.0中删除(或更改)。跑你的 再次测试套件,并修复代码 你得到警告,直到有 没有任何警告,以及所有测试 仍然通过。
- 醇>
在源代码树上运行2to3源到源转换器。 (参见2to3 - 自动Python 2到3 代码翻译了解更多 工具。)运行结果 Python 3.0下的翻译。手动 修复任何剩余的问题,修复 问题直到所有测试再次通过。
不建议尝试写 在...下运行不变的源代码 Python 2.6和3.0;你必须这样做 使用非常扭曲的编码风格, 例如避免印刷陈述, 元类,等等。如果你是 维护需要的库 支持Python 2.6和Python 3.0,最好的方法是通过编辑2.6修改上面的步骤3 源代码的版本并运行 2to3翻译再次,而不是 编辑3.0版本的源代码 代码。
理想情况下,您最终会得到一个兼容的版本,可以使用2to3转换为3.0。在实践中,您可能无法完全实现此目标。因此,您可能需要进行一些手动修改才能使其在3.0下工作。
我会在分支中维护这些修改,就像您的选项2.但是,我不会在此分支中维护最终的3.0兼容版本,而是考虑在 2to3之前应用手动修改翻译,并将此修改后的2.6代码放入您的分支。这种方法的优点是该分支与2.6中继之间的差异相当小,并且只包括手动更改,而不是2to3所做的更改。这样,单独的分支应该更容易维护和合并,并且您应该能够从2to3中的未来改进中受益。
或者,采取一些“观望”的方法。继续您的移植只能使用单个2.6版本加2to3翻译,并推迟剩余的手动修改,直到您真正需要3.0版本。也许到了这个时候,你不再需要任何手动调整......
答案 1 :(得分:2)
对于开发,选项3太麻烦了。维护两个分支是最简单的方法,尽管这样做的方式因VCS而异。许多DVCS将更乐意使用单独的repos(具有共同的祖先来帮助合并),并且集中式VCS可能更容易与两个分支一起使用。选项1是可能的,但你可能会错过合并的东西和更容易出错的IMO。
对于发行,如果可能的话,我也会使用选项3。无论如何,所有3个选项都是有效的,我不时会看到这些模型的变化。
答案 2 :(得分:2)
我认为我根本不会走这条路。无论你怎么看它都很痛苦。实际上,除非在同时保留两个版本方面存在强烈的商业利益,否则这比获得更令人头疼。
我认为现在继续开发2.x更有意义,至少持续几个月,长达一年。在某个时间点,现在是时候宣布2.x的最终稳定版本并开发下一个3.x +
例如,在某些主要框架采用这种方式之前,我不会切换到3.x:PyQt,matplotlib,numpy和其他一些框架。而且我真的不介意,如果在某些时候他们停止2.x支持并开始为3.x开发,因为我知道在短时间内我也可以切换到3.x. / p>
答案 3 :(得分:1)
我首先迁移到2.6,这非常接近python 3.0。您甚至可能希望等待2.7,这将更接近python 3.0。
然后,一旦你迁移到2.6(或2.7),我建议你只保留一个版本的脚本,例如“如果PY3K:......其他:......”在罕见的地方这将是强制性的。当然,这不是我们开发人员喜欢编写的代码,但是您不必担心管理多个脚本或分支或补丁或分发,这将是一场噩梦。
无论您选择什么,请确保您拥有100%代码覆盖率的全面测试。
祝你好运!答案 4 :(得分:0)
无论选择哪种开发选项,都可以通过彻底的单元测试来缓解大多数潜在问题,以确保两个版本产生匹配的输出。也就是说,选项2对我来说似乎最自然:将更改从一个源树应用到另一个源树是一个任务(大多数)版本控制系统的设计目的 - 为什么不利用它们提供的工具来简化这一点。
对于开发,如果没有“了解您的受众”,很难说。 Power Python用户可能会喜欢不必下载两个软件副本,但对于更普通的用户群来说,它可能只是“正常工作”。