在函数调用中 **(双星号)和 *(星号)是什么意思?
- 2024-11-20 08:43:00
- admin 原创
- 9
问题描述:
zip(*x)
在或这样的代码中,和分别f(**k)
是什么意思? Python 如何实现该行为?性能影响是什么?*
`**`
另请参阅:将元组扩展为参数。请使用该选项关闭 OP 需要*
在参数上使用但不知道其存在的问题。类似地,对于使用的情况,请使用将 Python 字典转换为 kwargs?。**
有关参数的补充问题,请参阅*(双星号)和 (星号)对参数有何作用?
解决方案 1:
单个星号*
将序列或集合解包为位置参数。假设我们有
def add(a, b):
return a + b
values = (1, 2)
使用*
解包运算符,我们可以写s = add(*values)
,这相当于写s = add(1, 2)
。
双星号**
对字典起着同样的作用,为命名参数提供值:
values = {'a': 1, 'b': 2}
s = add(**values) # equivalent to add(a=1, b=2)
两个运算符都可以用于同一个函数调用。例如,给定:
def sum(a, b, c, d):
return a + b + c + d
values1 = (1, 2)
values2 = {'c': 10, 'd': 15}
则s = add(*values1, **values2)
相当于s = sum(1, 2, c=10, d=15)
。
另请参阅Python 文档中本教程的相关部分。
类似地,*
和**
可用于参数。使用*
允许函数接受任意数量的位置参数,这些参数将被收集到单个参数中:
def add(*values):
s = 0
for v in values:
s = s + v
return s
现在,当像 这样的函数被调用时s = add(1, 2, 3, 4, 5)
,values
将是元组(1, 2, 3, 4, 5)
(当然,它会产生结果15
)。
类似地,标有 的参数**
将收到dict
:
def get_a(**values):
return values['a']
s = get_a(a=1, b=2) # returns 1
这允许指定大量可选参数而无需声明它们。
同样,两者可以结合起来:
def add(*values, **options):
s = 0
for i in values:
s = s + i
if "neg" in options:
if options["neg"]:
s = -s
return s
s = add(1, 2, 3, 4, 5) # returns 15
s = add(1, 2, 3, 4, 5, neg=True) # returns -15
s = add(1, 2, 3, 4, 5, neg=False) # returns 15
解决方案 2:
在函数调用中,单星号将列表转换为单独的参数(例如与给定zip(*x)
的相同),双星号将字典转换为单独的关键字参数(例如与给定的相同)。zip(x1, x2, x3)
`x=[x1,x2,x3]f(**k)
f(x=my_x, y=my_y)`k = {'x':my_x, 'y':my_y}
在函数定义中,情况正好相反:单星号将任意数量的参数转换为列表,双星号将任意数量的关键字参数转换为字典。例如,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}
)”。
解决方案 3:
我发现这对于存储函数调用的参数特别有用。
例如,假设我对函数“add”有一些单元测试:
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 add(test[0], test[1])
。此外,如果变量数量可变,代码可能会变得非常丑陋,因为您需要所有 if 语句。
另一个有用的地方是定义 Factory 对象(为您创建对象的对象)。假设您有一个 Factory 类,它创建 Car 对象并返回它们。您可以让它myFactory.make_car('red', 'bmw', '335ix')
创建Car('red', 'bmw', '335ix')
,然后返回它。
def make_car(*args):
return Car(*args)
当你想要调用超类的构造函数时这也很有用。
解决方案 4:
这被称为扩展调用语法。摘自文档:
如果语法 *expression 出现在函数调用中,expression 必须求值为一个序列。该序列中的元素被视为附加位置参数;如果有位置参数 x1,..., xN,并且 expression 求值为序列 y1, ..., yM,则这相当于具有 M+N 个位置参数 x1, ..., xN, y1, ..., yM 的调用。
和:
如果语法 **expression 出现在函数调用中,则 expression 必须求值为映射,其内容将被视为附加关键字参数。如果关键字同时出现在 expression 中和作为显式关键字参数,则会引发 TypeError 异常。
解决方案 5:
在定义可能包含多个具有相同值的键的字典时,它也很有用。例如,
d = {'a':'r1', 'b':'r1','c':'r1','d':'r2'}
可以写成,
d = {**dict.fromkeys(['a','b','c'],'r1'),'d':'r2'}
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件