意外的 Python 打印行为

问题描述 投票:0回答:5

刚刚遇到了以下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。无论如何,我在这里很困惑。

python python-2.x
5个回答
6
投票

这不仅仅是

print
语句,它是函数调用。

print i, name, valuate(name)

打印

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


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       

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


3
投票

非常简单。您的 print 语句会延迟计算参数。它首先打印 i,然后打印 name,然后调用 value。评估打印 65。然后你的打印语句打印评估的结果。


2
投票

您遇到的惊喜是,

print
语句会在计算下一个表达式之前打印出给出的每个表达式。也就是说,像
print A, B, C
这样的语句相当于:

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

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

这个惊喜也许是 Python 3 取消了

print
语句而采用内置
print
函数的部分原因,该函数的行为更像您所期望的(它的所有参数都会在函数运行之前评估)。

在 Python 2 中,如果您想使用

print
导入,您可以获得 Python 3 风格
future

from __future__ import print_function

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
行)

© www.soinside.com 2019 - 2024. All rights reserved.