意外的Python打印行为

2024-10-16 20:46:29 发布

您现在位置:Python中文网/ 问答频道 /正文

刚刚遇到了以下我无法理解的Python行为:

names = ["Paul", "Mary", "Susan"]
names.sort()

def valuate(string):
    print ord('A')
    return sum(ord(s) for s in string)

i = 1
for name in names:
    print i, name, valuate(name)
    i += 1

我希望输出:

65
1 Mary 409
65
2 Paul 402
65
3 Susan 522

但相反,输出:

1 Mary 65
409
2 Paul 65
402
3 Susan 65
522

print语句似乎已经尝试输出3个元素,当调用print ord('A')时,是否将其作为第三个语句?你知道吗

我没有找到任何关于这种行为的参考资料,也不知道如何在谷歌上搜索。顺便说一下,我在这里使用的是Python2.7.3。喂,我搞糊涂了。你知道吗


Tags: nameinforstringreturnnamesdef语句
3条回答

令人惊讶的是,^{} statement会在计算下一个表达式之前打印出它给出的每个表达式。也就是说,像print A, B, C这样的语句等价于:

print A, # note, the trailing comma suppresses the newline
print B,
print C

正如您从单独的语句中所期望的,在计算B或C之前,先写出A。你知道吗

这可能是python3放弃了print语句而支持一个行为更像您期望的内置print函数的部分原因(在函数运行之前对其所有参数进行求值)。你知道吗

在Python 2中,如果希望使用future导入,可以获得Python 3样式print

from __future__ import print_function

事件顺序如下:

print i,
print name,
val = valuate(name) # prints ord('A')
print val

通过查看为print i, name, valuate(name)生成的字节码可以证实这一点:

 11          19 LOAD_FAST                0 (i)
             22 PRINT_ITEM          
             23 LOAD_FAST                1 (name)
             26 PRINT_ITEM          
             27 LOAD_GLOBAL              1 (valuate)
             30 LOAD_FAST                1 (name)
             33 CALL_FUNCTION            1
             36 PRINT_ITEM          
             37 PRINT_NEWLINE       

我不知道这个评估顺序是否有保证(快速搜索没有发现任何东西)。我绝对不会依赖它,因此也不会编写这样的代码。你知道吗

它不仅仅是print语句,而是函数调用。你知道吗

print i, name, valuate(name)

打印i,然后name,然后调用valuate,打印65(和一个新行),然后在返回时print语句继续打印返回值(和另一个新行)。你知道吗

相关问题 更多 >