星际算符是什么意思?(复制)

时间:2021-10-02 01:14:26

Possible Duplicate:
What does *args and **kwargs mean?

可能的副本:*args和**kwargs是什么意思?

What does the * operator mean in Python, such as in code like zip(*x) or f(**k)?

*操作符在Python中是什么意思,比如在zip(*x)或f(**k)这样的代码中?

  1. How is it handled internally in the interpreter?
  2. 在解释器内部如何处理?
  3. Does it affect performance at all? Is it fast or slow?
  4. 它会影响性能吗?它是快还是慢?
  5. When is it useful and when is it not?
  6. 什么时候有用,什么时候没用?
  7. Should it be used in a function declaration or in a call?
  8. 它应该用于函数声明还是调用中?

5 个解决方案

#1


687  

The single star * unpacks the sequence/collection into positional arguments, so you can do this:

单星*将序列/集合分解为位置参数,因此您可以这样做:

def sum(a, b):
    return a + b

values = (1, 2)

s = sum(*values)

This will unpack the tuple so that it actually executes as:

这将打开tuple,使其实际执行为:

s = sum(1, 2)

The double star ** does the same, only using a dictionary and thus named arguments:

双星**也一样,只是使用字典和命名参数:

values = { 'a': 1, 'b': 2 }
s = sum(**values)

You can also combine:

你也可以结合:

def sum(a, b, c, d):
    return a + b + c + d

values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sum(*values1, **values2)

will execute as:

将执行:

s = sum(1, 2, c=10, d=15)

Also see section 4.7.4 - Unpacking Argument Lists of the Python documentation.

还可以参阅Python文档的第4.7.4 -解包参数列表。


Additionally you can define functions to take *x and **y arguments, this allows a function to accept any number of positional and/or named arguments that aren't specifically named in the declaration.

此外,您可以定义函数来获取*x和**y参数,这允许函数接受任何数量的位置参数和/或命名参数,这些参数在声明中没有指定。

Example:

例子:

def sum(*values):
    s = 0
    for v in values:
        s = s + v
    return s

s = sum(1, 2, 3, 4, 5)

or with **:

或* *:

def get_a(**values):
    return values['a']

s = get_a(a=1, b=2)      # returns 1

this can allow you to specify a large number of optional parameters without having to declare them.

这可以允许您指定大量的可选参数,而不必声明它们。

And again, you can combine:

再一次,你可以结合:

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

#2


35  

