What does the star operator mean?
在python中,
单星
1 2 3 4 5 6 | def sum(a, b): return a + b values = (1, 2) s = sum(*values) |
这将解包元组,使其实际执行为:
1 | s = sum(1, 2) |
双星
1 2 | values = { 'a': 1, 'b': 2 } s = sum(**values) |
您还可以组合:
1 2 3 4 5 6 | def sum(a, b, c, d): return a + b + c + d values1 = (1, 2) values2 = { 'c': 10, 'd': 15 } s = sum(*values1, **values2) |
执行方式:
1 | s = sum(1, 2, c=10, d=15) |
另请参见第4.7.4节-打开python文档的参数列表。
此外,还可以定义接受
例子:
1 2 3 4 5 6 7 | def sum(*values): s = 0 for v in values: s = s + v return s s = sum(1, 2, 3, 4, 5) |
或与
1 2 3 4 | def get_a(**values): return values['a'] s = get_a(a=1, b=2) # returns 1 |
这允许您指定大量可选参数,而不必声明它们。
同样,您可以组合:
1 2 3 4 5 6 7 8 9 10 11 12 | def sum(*values, **options): s = 0 for i in values: s = s + i if"neg" in options: if options["neg"]: s = -s return s s = sum(1, 2, 3, 4, 5) # returns 15 s = sum(1, 2, 3, 4, 5, neg=True) # returns -15 s = sum(1, 2, 3, 4, 5, neg=False) # returns 15 |
一个小问题:这些不是操作员。表达式中使用运算符从现有值(例如,1+2变为3)创建新值。这里的*和**是函数声明和调用语法的一部分。
我发现当你想"存储"一个函数调用时,这个特别有用。
例如,假设我对函数"add"进行了一些单元测试:
1 2 3 4 | def add(a, b): return a + b tests = { (1,4):5, (0, 0):0, (-1, 3):3 } for test, result in tests.items(): print 'test: adding', test, '==', result, '---', add(*test) == result |
除了手动执行诸如"添加"(测试[0],测试[1])之类的难看的操作之外,没有其他方法可以调用"添加"。此外,如果变量的数量是可变的,那么代码可能会变得非常难看,因为您需要所有的if语句。
另一个有用的地方是定义工厂对象(为您创建对象的对象)。假设您有一个类工厂,它生成汽车对象并返回它们。你可以这样做,使我的工厂。使汽车(‘红色’、‘宝马’、‘335ix’)创建汽车(‘红色’、‘宝马’、‘335ix’),然后返回它。
1 2 | def make_car(*args): return Car(*args) |
当您想调用超类的构造函数时,这也很有用。
它被称为扩展调用语法。从文档中:
If the syntax *expression appears in the function call, expression must evaluate to a sequence. Elements from this sequence are treated as if they were additional positional arguments; if there are positional arguments x1,..., xN, and expression evaluates to a sequence y1, ..., yM, this is equivalent to a call with M+N positional arguments x1, ..., xN, y1, ..., yM.
还有:
If the syntax **expression appears in the function call, expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments. In the case of a keyword appearing in both expression and as an explicit keyword argument, a TypeError exception is raised.
在函数调用中,如果
在函数定义中,它是相反的:单星将任意数量的参数变成一个列表,而双起始将任意数量的关键字参数变成一个字典。例如,