Python中的星号实际上只是标准的乘法运算符*.它映射到它所操作的对象的
__mul__方法,因此可以重载以具有自定义含义.这与if或print无关.
在字符串(str和unicode)的情况下,它已被重载/重写以表示重复字符串,使得“foo”* 5评估为“foofoofoofoofoo”.
>>> 'foo' * 5 # and the other way around 5 * "foo" also works
'foofoofoofoofoo'
而“Fizz”*(i%3 == 0)只是一个“聪明”的简写:
"Fizz" if i % 3 == 0 else ""
这是因为表达式i%3 == 0计算为布尔值,而布尔值是Python中整数的子类型,因此True == 1和False == 0,因此如果将“字符串”与“布尔”“相乘” ,你要么得到相同的字符串或空字符串.
注意:我还要注意,根据我的经验/理解,Python中不鼓励这种类型的编程风格 – 它使代码的可读性降低(对于新手和老朋友而言)并且不会更快(并且在事实上,可能更慢;请参阅http://pastebin.com/Q92j8qga以获得快速基准(但有趣的是,不是在PyPy:http://pastebin.com/sJtZ6uDm中)).
并且*也适用于列表和元组的实例:
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> (1, 2, 3) * 3
(1, 2, 3, 1, 2, 3, 1, 2, 3)
class Foo(object):
def __mul__(self, other):
return "called %r with %r" % (self, other)
print Foo() * "hello" # same as Foo().__mul__("hello")
输出:
called <__main__.Foo object at 0x10426f090> with 'hello'
*被映射到__mul__的情况也适用于“原始”类型,例如int,float等,因此3 * 4相当于(3).__ mul __(4)(和其他运算符相同).实际上,您甚至可以为int子类化并为*提供自定义行为:
class MyTrickyInt(int):
def __mul__(self, other):
return int.__mul__(self, other) - 1
def __add__(self, other):
return int.__add__(self, other) * -1
print MyTrickInt(3) * 4 # prints 11
print MyTrickyInt(3) + 2 # prints -5
…但请不要这样做:)(事实上,完全保持子类化混凝土类型的干净并没有伤害!)