One small point: these are not operators. Operators are used in expressions to create new values from existing values (1+2 becomes 3, for example. The * and ** here are part of the syntax of function declarations and calls.

一个小问题:这些不是操作符。表达式中使用运算符从现有值创建新值(例如,1+2变成3)。这里的*和**是函数声明和调用语法的一部分。

#3


15  

It is called the extended call syntax. From the documentation:

它被称为扩展调用语法。从文档:

If the syntax *expression appears in the function call, expression must evaluate to a sequence. Elements from this sequence are treated as if they were additional positional arguments; if there are positional arguments x1,..., xN, and expression evaluates to a sequence y1, ..., yM, this is equivalent to a call with M+N positional arguments x1, ..., xN, y1, ..., yM.

如果语法*表达式出现在函数调用中,表达式必须计算到一个序列。这个序列中的元素被视为附加的位置参数;如果有位置参数x1,…, xN,表达式计算为序列y1,…这等价于用M+N的位置参数x1,…,xN,y1,……,,

and:

和:

If the syntax **expression appears in the function call, expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments. In the case of a keyword appearing in both expression and as an explicit keyword argument, a TypeError exception is raised.

如果语法*表达式出现在函数调用中,则表达式必须计算到映射,其内容将被视为附加的关键字参数。对于同时出现在表达式和作为显式关键字参数的关键字,将引发一个TypeError异常。

#4


13  

I find this particularly useful for when you want to 'store' a function call.

我发现当您想要“存储”函数调用时,这一点特别有用。

For example, suppose I have some unit tests for a function 'add':

例如,假设我对一个函数“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

There is no other way to call add, other than manually doing something like add(test[0], test[1]), which is ugly. Also, if there are a variable number of variables, the code could get pretty ugly with all the if-statements you would need.

除了手动执行add(测试[0],测试[1])之外,没有其他方法调用add,这很难看。此外,如果变量的数量是可变的,那么使用所有你需要的if语句,代码可能会变得非常糟糕。

Another place this is useful is for defining Factory objects (objects that create objects for you). Suppose you have some class Factory, that makes Car objects and returns them. You could make it so that myFactory.make_car('red', 'bmw', '335ix') creates Car('red', 'bmw', '335ix'), then returns it.

另一个有用的地方是定义工厂对象(为您创建对象的对象)。假设您有一个类工厂,它生成汽车对象并返回它们。你可以把它做成我的工厂。make_car(“红色”、“宝马”、“335ix”)创建汽车(“红色”、“宝马”、“335ix”),然后返回。

def make_car(*args):
   return Car(*args)

This is also useful when you want to call a superclass' constructor.

当您想要调用超类的构造函数时,这也很有用。

#5


7  

In a function call the single star turns a list into seperate arguments (e.g. zip(*x) is the same as zip(x1,x2,x3) if x=[x1,x2,x3]) and the double star turns a dictionary into seperate keyword arguments (e.g. f(**k) is the same as f(x=my_x, y=my_y) if k = {'x':my_x, 'y':my_y}.

在函数调用中,如果x=[x1,x2,x3],则单星号将列表转换为独立的myperate参数(例如,zip(*x)与zip(x1,x2,x3)相同;双星号将字典转换为独立的关键字参数(例如,f(* k)与f(x=my_x, y=my_y '

In a function definition it's the other way around: the single star turns an arbitrary number of arguments into a list, and the double start turns an arbitrary number of keyword arguments into a dictionary. E.g. def foo(*x) means "foo takes an arbitrary number of arguments and they will be accessible through the list x (i.e. if the user calls foo(1,2,3), x will be [1,2,3])" and def bar(**k) means "bar takes an arbitrary number of keyword arguments and they will be accessible through the dictionary k (i.e. if the user calls bar(x=42, y=23), k will be {'x': 42, 'y': 23})".

在函数定义中,它是另一种方式:单个星形将任意数量的参数转换为一个列表,而double start则将任意数量的关键字参数转换为字典。例如def foo(* x)意味着“foo有任意数量的参数,他们将通过x列表(即如果用户调用foo(1、2、3),x将[1,2,3])”和def酒吧(* * k)意味着“酒吧需要任意数量的关键字参数,他们将可以通过字典k(即如果用户调用bar(x = 42,y = 23),k将{“x”:42岁的“y”:23 })”。

#1


687  

The single star * unpacks the sequence/collection into positional arguments, so you can do this:

单星*将序列/集合分解为位置参数,因此您可以这样做:

def sum(a, b):
    return a + b

values = (1, 2)

s = sum(*values)

This will unpack the tuple so that it actually executes as:

这将打开tuple,使其实际执行为:

s = sum(1, 2)

The double star ** does the same, only using a dictionary and thus named arguments:

双星**也一样,只是使用字典和命名参数:

values = { 'a': 1, 'b': 2 }
s = sum(**values)

You can also combine:

你也可以结合:

def sum(a, b, c, d):
    return a + b + c + d

values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sum(*values1, **values2)

will execute as:

将执行:

s = sum(1, 2, c=10, d=15)

Also see section 4.7.4 - Unpacking Argument Lists of the Python documentation.

还可以参阅Python文档的第4.7.4 -解包参数列表。


Additionally you can define functions to take *x and **y arguments, this allows a function to accept any number of positional and/or named arguments that aren't specifically named in the declaration.

此外,您可以定义函数来获取*x和**y参数,这允许函数接受任何数量的位置参数和/或命名参数,这些参数在声明中没有指定。

Example:

例子:

def sum(*values):
    s = 0
    for v in values:
        s = s + v
    return s

s = sum(1, 2, 3, 4, 5)

or with **:

或* *:

def get_a(**values):
    return values['a']

s = get_a(a=1, b=2)      # returns 1

this can allow you to specify a large number of optional parameters without having to declare them.

这可以允许您指定大量的可选参数,而不必声明它们。

And again, you can combine:

再一次,你可以结合:

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

#2


35  

One small point: these are not operators. Operators are used in expressions to create new values from existing values (1+2 becomes 3, for example. The * and ** here are part of the syntax of function declarations and calls.

一个小问题:这些不是操作符。表达式中使用运算符从现有值创建新值(例如,1+2变成3)。这里的*和**是函数声明和调用语法的一部分。

#3


15  

It is called the extended call syntax. From the documentation:

它被称为扩展调用语法。从文档:

If the syntax *expression appears in the function call, expression must evaluate to a sequence. Elements from this sequence are treated as if they were additional positional arguments; if there are positional arguments x1,..., xN, and expression evaluates to a sequence y1, ..., yM, this is equivalent to a call with M+N positional arguments x1, ..., xN, y1, ..., yM.

如果语法*表达式出现在函数调用中,表达式必须计算到一个序列。这个序列中的元素被视为附加的位置参数;如果有位置参数x1,…, xN,表达式计算为序列y1,…这等价于用M+N的位置参数x1,…,xN,y1,……,,

and:

和:

If the syntax **expression appears in the function call, expression must evaluate to a mapping, the contents of which are treated as additional keyword arguments. In the case of a keyword appearing in both expression and as an explicit keyword argument, a TypeError exception is raised.

如果语法*表达式出现在函数调用中,则表达式必须计算到映射,其内容将被视为附加的关键字参数。对于同时出现在表达式和作为显式关键字参数的关键字,将引发一个TypeError异常。

#4


13  

I find this particularly useful for when you want to 'store' a function call.

我发现当您想要“存储”函数调用时,这一点特别有用。

For example, suppose I have some unit tests for a function 'add':

例如,假设我对一个函数“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

There is no other way to call add, other than manually doing something like add(test[0], test[1]), which is ugly. Also, if there are a variable number of variables, the code could get pretty ugly with all the if-statements you would need.

除了手动执行add(测试[0],测试[1])之外,没有其他方法调用add,这很难看。此外,如果变量的数量是可变的,那么使用所有你需要的if语句,代码可能会变得非常糟糕。

Another place this is useful is for defining Factory objects (objects that create objects for you). Suppose you have some class Factory, that makes Car objects and returns them. You could make it so that myFactory.make_car('red', 'bmw', '335ix') creates Car('red', 'bmw', '335ix'), then returns it.

另一个有用的地方是定义工厂对象(为您创建对象的对象)。假设您有一个类工厂,它生成汽车对象并返回它们。你可以把它做成我的工厂。make_car(“红色”、“宝马”、“335ix”)创建汽车(“红色”、“宝马”、“335ix”),然后返回。

def make_car(*args):
   return Car(*args)

This is also useful when you want to call a superclass' constructor.

当您想要调用超类的构造函数时,这也很有用。

#5


7  

In a function call the single star turns a list into seperate arguments (e.g. zip(*x) is the same as zip(x1,x2,x3) if x=[x1,x2,x3]) and the double star turns a dictionary into seperate keyword arguments (e.g. f(**k) is the same as f(x=my_x, y=my_y) if k = {'x':my_x, 'y':my_y}.

在函数调用中,如果x=[x1,x2,x3],则单星号将列表转换为独立的myperate参数(例如,zip(*x)与zip(x1,x2,x3)相同;双星号将字典转换为独立的关键字参数(例如,f(* k)与f(x=my_x, y=my_y '

In a function definition it's the other way around: the single star turns an arbitrary number of arguments into a list, and the double start turns an arbitrary number of keyword arguments into a dictionary. E.g. def foo(*x) means "foo takes an arbitrary number of arguments and they will be accessible through the list x (i.e. if the user calls foo(1,2,3), x will be [1,2,3])" and def bar(**k) means "bar takes an arbitrary number of keyword arguments and they will be accessible through the dictionary k (i.e. if the user calls bar(x=42, y=23), k will be {'x': 42, 'y': 23})".

在函数定义中,它是另一种方式:单个星形将任意数量的参数转换为一个列表,而double start则将任意数量的关键字参数转换为字典。例如def foo(* x)意味着“foo有任意数量的参数,他们将通过x列表(即如果用户调用foo(1、2、3),x将[1,2,3])”和def酒吧(* * k)意味着“酒吧需要任意数量的关键字参数,他们将可以通过字典k(即如果用户调用bar(x = 42,y = 23),k将{“x”:42岁的“y”:23 })”。