星运营商是什么意思?
可能重复:
* args和** kwargs是什么意思?
*
运算符在Python中的含义是什么,比如像zip(*x)
或f(**k)
这样的代码?
- 翻译人员在内部如何处理?
- 它会影响性能吗? 是快还是慢?
- 什么时候有用,什么时候不是?
- 应该在函数声明还是在调用中使用?
单星*
将序列/集合解开成位置参数,所以你可以这样做:
def sum(a, b): return a + b values = (1, 2) s = sum(*values)
这将解压元组,使其实际执行如下:
s = sum(1, 2)
双星**
做同样的事情,只使用字典,因此命名参数:
values = { 'a': 1, 'b': 2 } s = sum(**values)
你也可以结合:
def sum(a, b, c, d): return a + b + c + d values1 = (1, 2) values2 = { 'c': 10, 'd': 15 } s = sum(*values1, **values2)
将执行为:
s = sum(1, 2, c=10, d=15)
另请参阅第4.7.4节 – Python文档的解包参数列表 。
此外,您可以定义函数以获取*x
和**y
参数,这允许函数接受任何数量的在声明中未具体指定的位置和/或命名参数。
例:
def sum(*values): s = 0 for v in values: s = s + v return s s = sum(1, 2, 3, 4, 5)
或与**
:
def get_a(**values): return values['a'] s = get_a(a=1, b=2) # returns 1
这可以让你指定大量的可选参数,而不必声明它们。
再次,你可以结合:
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
一个小点:这些不是运营商。 在expression式中使用运算符来从现有值创build新值(例如,1 + 2变为3)。这里的*和**是函数声明和调用语法的一部分。
它被称为扩展调用语法。 从文档 :
如果语法*expression式出现在函数调用中,则expression式必须计算为一个序列。 来自这个序列的元素被视为是额外的位置参数; 如果存在位置参数x1,…,xN,并且expression式计算为序列y1,…,yM,则这相当于具有M + N位置参数x1,…,xN,y1,…的调用。 ..,嗯。
和:
如果语法**expression式出现在函数调用中,则expression式必须求值为映射,其内容被视为附加关键字参数。 如果关键字出现在expression和explicit关键字参数中,则会引发TypeErrorexception。
我觉得这个特别有用,当你想“存储”一个函数调用。
例如,假设我有一些函数“add”的unit testing:
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
除了手动执行add(test [0],test [1])之外,没有其他方法可以调用add,这很丑陋。 而且,如果variables的数量是可变的,那么代码可能会变得很糟糕,所有你需要的if语句。
另一个有用的地方是定义Factory对象(为你创build对象的对象)。 假设你有一些类的工厂,使汽车对象和返回它们。 你可以让myFactory.make_car('red','bmw','335ix')创buildCar('red','bmw','335ix'),然后返回它。
def make_car(*args): return Car(*args)
当你想调用一个超类的构造函数时,这也很有用。
在函数调用中,单星将列表变成单独的参数(例如zip(x1,x2,x3)
如果x=[x1,x2,x3]
则zip(*x)
与zip(x1,x2,x3)
相同),并且双星将字典(例如f(**k)
与f(x=my_x, y=my_y)
如果k = {'x':my_x, 'y':my_y}
转换为单独的关键字参数。
在一个函数定义中,反过来也是这样:单星将任意数量的参数变成列表,而双重开始将任意数量的关键字variables转换成字典。 例如, def foo(*x)
意思是“foo带有任意数量的参数,它们可以通过列表x访问(即如果用户调用foo(1,2,3)
, x
将是[1,2,3]
)“和def bar(**k)
表示”bar采用任意数量的关键字参数,并且可以通过字典k访问(即如果用户调用bar(x=42, y=23)
, k
将是{'x': 42, 'y': 23}
)“。