【问题标题】:Python - How to run code written for new version on legacy interpreter?Python - 如何在旧版解释器上运行为新版本编写的代码?
【发布时间】:2014-07-12 19:35:05
【问题描述】:

编辑: 最后我做到了,但是整个过程很痛苦,对于未来的发展,我会明确听取@Martijn Pieters 的建议

我是 python 新手,需要将我在 Windows (cygwin) 机器上做的一些 Python 项目转移到 Linux。该项目使用 ipaddress 模块。我没有 root 访问权限,也没有来自 Linux 机器的 Internet 访问权限,因此无法安装任何东西。所以我已经将我的项目文件(ipfind_v5.py)和我在 cygwin 的 /lib/python2.7/site-packages 目录下找到的 ipaddress.py 模块复制到了一个 Linux 文件夹。问题是当我发出脚本时出现以下错误:

[wakatana@zeus]$ python ipfind_v5.py
Traceback (most recent call last):
  File "ipfind_v5.py", line 28, in ?
    import ipaddress as IP
  File "/home/wakatana/ipfind.py/ipaddress.py", line 28
    if b'\0'[0] == 0:  # Python 3 semantics
           ^
SyntaxError: invalid syntax

我换了

if b'\0'[0] == 0:

if '\x00' == 0:

但是又发生了另一个错误:

[wakatana@zeus ipfind.py]$ python ipfind_v5.py
Traceback (most recent call last):
  File "ipfind_v5.py", line 28, in ?
    import ipaddress as IP
  File "/home/wakatana/ipfind.py/ipaddress.py", line 1123
    except ValueError as exc:
                       ^
SyntaxError: invalid syntax

然后根据https://docs.python.org/2/tutorial/errors.html 这篇关于异常的文章,我做到了:

sed -i 's/ as exc/, exc/' ipaddress.py

在这之后我得到另一个错误(ipaddress模块​​的来源在这里:https://github.com/phihag/ipaddress/blob/master/ipaddress.py):

[wakatana@zeus ipfind.py]$ python ipfind_v5.py
Traceback (most recent call last):
  File "ipfind_v5.py", line 28, in ?
    import ipaddress as IP
  File "/home/wakatana/ipfind.py/ipaddress.py", line 1173
    if isinstance(b, bytes)
     ^
SyntaxError: invalid syntax

那我重写这部分:

return u'.'.join(_compat_str(struct.unpack('!B', b)[0]
                             if isinstance(b, bytes)
                             else b)
                 for b in _compat_to_bytes(ip_int, 4, 'big'))

进入这个(希望这是uquivalents,似乎代码运行正常):

retval=[]
for b in _compat_to_bytes(ip_int, 4, 'big'):
  if isinstance(b, str):
    retval.append(_compat_str(struct.unpack('!B', b)[0]))
  else:
    retval.append(b);

return unicode(".".join(retval))

需要的另外两个步骤: changing bytes to str changing: from . import foo to: import foo

配置:

Linux 版本: Python 2.4.3

Windows (cygwin) 版本: Python 2.7.3

【问题讨论】:

  • 你不能。您的选择是升级或移植。
  • 好的,那么如何移植ipaddress模块​​以在2.4.3版本上运行?
  • 通过docs.python.org/2/whatsnew了解每个主要版本之间的变化。

标签: python linux cygwin version


【解决方案1】:

你不能让 Python 2.4 运行 Python 2.7 代码,不。

Python 项目使用 MAJOR.MINOR.PATCH 编号方案遵循 semantic version model。 Python 保证语法在补丁版本之间保持不变; 2.4 代码可以在 2.4.x 版本中正常工作,除非出现错误。在次要版本中,Python 尝试保持向后兼容性;早期 2.x 版本的代码在可能的情况下继续在以后的版本中工作。因此,为 2.4 编写的代码在使用 Python 2.7 运行时仍然有效。 Python 3 是一个新的主要发布周期,并引入了向后不兼容的重大更改。

except Exception, name:except Exception as name: 的变化就是这样一种变化,在Python 2.6 中引入;旧的语法容易出错,新的语法让你更清楚地将捕获的异常绑定到一个名称。

也就是说,我们已努力简化编写可在 Python 2.x 和 Python 3.x 解释器上运行的代码。这包括在 Python 2.x 版本中添加以接受某些类型的语法,否则这些语法只能在 Python 3 中使用。

b'...' 语法就是这样一种变化。 Python 2 的str 类型已被Python 3 中的bytes 类型替换,b'..' 表示法是bytes 字符串文字语法。因为bytes 实际上是Python 2 中的旧str 类型,所以您也可以使用b'...' from Python 2.6 onwards,从而生成一个常规的Python 2 字符串对象。相反,较新的 Python 3.x 版本接受 u'...' 作为字符串文字语法,这在 Python 2 中会产生 Unicode 字符串值。

每个主要和次要版本都记录了 What's new section 中的更改和新增内容,如果您想将代码反向移植到 Python 2.4,则必须通读这些文档。

对此没有“通用转换器”。有一个工具可以在 Python 2 和 Python 3 语法之间进行转换(请参阅 2to33to2 工具),但这些工具不会帮助您将兼容 2.7 的代码打包到 2.4。

然而,编译 Python 解释器并将其安装在您的主目录中相对容易,无需 root 访问权限。我会下载 Python 2.7,使用./configure --prefix=$HOME 对其进行配置,然后使用makemake install 将其安装在~/bin/~/lib/python2.7/ 中,然后使用该二进制文件运行脚本。

【讨论】:

  • 谢谢。我知道这不是最好的方法,安装新的解释器会更好。但是当使用已安装的解释器可能是我唯一的选择(某些公司政治等)时,我处于这种情况。基本上我现在需要的是最后一个代码sn-p的语法等价物,你能帮忙或指向我的文档(你在评论中提到的变化有点长阅读)?到目前为止,我发现问题出在 if 语句中,因为 u'.'join... 似乎在 2.4 上工作。我搜索过:python if else 样式但没有运气。谢谢
  • @WakanTanka: 你有一个conditional expressiontrue_expression if test_expression else false_expression 将首先执行test_expression,如果是,则执行true_expression 并返回它,否则执行false_expression 并返回它.
最近更新 更多