当前位置:  开发笔记 > 编程语言 > 正文

Python 2.x和3.x中的有效语法是否引发异常?

如何解决《Python2.x和3.x中的有效语法是否引发异常?》经验,为你挑选了2个好方法。

如何将这段代码移植到Python 3,以便它可以同时在Python 2和Python3中运行?

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")

Martijn Piet.. 9

您必须诉诸使用,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")

现在您可以使用:

reraise(BarException, BarException(e), sys.exc_info()[2])

无需进一步测试Python版本。



1> Martijn Piet..:

您必须诉诸使用,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")

现在您可以使用:

reraise(BarException, BarException(e), sys.exc_info()[2])

无需进一步测试Python版本。



2> cadvena..:
Python 2/3兼容代码引发异常

六个提供了用于包装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)
从Python 2转换为Python 3。

您可以使用2to3制作代码的Python 3副本。

2to3是一个Python程序,可读取Python 2.x源代码并应用一系列修复程序将其转换为有效的Python 3.x代码。标准库包含一组丰富的修复程序,可以处理几乎所有代码。2to3支持库lib2to3是一个灵活而通用的库,因此可以为2to3编写自己的修复程序。lib2to3也可以适用于需要自动编辑Python代码的自定义应用程序。

...

2to3还可以将所需的修改直接写回到源文件。(当然,除非提供了-n,否则也将备份原始文件。)使用-w标志启用回写更改:

$ 2to3 -w example.py

(来自https://docs.python.org/3.0/library/2to3.html)

Python版本确定

如果要确定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决策

别忘了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)
Python 2和3中的异常处理

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

仅限Python 2:

raise ValueError, "dodgy value"

Python 2和3:

raise ValueError("dodgy value")
Raising exceptions with a traceback:

仅限Python 2:

traceback = sys.exc_info()[2]
raise ValueError, "dodgy value", traceback

仅限Python 3:

raise ValueError("dodgy value").with_traceback()

Python 2和3:选项1

from six import reraise as raise_
# or
from future.utils import raise_

traceback = sys.exc_info()[2]
raise_(ValueError, "dodgy value", traceback)

Python 2和3:选项2

from future.utils import raise_with_traceback

raise_with_traceback(ValueError("dodgy value"))
Exception chaining (PEP 3134):

设定:

class DatabaseError(Exception):
    pass

仅Python 3

class FileDatabase:
    def __init__(self, filename):
        try:
            self.file = open(filename)
        except IOError as exc:
            raise DatabaseError('failed to open') from exc

Python 2和3:

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

捕捉异常

仅限Python 2:

try:
    ...
except ValueError, e:
    ...

Python 2和3:

try:
    ...
except ValueError as e:
    ...

推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有