语法误差仅在Python 3中



我有以下代码,该代码在python 2上运行良好,但在python 3

上丢弃了错误
import sys
if sys.version_info > (3,):
  #print("Python 3")
  #Try Block
  except urllib2.HTTPError as err:
else:
  #print "Python 2"  # Throws error on python 3
  #Try Block
  except urllib2.HTTPError, err: # Throws error on python 3.

上面的代码返回Python 2中的" Python 2",但在Python 3上丢弃语法错误(对于Python 2语法(。

谁能告诉我为什么会发生这种情况?在Python 3中解决这些语法错误的工作是什么?

注意:我知道Python上的打印语法3

谢谢!

问题是 parser 在运行时评估任何代码之前运行。您的检查sys.version_info > (3,)在已经解析和编译后,在运行时运行。因此,进行此类检查,您可以在运行时进行更改,但是在处理语法更改时,这对您无济于事。

在解释任何代码之前,语法是对语法进行解析和编译的,这就是为什么即使在运行时从未运行的代码也会获得语法错误。

如果您试图创建一个能够在Python 3和Python 2上运行的polyglot脚本,那么您将需要确保使用两者都可以使用的语法。特别是对于print,您可以在Python 2中导入打印功能,因此您可以像在Python 3中一样使用它:

from __future__ import print_function

一些较新的功能不会这种方式(例如所有异步(,但是在大多数情况下,您可以使其有效。

如果您最终取决于需要Python 3的内容,该内容需要Python 2不兼容的语法,则可以将其放入单独的模块中,并在运行时条件地导入该模块。这样,它不会为Python 2加载,因此Python 2解析器不会尝试加载不兼容的语法。


至于为什么python 2没有丢失错误,这实际上很简单:即使使用print 语句print('foo bar')也是Python 2中的有效语法。那是因为您可以将括号围绕在任何物体上,而不会影响价值。因此,您实际做的是:

print ('foo bar')
^^^^^
print statement
      ^^^^^^^^^^^
      value, wrapped in parentheses (that don’t do anything)

这也是原因,为什么以下在Python 3和2中产生不同的结果:

print('foo', 'bar')

在Python 3中,您将foo bar作为输出,而Python 2为您提供('foo', 'bar')。那是因为括号内的逗号现在使它成为元组,因此您将元组传递给print语句。 - 导入打印功能可以解决此问题,以使您在Python 2上与Python 3。

相同

即使行print "Python 2"永远不会在python 3中执行,但它仍然会被编译为 compine byte代码(或至少至少尝试(。该行是python 3中的语法错误,它要求印刷项目在括号中。查找文档以获取更多详细信息:还进行了print的其他更改。

因此,请删除错误。做线

print("Python 2")  # Throws error on python 3

而是。这样,它在Python 2和3中都可以使用。有许多站点讨论如何编写在Python的两个版本中执行的代码。括号仅在版本2中忽略,但在版本3中需要忽略。如果您只打印一个项目,则可以使用:多个都变得更加复杂。

使用from __future__ import print_function在两个版本中都有另一种打印的方法,但是我显示的方式更容易。

请注意,您在行中尝试的评论也不是适当的python语法。将//更改为#,并且可以工作。

最新更新