为什么Python3代码在Python2上运行?
我创建了一个小的购物清单程序,设计用于在Python3上运行。我假设我的Mac电脑运行的是Python 3,并试图运行该文件。只要我用引号将输入字符串括起来,它似乎工作得很好,否则就会出现NameError。这在Python3中是不需要的 为什么代码会运行?我知道像print()这样的函数在Python2中的编写方式不同,所以为什么它一开始就没有失败呢为什么Python3代码在Python2上运行?,python,python-3.x,Python,Python 3.x,我创建了一个小的购物清单程序,设计用于在Python3上运行。我假设我的Mac电脑运行的是Python 3,并试图运行该文件。只要我用引号将输入字符串括起来,它似乎工作得很好,否则就会出现NameError。这在Python3中是不需要的 为什么代码会运行?我知道像print()这样的函数在Python2中的编写方式不同,所以为什么它一开始就没有失败呢 #列表创建 购物清单=[] #帮助 def show_help(): 打印(“”) 在提示时将项目添加到列表中。 要结束列表,请键入“完成”。
#列表创建
购物清单=[]
#帮助
def show_help():
打印(“”)
在提示时将项目添加到列表中。
要结束列表,请键入“完成”。
要查看列表,请键入“SHOW”。
要查看此帮助提示,请键入“帮助”。
""")
显示帮助()
#看法
def view_list():
打印(购物清单)
尽管如此:
新项目=输入(“>”)
如果new_item.upper()=“完成”:
打破
elif new_item.upper()=“帮助”:
显示帮助()
持续
elif new_item.upper()=“显示”:
查看列表()
持续
购物清单。附加(新项目)
打印(购物清单)
关于打印
,Python3使其成为一个合适的函数,因此您必须用括号调用它。在Python2中,这些括号被解释为“分组”括号,而不是函数调用的开始,因此没有区别
Python2:print(1+2)
表示对表达式进行求值(1+2)
->print 3
Python3:
print(1+2)
意味着计算表达式1+2
,并将结果传递到函数print
->print(3)
您没有利用Python3的改进
因此,它可以在Python 2中运行(除了打印),因为它是完全有效的Python 2代码。但是,Python2中的
input
尝试对作为Python表达式输入的字符串求值;Python3中的等价物是eval(输入(“>”)
。Python2应该始终使用raw\u输入
,Python3通过摆脱旧的input
行为并将raw\u输入
重命名为input
来实现这一点
对于print
,关键字print
后面的每个项目都是一个表达式,有效的表达式可以用括号括起来print('hello')
只打印表达式('hello')
的结果,该结果相当于未加密的字符串'hello'
;因此,print('hello')
和print'hello'
是等效的
请注意,
print'hello'、
和print'hello'、
并不等同;前者打印字符串hello
,不带行尾,而后者打印单元素元组(hello,)
。在Python3中,print('hello',)
和print('hello')
是相同的,因为函数调用的参数列表允许有一个被忽略的尾随逗号。许多Python3代码在Python2中运行,因为Python是专门为实现这一点而设计的
print
是一种特殊情况,简单的print
s单个变量在两种语言中做相同的事情,但更复杂的print
s可能不会。这是怎么回事
在Python3中,print(shopping\u list)
是对print
函数的调用,该函数只有一个参数,shopping\u list
在Python 2中,print(shopping\u list)
是一个带有一个可打印值的print语句,(shopping\u list)
,该值当然与shopping\u list
的值相同。所以你得到了同样的结果
当然,当您print(x,y)
(这很有效,但在Python2中打印一个2元组值而不是两个值)或print(x,file=sys.stderr)
(这在Python2中是一个错误)时,情况就不是这样了
input
是另一种特殊情况。这一个不是为了兼容而设计的,你只是在这里走运而已。或者可能不走运
在Python 2中,input()
执行eval(raw\u input())
——也就是说,它接受您键入的内容并尝试将其作为Python源代码进行评估
在Python3中,input()
执行Python2中的raw\u input()
操作,也就是说,它只返回一个字符串
因此,代码在这两种情况下都能工作,尽管您必须在Python 2中键入“DONE”
,而不是仅仅键入DONE
——就像您必须在源代码中键入“DONE”
。另外,当然,您可以在Python2中键入\uuuuu import\uuuuu('os').system('rm-rf/')
,这会让您感到非常难过。(这就是为什么Python2的输入在Python3中不存在的原因。)
如果您想知道为什么Python 3是这样设计的:
一旦确定需要一些向后的不兼容来修复20年的积压问题,就有一个讨论,关于“Python 3000”是否应该故意不兼容以大声破坏一切,或者尽可能兼容(但不再如此)以使迁移更容易
小组决定采用后者。这包括对Python2.6进行一些更改,使其更容易最终迁移到3.x,以及在Python3.0中做出一些设计决策,这些决策只是为了使从2.6迁移更容易
一旦Python3进入野外,这就是正确的选择。几乎所有人都感到惊讶的是,实际上编写“双版本”代码(借助于适配器库,如six
)比编写可以通过2to3
和3to2
自动转换的代码更容易
所以他们走得更远。Python2.7添加了一些专为双版本代码设计的特性,并且他们继续添加类似于u
string literal前缀的内容(在Python3中它不起任何作用,但它是一种确保无论在2.7还是3.4中运行都有Unicode字符串的方法)和