带星号参数和不带星号参数的差异调用函数
Difference call function with asterisk parameter and without
我知道 Python 中函数定义中星号的含义。
不过,我经常看到星号表示调用带有以下参数的函数:
def foo(*args, **kwargs):
first_func(args, kwargs)
second_func(*args, **kwargs)
第一次和第二次函数调用有什么区别?
不同之处在于如何将参数传递给被调用的函数。当您使用 *
时,参数被解包(如果它们是列表或元组)——否则,它们将按原样简单地传递。
这是一个差异示例:
>>> def add(a, b):
... print a + b
...
>>> add(*[2,3])
5
>>> add([2,3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (1 given)
>>> add(4, 5)
9
当我在参数前面加上 *
前缀时,它实际上将列表解压缩为两个单独的参数,它们作为 a
和 b
传递给 add
。没有它,它只是作为一个参数传入列表。
字典和 **
的情况相同,只是它们作为命名参数而不是有序参数传入。
>>> def show_two_stars(first, second='second', third='third'):
... print "first: " + str(first)
... print "second: " + str(second)
... print "third: " + str(third)
>>> show_two_stars('a', 'b', 'c')
first: a
second: b
third: c
>>> show_two_stars(**{'second': 'hey', 'first': 'you'})
first: you
second: hey
third: third
>>> show_two_stars({'second': 'hey', 'first': 'you'})
first: {'second': 'hey', 'first': 'you'}
second: second
third: third
让args = [1,2,3]
:
func(*args) == func(1,2,3)
- 变量作为参数从列表(或任何其他序列类型)中解包出来
func(args) == func([1,2,3])
- 列表通过
让kwargs = dict(a=1,b=2,c=3)
:
func(kwargs) == func({'a':1, 'b':2, 'c':3})
- 口述通过
func(*kwargs) == func(('a','b','c'))
- 字典键的元组(随机顺序)
func(**kwargs) == func(a=1,b=2,c=3)
- (key, value) 作为命名参数从字典(或任何其他映射类型)中解压出来
def fun1(*args):
""" This function accepts a non keyworded variable length argument as a parameter.
"""
print args
print len(args)
>>> a = []
>>> fun1(a)
([],)
1
# This clearly shows that, the empty list itself is passed as a first argument. Since *args now contains one empty list as its first argument, so the length is 1
>>> fun1(*a)
()
0
# Here the empty list is unwrapped (elements are brought out as separate variable length arguments) and passed to the function. Since there is no element inside, the length of *args is 0
>>>
我知道 Python 中函数定义中星号的含义。
不过,我经常看到星号表示调用带有以下参数的函数:
def foo(*args, **kwargs):
first_func(args, kwargs)
second_func(*args, **kwargs)
第一次和第二次函数调用有什么区别?
不同之处在于如何将参数传递给被调用的函数。当您使用 *
时,参数被解包(如果它们是列表或元组)——否则,它们将按原样简单地传递。
这是一个差异示例:
>>> def add(a, b):
... print a + b
...
>>> add(*[2,3])
5
>>> add([2,3])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: add() takes exactly 2 arguments (1 given)
>>> add(4, 5)
9
当我在参数前面加上 *
前缀时,它实际上将列表解压缩为两个单独的参数,它们作为 a
和 b
传递给 add
。没有它,它只是作为一个参数传入列表。
字典和 **
的情况相同,只是它们作为命名参数而不是有序参数传入。
>>> def show_two_stars(first, second='second', third='third'):
... print "first: " + str(first)
... print "second: " + str(second)
... print "third: " + str(third)
>>> show_two_stars('a', 'b', 'c')
first: a
second: b
third: c
>>> show_two_stars(**{'second': 'hey', 'first': 'you'})
first: you
second: hey
third: third
>>> show_two_stars({'second': 'hey', 'first': 'you'})
first: {'second': 'hey', 'first': 'you'}
second: second
third: third
让args = [1,2,3]
:
func(*args) == func(1,2,3)
- 变量作为参数从列表(或任何其他序列类型)中解包出来
func(args) == func([1,2,3])
- 列表通过
让kwargs = dict(a=1,b=2,c=3)
:
func(kwargs) == func({'a':1, 'b':2, 'c':3})
- 口述通过
func(*kwargs) == func(('a','b','c'))
- 字典键的元组(随机顺序)
func(**kwargs) == func(a=1,b=2,c=3)
- (key, value) 作为命名参数从字典(或任何其他映射类型)中解压出来
def fun1(*args):
""" This function accepts a non keyworded variable length argument as a parameter.
"""
print args
print len(args)
>>> a = []
>>> fun1(a)
([],)
1
# This clearly shows that, the empty list itself is passed as a first argument. Since *args now contains one empty list as its first argument, so the length is 1
>>> fun1(*a)
()
0
# Here the empty list is unwrapped (elements are brought out as separate variable length arguments) and passed to the function. Since there is no element inside, the length of *args is 0
>>>