我创建了一个小型购物清单程序,旨在在Python 3上运行。我假设我的Mac运行Python 3并尝试运行该文件。只要我用输入标记包围输入字符串,它似乎运行良好,否则我得到一个NameError。 Python 3中不需要这样做。
为什么代码会运行?我知道print()这样的函数在Python 2中的编写方式不同,为什么它从一开始就没有失败呢?
# List Creation
shopping_list = []
# Help
def show_help():
print("""
Add items to the list when promted.
To end the list type 'DONE'.
To view the list type 'SHOW'.
To view this help prompt, type 'HELP'.
""")
show_help()
# View
def view_list():
print(shopping_list)
while True:
new_item = input("> ")
if new_item.upper() == 'DONE':
break
elif new_item.upper() == 'HELP':
show_help()
continue
elif new_item.upper() == 'SHOW':
view_list()
continue
shopping_list.append(new_item)
print(shopping_list)
答案 0 :(得分:4)
许多Python 3代码在Python 2中运行,因为Python专门设计用于实现这一点。
print
有点特殊情况 - 单个变量的简单print
在两种语言中都做同样的事情,但更复杂的print
可能不会。这是如何工作的?
在Python 3中,print(shopping_list)
是使用单个参数print
调用shopping_list
函数。
在Python 2中,print(shopping_list)
是一个打印语句,其中一个可打印,值为(shopping_list)
,当然与shopping_list
的值相同。所以你得到同样的东西。
当你print(x, y)
(有效,但在Python 2中打印单个2元组值而不是两个值)或print(x, file=sys.stderr)
时(这是一个错误),这当然不是真的在Python 2)。
input
是另一个特例。这个不是为了兼容,你在这里很幸运。或者也许不走运。
在Python 2中,input()
执行eval(raw_input())
- 也就是说,它会输入您输入的内容,并尝试将其作为Python源进行评估。
在Python 3中,input()
执行raw_input()
在Python 2中所做的事情 - 也就是说,它只返回一个字符串。
因此,虽然您必须在Python 2中键入"DONE"
而不仅仅是DONE
,但代码类似于两者,就像您必须在源代码中键入"DONE"
一样。另外,当然,您可以在Python 2中键入__import__('os').system('rm -rf /')
并让自己非常难过。 (这就是Python 3中不存在Python 2的input
。)
如果你问为什么Python 3是这样设计的:
一旦确定需要一些向后不兼容性来解决二十年的积压问题,就会讨论“Python 3000”是否应该故意不相容而吵闹一切,或尽可能兼容(但不是更多)使迁移变得更容易。
团队决定采用后者。这包括对Python 2.6进行一些更改,以便最终更容易迁移到3.x,以及Python 3.0中的一些设计决策,这些决策只能使从2.6迁移变得更容易。
一旦Python 3进入野外,结果证明这是正确的选择。几乎每个人都感到惊讶的是,编写“双版”代码(借助于six
等适配器库)实际上比编写可以通过2to3
和{{自动转换的代码编写代码更容易1}}。
所以他们走得更远了。 Python 2.7添加了一些专为双版本代码设计的功能,并且他们继续添加诸如3to2
字符串文字前缀(在Python 3中什么都不做,但它确保你有Unicode的方法)。字符串,无论你运行在2.7或3.4)和u
(允许Python 2 bytes.__mod__
- 格式化代码继续在Python 3中工作,如果你故意选择保留{{1 - 例如,解析HTTP,你所知道的是它是一些与ASCII兼容的字符集,直到你到达%
标题。)
顺便说一句,对Python 2进行的“向前兼容性”更改之一是bytes
的添加,它为您提供了Python 3风格的charset
。
答案 1 :(得分:1)
关于print
,Python3使它成为一个正确的函数,所以你必须用括号调用它。在Python2中,这些括号被解释为"分组"括号而不是函数调用的开始,所以没有区别。
Python2:print (1 + 2)
表示,评估表达式(1 + 2)
- > print 3
Python3:print (1 + 2)
表示评估表达式1 + 2
并将结果传递给函数print
- > print(3)
答案 2 :(得分:1)
它运行是因为它是完全有效的Python 2代码。但是,Python 2中的input
尝试计算作为Python表达式输入的字符串; Python 3中的等价物是eval(input("> "))
。 Python 2应始终使用raw_input
,Python 3通过删除旧的input
行为并将raw_input
重命名为input
来强制执行此操作。
至于print
,print
关键字后面的每个项都是一个表达式,有效的表达式可以用括号括起来。 print('hello')
只打印表达式('hello')
的结果,该结果等同于未加括号的字符串'hello'
;因此,print('hello')
和print 'hello'
是等效的。
但请注意,print 'hello',
和print('hello',)
不等同于此;前者打印字符串hello
没有行结束,而后者打印单元素元组(hello,)
。在Python 3中,print('hello',)
和print('hello')
将是相同的,因为允许函数调用的参数列表具有被忽略的尾随逗号。
答案 3 :(得分:-3)
您没有利用Python 3的改进。
因此它在Python 2中起作用(除了打印)