Python奇怪/意外的行为运算符优先级

2024-05-08 22:03:24 发布

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

我最近对python生成器进行了一些实验,我遇到了以下奇怪的行为,我很想知道为什么会发生这种情况,以及发生了什么情况:

def generating_test(n): 
    for a in range(n): 
        yield "a squared is %s" % a*a # Notice instead of a**2 we have written a*a

for asquare in generating_test(3): 
    print asquare 

输出:

^{pr2}$

与生成预期输出的以下脚本相比:

def generating_test(n): 
    for a in range(n): 
        yield "a squared is %s" % a**2 # we use the correct a**2 here

for asquare in generating_test(3): 
    print asquare 

输出:

a squared is 0
a squared is 1
a squared is 4

Tags: intestforisdef情况rangenotice
3条回答

这和发电机没有关系:

>>> a = 2
>>> "a squared is %s" % a
'a squared is 2'
>>> ("a squared is %s" % a)*a
'a squared is 2a squared is 2'
>>> "a squared is %s" % a*a
'a squared is 2a squared is 2'
>>> "a squared is %s" % (a*a)
'a squared is 4'

在乘法之前执行%操作,使用字符串和第一个a作为参数。您的a**2起作用是因为**操作以a和{}作为参数,在%之前计算。在

Python's order of operations是从左到右,除非PEMDAS适用。字符串插值运算符显然与模和乘法具有相同的优先级,因为如果您颠倒顺序,使乘法位于插值的左侧,则它优先:

>>> print 3 * "a foo %s" % 'hi'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string
>>> print 3 * "a foo %s" % ('hi', 'ho', 'yo')
a foo hia foo hoa foo yo

然而,正如您所演示的,求幂运算胜过从左到右的顺序。在

更新:在这个same document under Binary Arithmetic Operations中,它陈述了一些表面上明显,但隐含相关的东西:

…the % operator is also overloaded by string and unicode objects to perform string formatting (also known as interpolation).

虽然这似乎只是告诉你%运算符做了什么,但我认为它的位置和上下文也告诉你,无论它是用作还是插值都具有相同的优先级。在

当你观察到意想不到的行为时,开始你的分析,把它提炼成最简单的情况。一个简单的案例更容易研究和理解。在

意外行为:

>>> 'hello %s' % 3 * 2
'hello 3hello 3'

(您期望'hello 6'


我们认为Python必须将命令解释为'hello 3' * 2,而不是{}。我们试着用括号强迫第二种解释

^{pr2}$

尤里卡!在

我们已经证明了字符串格式化运算符%的优先级高于或等于乘法。我们检查Python文档-是的,它确认了http://docs.python.org/reference/expressions.html#summary

为了确认优先级相等,我们可以用另一种方法:

>>> "%d,"*2%(1,2)
'1,2,'

由于逗号(,)是重复的,我们推断乘法"%d," * 2是在字符串格式化%之前执行的。如果乘法可以先于字符串格式,而字符串格式先于乘法,则它们的优先级必须相等。在

相关问题 更多 >