1

刚刚遇到了以下我无法理解的 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') 时,是否将其作为第三条语句?

我没有找到对这种行为的任何引用,也不知道如何在谷歌上搜索它。顺便说一句,我在这里使用 Python 2.7.3。Anyhoo,我在这里很困惑。

4

5 回答 5

6

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

print i, name, valuate(name)

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

于 2012-12-09T21:41:43.920 回答
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       

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

于 2012-12-09T21:42:39.400 回答
3

这很简单。您的 print 语句懒惰地评估参数。它首先打印 i,然后是 name,然后调用 valuate。评估打印 65。然后您的打印语句打印评估的结果。

于 2012-12-09T21:41:45.947 回答
2

您遇到的惊喜是该print语句会在计算下一个表达式之前打印出它给出的每个表达式。也就是说,类似的语句print A, B, C等同于:

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

正如您对单独的语句所期望的那样,在评估 B 或 C 之前写出 A。

这个惊喜可能是 Python 3 取消了print支持内置print函数的声明的部分原因,该函数的行为更像您的预期(它的所有参数都在函数运行之前进行评估)。

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

from __future__ import print_function
于 2012-12-09T21:53:26.257 回答
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行)

于 2012-12-09T21:47:26.177 回答