spe*_*ndo 8 python exception python-2.x python-3.x
如何将这段代码移植到Python 3,以便它可以同时在Python 2和Python3中运行?
raise BarException, BarException(e), sys.exc_info()[2]
Run Code Online (Sandbox Code Playgroud)
(从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")
Run Code Online (Sandbox Code Playgroud)
您必须诉诸使用,exec()
因为您无法在Python 3中使用3参数语法。它将引发语法错误。
像往常一样,该six
库已经涵盖了您,移植为不依赖于其他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")
Run Code Online (Sandbox Code Playgroud)
现在您可以使用:
reraise(BarException, BarException(e), sys.exc_info()[2])
Run Code Online (Sandbox Code Playgroud)
无需进一步测试Python版本。
六个提供了用于包装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)
Run Code Online (Sandbox Code Playgroud)
您可以使用2to3制作代码的Python 3副本。
2to3是一个Python程序,可读取Python 2.x源代码并应用一系列修复程序将其转换为有效的Python 3.x代码。标准库包含一组丰富的修复程序,可以处理几乎所有代码。2to3支持库lib2to3是一个灵活而通用的库,因此可以为2to3编写自己的修复程序。lib2to3也可以适用于需要自动编辑Python代码的自定义应用程序。
...
2to3还可以将所需的修改直接写回到源文件。(当然,除非提供了-n,否则也将备份原始文件。)使用-w标志启用回写更改:
Run Code Online (Sandbox Code Playgroud)$ 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
Run Code Online (Sandbox Code Playgroud)
别忘了Python 2的早期版本会从2.7开始变化。我喜欢为所有突发事件做好计划,因此,如果使用的是2.7之前的Python版本,则以下代码(偶尔会)出错。
# 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)
Run Code Online (Sandbox Code Playgroud)
python-future是Python 2和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
Run Code Online (Sandbox Code Playgroud)
raise ValueError, "dodgy value"
Run Code Online (Sandbox Code Playgroud)
raise ValueError("dodgy value")
Raising exceptions with a traceback:
Run Code Online (Sandbox Code Playgroud)
traceback = sys.exc_info()[2]
raise ValueError, "dodgy value", traceback
Run Code Online (Sandbox Code Playgroud)
raise ValueError("dodgy value").with_traceback()
Run Code Online (Sandbox Code Playgroud)
from six import reraise as raise_
# or
from future.utils import raise_
traceback = sys.exc_info()[2]
raise_(ValueError, "dodgy value", traceback)
Run Code Online (Sandbox Code Playgroud)
from future.utils import raise_with_traceback
raise_with_traceback(ValueError("dodgy value"))
Exception chaining (PEP 3134):
Run Code Online (Sandbox Code Playgroud)
class DatabaseError(Exception):
pass
Run Code Online (Sandbox Code Playgroud)
class FileDatabase:
def __init__(self, filename):
try:
self.file = open(filename)
except IOError as exc:
raise DatabaseError('failed to open') from exc
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
try:
fd = FileDatabase('non_existent_file.txt')
except Exception as e:
assert isinstance(e.__cause__, IOError) # FileNotFoundError on Py3.3+ inherits from IOError
Run Code Online (Sandbox Code Playgroud)
try:
...
except ValueError, e:
...
Run Code Online (Sandbox Code Playgroud)
try:
...
except ValueError as e:
...
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
6137 次 |
最近记录: |