意外的Python打印行为

时间:2012-12-09 21:36:32

标签: python

刚遇到以下Pythonic行为,我无法理解:

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')时,将其作为第三个语句?

我没有找到任何关于此行为的引用,也不知道我如何才能使用Google。顺便说一句,我在这里使用Python 2.7.3。 Anyhoo,我在这里很困惑。

5 个答案:

答案 0 :(得分:6)

这不仅仅是print语句,而是函数调用。

print i, name, valuate(name)

打印i,然后打印name,然后调用打印65(和新行)的valuate,然后返回print语句继续打印返回值(和另一个换行符。)

答案 1 :(得分:4)

事件顺序如下:

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       

我不知道这个评估顺序是否有保证(快速搜索没有透露任何内容)。我绝对不会依赖它,因此不会编写这样的代码。

答案 2 :(得分:3)

这很简单。您的print语句懒惰地评估参数。它首先打印我,然后命名,然后它调用valuate。 Valuate打印65.然后您的print语句打印出评估结果。

答案 3 :(得分:2)

您遇到的惊喜是print statement在评估下一个表达式之前打印出它所给出的每个表达式。也就是说,像print A, B, C这样的陈述相当于:

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

正如您对单独的陈述所期望的那样,在评估B或C之前,A会被写出来。

这个惊喜可能是Python 3取消print语句而支持内置print函数的原因之一,该函数的行为更像您期望的(它的所有参数都在之前评估过)该功能运行。)

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

from __future__ import print_function

答案 4 :(得分:0)

我认为一个小','会让事情变得更容易掌握。

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

现在输出:

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

print之后的逗号不会在结尾处打印新的换行符。所以现在您可以看到valuate首先打印ord('A'),然后返回外部打印的输出。 (我还缩进了i += 1行)