如何将此代码移植到Python 3中,以便它可以在Python 2和Python 3中运行?
raise BarException, BarException(e), sys.exc_info()[2]
(从http://blog.ionelmc.ro/2014/08/03/the-most-underrated-feature-in-python-3/复制)
奖金问题
做一些像
IS_PYTHON2 = sys.version_info < (3, 0)
if IS_PYTHON2:
raise BarException, BarException(e), sys.exc_info()[2]
# replace with the code that would run in Python 2 and Python 3 respectively
else:
raise BarException("Bar is closed on Christmas")
答案 0 :(得分:5)
您必须使用exec()
,因为您无法在Python 3中使用3参数语法;它会引发语法错误。
一如既往six
library已覆盖您,移植到不依赖其他six
定义,其版本如下:
import sys
if sys.version_info[0] == 3:
def reraise(tp, value, tb=None):
if value is None:
value = tp()
if value.__traceback__ is not tb:
raise value.with_traceback(tb)
raise value
else:
exec("def reraise(tp, value, tb=None):\n raise tp, value, tb\n")
现在你可以使用:
reraise(BarException, BarException(e), sys.exc_info()[2])
没有进一步测试Python版本。
答案 1 :(得分:5)
Six提供了简单的实用程序来包装它们之间的差异 Python 2和Python 3.它旨在支持有效的代码库 在Python 2和3上都没有修改。六个只包含一个 Python文件,因此复制到项目中很容易。 http://pythonhosted.org/six/
from six import reraise as raise_ # or from future.utils import raise_
traceback = sys.exc_info()[2]
err_msg = "Bar is closed on Christmas"
raise_(ValueError, err_msg, traceback)
您可以使用2to3制作代码的Python 3副本。
2to3是一个Python程序,它读取Python 2.x源代码并应用 一系列修复程序,将其转换为有效的Python 3.x代码。该 标准库包含一组丰富的修复程序,几乎可以处理 所有代码。然而,2to3支持库lib2to3是灵活的 通用库,因此可以为2to3编写自己的修复程序。 lib2to3也可以适用于Python中的自定义应用程序 代码需要自动编辑。
...
2to3也可以将所需的修改写回源 文件。 (当然,除非-n,否则也会备份原件 也给出了。)使用-w标志:
启用了更改$ 2to3 -w example.py
如果你想确定python版本,我建议:
PY2 = sys.version_info.major == 2
PY3 = sys.version_info.major == 3
# or
import six # Python 2 / 3 compatability module
six.PY2 # is this Python 2
six.PY3 # is this Python 3
不要忘记Python 2的早期版本将与2.7不同。我喜欢计划所有意外情况,因此如果使用2.7之前的Python版本,以下代码会出现异常(litteraly)。
# If you want to use and if/then/else block...
import sys
major = sys.version_info.major
minor = sys.version_info.minor
if major == 3: # Python 3 exception handling
print("Do something with Python {}.{} code.".format(major, minor))
elif major == 2: # Python 2 exception handling
if minor >= 7: # Python 2.7
print("Do something with Python {}.{} code.".format(major, minor))
else: # Python 2.6 and earlier exception handling
assert minor >= 2, "Please use Python 2.7 or later, not {}.{}.".format(major,minor)
else:
assert major >= 2, "Sorry, I'm not writing code for pre-version 2 Python. It just ain't happening. You are using Python {}.{}.".format(major,minor)
assert major > 3, "I can't handle Python versions that haven't been written yet.. You are using Python {}.{}.".format(major,minor)
python-future是Python 2和Python之间缺少的兼容层 Python 3.它允许您使用单个,干净的Python 3.x兼容 代码库以最小的开销支持Python 2和Python 3。
它提供带有后端口和前向端口的未来和过去的包 Python 3和2的功能。它还带有未来化和 巴氏杀菌,定制的基于2to3的脚本,可以帮助您进行转换 Py2或Py3代码很容易支持Python 2和3 单个干净的Py3风格的代码库,逐个模块。 http://python-future.org/overview.html
请参阅http://python-future.org/上的python未来模块文档。 以下是该页面的“提升异常和暗示例外”部分的副本。
import future # pip install future
import builtins # pip install future
import past # pip install future
import six # pip install six
raise ValueError, "dodgy value"
raise ValueError("dodgy value")
Raising exceptions with a traceback:
traceback = sys.exc_info()[2]
raise ValueError, "dodgy value", traceback
raise ValueError("dodgy value").with_traceback()
from six import reraise as raise_
# or
from future.utils import raise_
traceback = sys.exc_info()[2]
raise_(ValueError, "dodgy value", traceback)
from future.utils import raise_with_traceback
raise_with_traceback(ValueError("dodgy value"))
Exception chaining (PEP 3134):
class DatabaseError(Exception):
pass
class FileDatabase:
def __init__(self, filename):
try:
self.file = open(filename)
except IOError as exc:
raise DatabaseError('failed to open') from exc
from future.utils import raise_from
class FileDatabase:
def __init__(self, filename):
try:
self.file = open(filename)
except IOError as exc:
raise_from(DatabaseError('failed to open'), exc)
try:
fd = FileDatabase('non_existent_file.txt')
except Exception as e:
assert isinstance(e.__cause__, IOError) # FileNotFoundError on Py3.3+ inherits from IOError
try:
...
except ValueError, e:
...
try:
...
except ValueError as e:
...