[英]Python - curious/unexpected behaviour - precedence of operators
我最近一直在尝试使用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
输出:
a squared is 1
a squared is 2a squared is 2
与下面的脚本生成预期的输出:
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
这与生成器无关:
>>> 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'
%
op在乘法之前执行,使用字符串和第一个a
作为参数。 您的a**2
之所以有效,是因为带有a
和2
作为参数的**
op在%
之前被求值。
除了适用PEMDAS之外, Python的操作顺序是从左至右。 字符串插值运算符显然具有与取模和乘法相同的优先级,因为如果您颠倒顺序,使插值剩下的乘法就优先于:
>>> 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
但是,正如您所展示的,幂运算从左到右顺序胜过。
更新:在二进制算术运算下的同一文档中,它声明了一些明显地但有意义的内容:
…%运算符还被字符串和unicode对象重载以执行字符串格式化(也称为插值)。
尽管这似乎只是在告诉您%
运算符的功能 ,但我认为它的位置和上下文还可以告诉您它是用作模还是插值的优先级相同。
当您观察到意外行为时,请通过将其提炼为最简单的情况来开始分析。 一个简单的案例将更易于研究和理解。
意外的行为:
>>> 'hello %s' % 3 * 2
'hello 3hello 3'
(您预期为'hello 6'
)
我们认为Python必须将命令解释为'hello 3' * 2
而不是'hello %d' % 6
。 我们尝试使用方括号来强制进行第二种解释
>>> "hello %s" % (3*2)
'hello 6'
尤里卡!
我们已经证明了字符串格式化运算符%
优先级大于或等于乘法。 我们检查了Python文档-是的,它确认了此http://docs.python.org/reference/expressions.html#summary
为了确认优先顺序是否相等,我们可以用另一种方法尝试:
>>> "%d,"*2%(1,2)
'1,2,'
看到逗号(,)被复制,我们认为乘法"%d," * 2
是在格式化字符串%
之前执行的。 如果乘法可以在字符串格式之前进行,并且字符串格式在乘法之前进行,则它们的优先级必须相等。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.