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))。
并且* 也适用于list 和tuple 的实例:
>>> [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)
您还可以为您的类型定义自己的* 运算符,使用相当于operator overloading in Python:
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
...但请不要那样做 :)(事实上,完全避免子类化具体类型并没有什么坏处!)