*args和**kwargs是什么意思?

def foo(x, y, *args):
def bar(x, y, **kwargs):

当前回答

单*表示可以有任意数量的额外位置参数。foo()可以像foo(1,2,3,4,5)一样调用。在foo()的主体中,param2是一个包含2-5的序列。

双**表示可以有任意数量的额外命名参数。bar()可以像bar(1,a=2,b=3)一样调用。在bar()的主体中,param2是一个字典,其中包含{‘a‘:2,‘b‘:3}

使用以下代码:

def foo(param1, *param2):
    print(param1)
    print(param2)

def bar(param1, **param2):
    print(param1)
    print(param2)

foo(1,2,3,4,5)
bar(1,a=2,b=3)

输出为

1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}

其他回答

*表示以元组形式接收变量参数

**表示接收变量参数作为字典

使用方式如下:

1) 单个*

def foo(*args):
    for arg in args:
        print(arg)

foo("two", 3)

输出:

two
3

2) 现在**

def bar(**kwargs):
    for key in kwargs:
        print(key, kwargs[key])

bar(dic1="two", dic2=3)

输出:

dic1 two
dic2 3

单*表示可以有任意数量的额外位置参数。foo()可以像foo(1,2,3,4,5)一样调用。在foo()的主体中,param2是一个包含2-5的序列。

双**表示可以有任意数量的额外命名参数。bar()可以像bar(1,a=2,b=3)一样调用。在bar()的主体中,param2是一个字典,其中包含{‘a‘:2,‘b‘:3}

使用以下代码:

def foo(param1, *param2):
    print(param1)
    print(param2)

def bar(param1, **param2):
    print(param1)
    print(param2)

foo(1,2,3,4,5)
bar(1,a=2,b=3)

输出为

1
(2, 3, 4, 5)
1
{'a': 2, 'b': 3}

*args和**kwargs:允许您向函数传递可变数量的参数。

*args:用于向函数发送非关键字可变长度参数列表:

def args(normal_arg, *argv):
    print("normal argument:", normal_arg)

    for arg in argv:
        print("Argument in list of arguments from *argv:", arg)

args('animals', 'fish', 'duck', 'bird')

将产生:

normal argument: animals
Argument in list of arguments from *argv: fish
Argument in list of arguments from *argv: duck
Argument in list of arguments from *argv: bird

**夸尔斯*

**kwargs允许您向函数传递关键字可变长度的参数。如果要处理函数中的命名参数,应使用**kwargs。

def who(**kwargs):
    if kwargs is not None:
        for key, value in kwargs.items():
            print("Your %s is %s." % (key, value))

who(name="Nikola", last_name="Tesla", birthday="7.10.1856", birthplace="Croatia")  

将产生:

Your name is Nikola.
Your last_name is Tesla.
Your birthday is 7.10.1856.
Your birthplace is Croatia.

除了函数调用之外,*args和**kwargs在类层次结构中也很有用,并且还可以避免在Python中编写__init__方法。类似的用法可以在Django代码等框架中看到。

例如

def __init__(self, *args, **kwargs):
    for attribute_name, value in zip(self._expected_attributes, args):
        setattr(self, attribute_name, value)
        if kwargs.has_key(attribute_name):
            kwargs.pop(attribute_name)

    for attribute_name in kwargs.viewkeys():
        setattr(self, attribute_name, kwargs[attribute_name])

子类可以是

class RetailItem(Item):
    _expected_attributes = Item._expected_attributes + ['name', 'price', 'category', 'country_of_origin']

class FoodItem(RetailItem):
    _expected_attributes = RetailItem._expected_attributes +  ['expiry_date']

然后将子类实例化为

food_item = FoodItem(name = 'Jam', 
                     price = 12.0, 
                     category = 'Foods', 
                     country_of_origin = 'US', 
                     expiry_date = datetime.datetime.now())

此外,具有仅对该子类实例有意义的新属性的子类可以调用基类__init__来卸载属性设置。这是通过*args和**kwargs完成的。kwargs主要用于使用命名参数使代码可读。例如

class ElectronicAccessories(RetailItem):
    _expected_attributes = RetailItem._expected_attributes +  ['specifications']
    # Depend on args and kwargs to populate the data as needed.
    def __init__(self, specifications = None, *args, **kwargs):
        self.specifications = specifications  # Rest of attributes will make sense to parent class.
        super(ElectronicAccessories, self).__init__(*args, **kwargs)

其可以被初始化为

usb_key = ElectronicAccessories(name = 'Sandisk', 
                                price = '$6.00', 
                                category = 'Electronics',
                                country_of_origin = 'CN',
                                specifications = '4GB USB 2.0/USB 3.0')

完整的代码在这里

def foo(param1,*param2):是一个可以接受任意数量的*param2值的方法,def bar(param1,**param2):是一种方法,可以接受任意数量的带有*param2键的值param1是一个简单的参数。

例如,在Java中实现varargs的语法如下:

accessModifier methodName(datatype… arg) {
    // method body
}