在 Python 编程中,* args 和** kwargs 是常用的两个参数,它们被用来让函数接受任意数量的位置参数和关键字参数。本文将详细介绍它们的使用原理。*args 使用原理
*args是一个特殊的语法,它可以让我们在函数声明中接受任意数量的位置参数。*args 其实是一个元组,包含了所有传入的位置参数。下面给一个简单的例子,方便大家了解。def foo(*args):
for arg in args:
print(arg)
foo(1, 2, 3)
在这个例子中,函数 foo 接受任意数量的位置参数。如果调用 foo 函数时传递了任意数量的位置参数,这些参数都会打包成一个元组,然后作为参数传递给 foo 函数。在函数体内,使用 for 循环遍历元组,依次输出元组中的每个值。**kwargs 使用原理
与* args 类似,** kwargs 也是 Python 中的特殊语法,它可以让我们接受任意数量的关键字参数。在函数声明中,** kwargs 其实是一个字典,其中包含了所有传入的关键字参数。def bar(**kwargs):
for key, value in kwargs.items():
print(key, value)
bar(name='Tom', age=18, gender='male')
'name': 'Tom'
'age': 18
'gender': 'male'
在这个例子中,函数 bar 接受任意数量的关键字参数。如果调用 bar 函数时传递了任意数量的关键字参数,这些参数都会存储在一个字典中,然后作为参数传递给 bar 函数。在函数体内,使用 for 循环遍历字典,依次输出字典中的每个键值对。用*args和**kwargs定义函数
在实际应用中,我们经常需要定义一个函数,它能够接受任意数量的位置参数和关键字参数。使用* args和** kwargs可以非常方便地实现这个功能。def my_func(*args, **kwargs):
for arg in args:
print(arg)
for key, value in kwargs.items():
print(key, value)
my_func(1, 2, 3, name='Tom', age=18, gender='male')
1
2
3
name Tom
age 18
gender male
在这个例子中,我们定义了一个名为 my_func 的函数,它接受任意数量的位置参数和关键字参数。使用 for 循环遍历 args 元组和 kwargs 字典,分别输出其中的值。*args 和 **kwargs 的使用场景
可用于任意数量的参数
最常见的使用场景是函数的可扩展性,可以接受任意数量的参数。比如说经常用到的内置函数 sum(),接受任意数量的参数,返回参数的总和。def sum_all(*args):
result = 0
for i in args:
result += i
return result
print(sum_all(1,2,3,4,5)) # 15
print(sum_all(10,20,30,40,50)) # 150
可用于重载函数
重载函数指的是在同一个作用范围下定义多个同名函数,但他们的参数个数或者参数类型不同。Python 中并不是真正意义上的重载函数,但我们可以用简单的技巧来实现类似的功能。利用 *args 和 ** kwargs,我们可以将不同的参数传递方式都转化为函数的参数,然后再根据参数的类型或数量来实现不同的功能。def print_all(*args):
for arg in args:
print(arg)
def print_dict(**kwargs):
for key, value in kwargs.items():
print("{}: {}".format(key, value))
def print_msg(*args, **kwargs):
print_all(*args)
print_dict(**kwargs)
print_msg('Hello', 'world!', name='Tom', age=18)
Hello
world!
name: Tom
age: 18
在本例子中,用* args 和** kwargs 来定义了 print_all() 和 print_dict() 两个函数,用于分别打印位置参数和关键字参数。然后我们定义了一个名为 print_msg 的函数,它接受任意数量的参数,包括位置参数和关键字参数,然后使用 print_all() 和 print_dict() 分别处理这些参数。可使用在子类的构造函数中
可以使用*args和** kwargs 将参数从子类的构造函数传递到父类的构造函数。这样可以让子类更加灵活地继承父类的功能,在定义子类时可以针对不同的需求,传递不同数量的位置参数和关键字参数。下面给一个例子。class Animal:
def __init__(self, name, species):
self.name = name
self.species = species
class Dog(Animal):
def __init__(self, breed, *args, **kwargs):
super().__init__(*args, species='Dog', **kwargs)
self.breed = breed
my_dog = Dog('Golden Retriever', 'Max')
print(my_dog.name) # Max
print(my_dog.species) # Dog
print(my_dog.breed) # Golden Retriever
在这个例子中,我们定义了两个类,Animal 和 Dog。Animal 表示动物,有两个属性:name 和 species。Dog 继承自 Animal,有三个属性:name、species 和 breed。使用 *args 和 ** kwargs,我们可以将 Dog 类的构造函数参数转换为 Animal 类的构造函数参数,并且在 super() 函数中指定了 Animal 类的 species 属性,这样就可以在 Dog 类中添加特定于狗的属性。总结
使用* args和** kwargs是Python编程中非常有用的技巧。在函数声明中使用它们可以实现接收任意数量的位置参数和关键字参数的功能,让函数的可扩展性更加高效。