**(二重星/アスタリスク)および*(星/アスタリスク)はパラメーターに対して何をしますか?

2515
Todd 2008-09-01 05:04.

次のメソッド定義では、***は何をしparam2ますか?

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

21 answers

2402
Peter Hoffmann 2008-09-01 05:17.

*argsそして**kwargsセクションで説明したように機能する任意の数の引数を可能にする一般的なイディオムである機能の定義の詳細Pythonドキュメントに。

*argsあなたはすべての関数パラメータ与えるタプルとしては:

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

foo(1)
# 1

foo(1,2,3)
# 1
# 2
# 3

**kwargsあなたにすべて与えるキーワード引数を辞書として仮パラメータに対応するものを除き。

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

bar(name='one', age=27)
# age 27
# name one

両方のイディオムを通常の引数と組み合わせて、固定引数といくつかの可変引数のセットを許可できます。

def foo(kind, *args, **kwargs):
   pass

これを逆に使用することも可能です。

def foo(a, b, c):
    print(a, b, c)

obj = {'b':10, 'c':'lee'}

foo(100,**obj)
# 100 10 lee

この*lイディオムのもう1つの使用法は、関数を呼び出すときに引数リスト解凍することです。

def foo(bar, lee):
    print(bar, lee)

l = [1,2]

foo(*l)
# 1 2

Python 3では*l、割り当ての左側で使用することができます(Extended Iterable Unpacking)が、このコンテキストではタプルの代わりにリストを提供します。

first, *rest = [1,2,3,4]
first, *l, last = [1,2,3,4]

また、Python 3は新しいセマンティクスを追加します(PEP 3102を参照)。

def func(arg1, arg2, arg3, *, kwarg1, kwarg2):
    pass

このような関数は3つの位置引数のみを受け入れ、それ以降*はすべてキーワード引数としてのみ渡すことができます。

656
Lorin Hochstein 2008-09-01 05:47.

それはまた、あなたが使用できることは注目に値します***、同様の機能を呼び出すとき。これは、リスト/タプルまたはディクショナリのいずれかを使用して、関数に複数の引数を直接渡すことができるショートカットです。たとえば、次の関数がある場合:

def foo(x,y,z):
    print("x=" + str(x))
    print("y=" + str(y))
    print("z=" + str(z))

次のようなことができます。

>>> mylist = [1,2,3]
>>> foo(*mylist)
x=1
y=2
z=3

>>> mydict = {'x':1,'y':2,'z':3}
>>> foo(**mydict)
x=1
y=2
z=3

>>> mytuple = (1, 2, 3)
>>> foo(*mytuple)
x=1
y=2
z=3

注:のキーにmydictは、関数のパラメーターとまったく同じ名前を付ける必要がありますfoo。それ以外の場合は、TypeError:をスローします

>>> mydict = {'x':1,'y':2,'z':3,'badnews':9}
>>> foo(**mydict)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() got an unexpected keyword argument 'badnews'
185
nickd 2008-09-01 05:20.

単一の*は、追加の位置引数がいくつでも存在できることを意味します。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}
156
Aaron Hall 2014-10-15 06:34.

何を**(ダブルスター)及び*(スター)のパラメータのために行います

これらを使用すると、関数を定義して受け入れユーザーが任意の数の引数、定位置(*)およびキーワード(**を渡すことができます。

関数の定義

*argsargs。という名前のタプルに割り当てられるオプションの位置引数(パラメーター)をいくつでも使用できます。

**kwargskwargs。という名前のdictに含まれるオプションのキーワード引数(パラメーター)をいくつでも使用できます。

適切な名前を選択できます(そして選択する必要があります)が、引数が非特定のセマンティクスでargsありkwargs、標準名であることが意図されている場合。

拡張、任意の数の引数を渡す

*args**kwargsを使用して、リスト(または任意の反復可能)およびdict(または任意のマッピング)からそれぞれパラメーターを渡すこともできます。

パラメータを受け取る関数は、パラメータが展開されていることを知る必要はありません。

たとえば、Python 2のxrangeは明示的にを期待していません*argsが、引数として3つの整数を受け取るためです。

>>> x = xrange(3) # create our *args - an iterable of 3 integers
>>> xrange(*x)    # expand here
xrange(0, 2, 2)

別の例として、次の場所でdict展開を使用できますstr.format

>>> foo = 'FOO'
>>> bar = 'BAR'
>>> 'this is foo, {foo} and bar, {bar}'.format(**locals())
'this is foo, FOO and bar, BAR'

Python 3の新機能:キーワードのみの引数を使用した関数の定義

-の後にキーワードのみの引数を設定できます*args-たとえば、ここでkwarg2は、キーワード引数として指定する必要があります-位置的にではありません:

def foo(arg, kwarg=None, *args, kwarg2=None, **kwargs): 
    return arg, kwarg, args, kwarg2, kwargs

使用法:

>>> foo(1,2,3,4,5,kwarg2='kwarg2', bar='bar', baz='baz')
(1, 2, (3, 4, 5), 'kwarg2', {'bar': 'bar', 'baz': 'baz'})

また、*それ自体を使用して、無制限の位置引数を許可せずに、キーワードのみの引数が続くことを示すことができます。

def foo(arg, kwarg=None, *, kwarg2=None, **kwargs): 
    return arg, kwarg, kwarg2, kwargs

ここkwarg2でも、明示的に名前が付けられたキーワード引数である必要があります。

>>> foo(1,2,kwarg2='kwarg2', foo='foo', bar='bar')
(1, 2, 'kwarg2', {'foo': 'foo', 'bar': 'bar'})

そして、次のものがないため、無制限の位置引数を受け入れることができなくなりました*args*

>>> foo(1,2,3,4,5, kwarg2='kwarg2', foo='foo', bar='bar')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes from 1 to 2 positional arguments 
    but 5 positional arguments (and 1 keyword-only argument) were given

繰り返しますが、もっと簡単に言えば、ここkwargでは位置ではなく名前で指定する必要があります。

def bar(*, kwarg=None): 
    return kwarg

この例では、kwarg位置を通過しようとすると、エラーが発生することがわかります。

>>> bar('kwarg')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bar() takes 0 positional arguments but 1 was given

kwargパラメータをキーワード引数として明示的に渡す必要があります。

>>> bar(kwarg='kwarg')
'kwarg'

Python2互換のデモ

*args(通常は「star-args」と**kwargs呼ばれます)および(星は「kwargs」と言うことで暗示されますが、「double-star kwargs」で明示されます)は、*and**表記を使用するためのPythonの一般的なイディオムです。これらの特定の変数名は、(例えば、あなたが使用できる必要はありません*foos**bars)が、大会からの逸脱は、おそらくあなたの仲間のPythonプログラマーを激怒させることです。

通常、これらは、関数が受け取るものや渡す引数の数がわからない場合に使用します。また、すべての変数に個別に名前を付ける場合でも、非常に面倒で冗長になる場合があります(ただし、これは通常、明示的な場合です。暗黙的よりも優れています)。

例1

次の関数は、それらの使用方法を説明し、動作を示します。名前付きb引数は、次の前の2番目の位置引数によって消費されることに注意してください。

def foo(a, b=10, *args, **kwargs):
    '''
    this function takes required argument a, not required keyword argument b
    and any number of unknown positional arguments and keyword arguments after
    '''
    print('a is a required argument, and its value is {0}'.format(a))
    print('b not required, its default value is 10, actual value: {0}'.format(b))
    # we can inspect the unknown arguments we were passed:
    #  - args:
    print('args is of type {0} and length {1}'.format(type(args), len(args)))
    for arg in args:
        print('unknown arg: {0}'.format(arg))
    #  - kwargs:
    print('kwargs is of type {0} and length {1}'.format(type(kwargs),
                                                        len(kwargs)))
    for kw, arg in kwargs.items():
        print('unknown kwarg - kw: {0}, arg: {1}'.format(kw, arg))
    # But we don't have to know anything about them 
    # to pass them to other functions.
    print('Args or kwargs can be passed without knowing what they are.')
    # max can take two or more positional args: max(a, b, c...)
    print('e.g. max(a, b, *args) \n{0}'.format(
      max(a, b, *args))) 
    kweg = 'dict({0})'.format( # named args same as unknown kwargs
      ', '.join('{k}={v}'.format(k=k, v=v) 
                             for k, v in sorted(kwargs.items())))
    print('e.g. dict(**kwargs) (same as {kweg}) returns: \n{0}'.format(
      dict(**kwargs), kweg=kweg))

関数のシグネチャについては、オンラインヘルプでを確認できますhelp(foo)。これにより、

foo(a, b=10, *args, **kwargs)

この関数をで呼び出しましょう foo(1, 2, 3, 4, e=5, f=6, g=7)

印刷するもの:

a is a required argument, and its value is 1
b not required, its default value is 10, actual value: 2
args is of type <type 'tuple'> and length 2
unknown arg: 3
unknown arg: 4
kwargs is of type <type 'dict'> and length 3
unknown kwarg - kw: e, arg: 5
unknown kwarg - kw: g, arg: 7
unknown kwarg - kw: f, arg: 6
Args or kwargs can be passed without knowing what they are.
e.g. max(a, b, *args) 
4
e.g. dict(**kwargs) (same as dict(e=5, f=6, g=7)) returns: 
{'e': 5, 'g': 7, 'f': 6}

例2

別の関数を使用して呼び出すこともできますa

def bar(a):
    b, c, d, e, f = 2, 3, 4, 5, 6
    # dumping every local variable into foo as a keyword argument 
    # by expanding the locals dict:
    foo(**locals()) 

bar(100) プリント:

a is a required argument, and its value is 100
b not required, its default value is 10, actual value: 2
args is of type <type 'tuple'> and length 0
kwargs is of type <type 'dict'> and length 4
unknown kwarg - kw: c, arg: 3
unknown kwarg - kw: e, arg: 5
unknown kwarg - kw: d, arg: 4
unknown kwarg - kw: f, arg: 6
Args or kwargs can be passed without knowing what they are.
e.g. max(a, b, *args) 
100
e.g. dict(**kwargs) (same as dict(c=3, d=4, e=5, f=6)) returns: 
{'c': 3, 'e': 5, 'd': 4, 'f': 6}

例3:デコレータでの実際の使用法

OK、それで多分私達はまだユーティリティを見ていません。したがって、差別化コードの前後に冗長コードを持ついくつかの関数があると想像してください。以下の名前付き関数は、説明のための単なる擬似コードです。

def foo(a, b, c, d=0, e=100):
    # imagine this is much more code than a simple function call
    preprocess() 
    differentiating_process_foo(a,b,c,d,e)
    # imagine this is much more code than a simple function call
    postprocess()

def bar(a, b, c=None, d=0, e=100, f=None):
    preprocess()
    differentiating_process_bar(a,b,c,d,e,f)
    postprocess()

def baz(a, b, c, d, e, f):
    ... and so on

これを別の方法で処理できる可能性がありますが、デコレータを使用して冗長性を確実に抽出できるため、以下の例は、その方法*args**kwargs非常に役立つ方法を示しています。

def decorator(function):
    '''function to wrap other functions with a pre- and postprocess'''
    @functools.wraps(function) # applies module, name, and docstring to wrapper
    def wrapper(*args, **kwargs):
        # again, imagine this is complicated, but we only write it once!
        preprocess()
        function(*args, **kwargs)
        postprocess()
    return wrapper

そして、冗長性を考慮したため、ラップされたすべての関数をより簡潔に記述できるようになりました。

@decorator
def foo(a, b, c, d=0, e=100):
    differentiating_process_foo(a,b,c,d,e)

@decorator
def bar(a, b, c=None, d=0, e=100, f=None):
    differentiating_process_bar(a,b,c,d,e,f)

@decorator
def baz(a, b, c=None, d=0, e=100, f=None, g=None):
    differentiating_process_baz(a,b,c,d,e,f, g)

@decorator
def quux(a, b, c=None, d=0, e=100, f=None, g=None, h=None):
    differentiating_process_quux(a,b,c,d,e,f,g,h)

そして、我々のコード、アウトファクタリングによって*argsおよび**kwargs私たちが行うことができ、我々は、コードの行数を減らし、可読性と保守性を向上させ、そして私たちのプログラムのロジックのための唯一の標準的な場所を持っています。この構造の一部を変更する必要がある場合は、それぞれを変更する場所が1つあります。

53
Karan Ahuja 2016-01-21 01:40.

まず、位置引数とキーワード引数とは何かを理解しましょう。以下は、Positional引数を使用した関数定義の例です

def test(a,b,c):
     print(a)
     print(b)
     print(c)

test(1,2,3)
#output:
1
2
3

したがって、これは位置引数を使用した関数定義です。キーワード/名前付き引数を使用して呼び出すこともできます。

def test(a,b,c):
     print(a)
     print(b)
     print(c)

test(a=1,b=2,c=3)
#output:
1
2
3

ここで、キーワード引数を使用した関数定義の例を調べてみましょう。

def test(a=0,b=0,c=0):
     print(a)
     print(b)
     print(c)
     print('-------------------------')

test(a=1,b=2,c=3)
#output :
1
2
3
-------------------------

この関数は、位置引数を使用して呼び出すこともできます。

def test(a=0,b=0,c=0):
    print(a)
    print(b)
    print(c)
    print('-------------------------')

test(1,2,3)
# output :
1
2
3
---------------------------------

これで、位置引数とキーワード引数を使用した関数定義がわかりました。

ここで、「*」演算子と「**」演算子について調べてみましょう。

これらの演算子は次の2つの領域で使用できることに注意してください。

a)関数呼び出し

b)関数の定義

関数呼び出しでの「*」演算子と「**」演算子の使用

例に直接取り掛かり、それについて議論しましょう。

def sum(a,b):  #receive args from function calls as sum(1,2) or sum(a=1,b=2)
    print(a+b)

my_tuple = (1,2)
my_list = [1,2]
my_dict = {'a':1,'b':2}

# Let us unpack data structure of list or tuple or dict into arguments with help of '*' operator
sum(*my_tuple)   # becomes same as sum(1,2) after unpacking my_tuple with '*'
sum(*my_list)    # becomes same as sum(1,2) after unpacking my_list with  '*'
sum(**my_dict)   # becomes same as sum(a=1,b=2) after unpacking by '**' 

# output is 3 in all three calls to sum function.

覚えておいてください

'*'または '**'演算子が関数呼び出しで使用される場合-

'*'演算子は、リストやタプルなどのデータ構造を関数定義に必要な引数に解凍します。

'**'演算子は、関数定義に必要な引数に辞書を解凍します。

ここで、関数定義での「*」演算子の使用について調べてみましょう。例:

def sum(*args): #pack the received positional args into data structure of tuple. after applying '*' - def sum((1,2,3,4))
    sum = 0
    for a in args:
        sum+=a
    print(sum)

sum(1,2,3,4)  #positional args sent to function sum
#output:
10

関数定義では、「*」演算子は受信した引数をタプルにパックします。

ここで、関数定義で使用される「**」の例を見てみましょう。

def sum(**args): #pack keyword args into datastructure of dict after applying '**' - def sum({a:1,b:2,c:3,d:4})
    sum=0
    for k,v in args.items():
        sum+=v
    print(sum)

sum(a=1,b=2,c=3,d=4) #positional args sent to function sum

関数定義では、「**」演算子は受信した引数を辞書にパックします。

覚えておいてください:

関数を呼び出す「*」アンパック関数定義によって受信されるように、位置やキーワード引数にタプルやリストのデータ構造を。

では、関数呼び出し「**」アンパック関数定義が受信する位置やキーワード引数に辞書のデータ構造。

では関数定義「*」パックタプルに位置引数。

では関数定義「**」パック辞書にキーワード引数。

37
Brad Solomon 2017-12-01 08:28.

このテーブルには、使用に便利である***、関数内の建設と機能の呼び出し

            In function construction         In function call
=======================================================================
          |  def f(*args):                 |  def f(a, b):
*args     |      for arg in args:          |      return a + b
          |          print(arg)            |  args = (1, 2)
          |  f(1, 2)                       |  f(*args)
----------|--------------------------------|---------------------------
          |  def f(a, b):                  |  def f(a, b):
**kwargs  |      return a + b              |      return a + b
          |  def g(**kwargs):              |  kwargs = dict(a=1, b=2)
          |      return f(**kwargs)        |  f(**kwargs)
          |  g(a=1, b=2)                   |
-----------------------------------------------------------------------

これは本当にロリンホッホスタインの答えを要約するのに役立ちますが、私はそれが役立つと思います。

関連:スター/スプラット演算子の使用がPython3で拡張されました

22
ronak 2012-09-11 18:33.

*そして**関数の引数リストに特別な使い方があります。*引数がリストである**ことを意味し、引数が辞書であることを意味します。これにより、関数は任意の数の引数を取ることができます

20
Miladiouss 2018-05-22 21:03.

例を挙げて学ぶ方へ!

  1. の目的は*、リストとして提供される任意の数の引数を取ることができる関数を定義する機能を提供することです(例f(*myList))。
  2. の目的は**、辞書(eg f(**{'x' : 1, 'y' : 2}))を提供することにより、関数の引数をフィードする機能を提供することです。

私たちは2つの通常の変数を取る関数を定義することによって、これをお見せしましょうxyとのように複数の引数を受け入れることができmyArgs、そしてとしてさらに多くの引数を受け取ることができますmyKW。後で、をy使用してフィードする方法を示しますmyArgDict

def f(x, y, *myArgs, **myKW):
    print("# x      = {}".format(x))
    print("# y      = {}".format(y))
    print("# myArgs = {}".format(myArgs))
    print("# myKW   = {}".format(myKW))
    print("# ----------------------------------------------------------------------")

# Define a list for demonstration purposes
myList    = ["Left", "Right", "Up", "Down"]
# Define a dictionary for demonstration purposes
myDict    = {"Wubba": "lubba", "Dub": "dub"}
# Define a dictionary to feed y
myArgDict = {'y': "Why?", 'y0': "Why not?", "q": "Here is a cue!"}

# The 1st elem of myList feeds y
f("myEx", *myList, **myDict)
# x      = myEx
# y      = Left
# myArgs = ('Right', 'Up', 'Down')
# myKW   = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------

# y is matched and fed first
# The rest of myArgDict becomes additional arguments feeding myKW
f("myEx", **myArgDict)
# x      = myEx
# y      = Why?
# myArgs = ()
# myKW   = {'y0': 'Why not?', 'q': 'Here is a cue!'}
# ----------------------------------------------------------------------

# The rest of myArgDict becomes additional arguments feeding myArgs
f("myEx", *myArgDict)
# x      = myEx
# y      = y
# myArgs = ('y0', 'q')
# myKW   = {}
# ----------------------------------------------------------------------

# Feed extra arguments manually and append even more from my list
f("myEx", 4, 42, 420, *myList, *myDict, **myDict)
# x      = myEx
# y      = 4
# myArgs = (42, 420, 'Left', 'Right', 'Up', 'Down', 'Wubba', 'Dub')
# myKW   = {'Wubba': 'lubba', 'Dub': 'dub'}
# ----------------------------------------------------------------------

# Without the stars, the entire provided list and dict become x, and y:
f(myList, myDict)
# x      = ['Left', 'Right', 'Up', 'Down']
# y      = {'Wubba': 'lubba', 'Dub': 'dub'}
# myArgs = ()
# myKW   = {}
# ----------------------------------------------------------------------

警告

  1. ** 辞書専用です。
  2. オプションではない引数の割り当てが最初に行われます。
  3. オプション以外の引数を2回使用することはできません。
  4. 該当する場合は、常に***に来る必要があります。
15
Chris Upchurch 2008-09-01 05:07.

Pythonドキュメントから:

仮パラメータースロットよりも多くの位置引数がある場合、構文「*識別子」を使用する仮パラメーターが存在しない限り、TypeError例外が発生します。この場合、その仮パラメーターは、過剰な位置引数を含むタプル(または、過剰な位置引数がなかった場合は空のタプル)を受け取ります。

キーワード引数が仮パラメータ名に対応していない場合、構文「**識別子」を使用する仮パラメータが存在しない限り、TypeError例外が発生します。この場合、その仮パラメーターは、過剰なキーワード引数を含む辞書(キーワードをキーとして使用し、引数値を対応する値として使用)、または過剰なキーワード引数がない場合は(新しい)空の辞書を受け取ります。

12
ishandutta2007 2018-08-08 08:28.

* タプルとして変数引数を受け取ることを意味します

** 辞書として可変引数を受け取ることを意味します

次のように使用されます。

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
10
leewz 2015-12-09 11:38.

Pythonの3.5で、あなたもこの構文を使用することができlistdicttuple、とset表示されます(また時にはリテラルと呼ばれます)。PEP 488:追加の開梱の一般化を参照してください。

>>> (0, *range(1, 4), 5, *range(6, 8))
(0, 1, 2, 3, 5, 6, 7)
>>> [0, *range(1, 4), 5, *range(6, 8)]
[0, 1, 2, 3, 5, 6, 7]
>>> {0, *range(1, 4), 5, *range(6, 8)}
{0, 1, 2, 3, 5, 6, 7}
>>> d = {'one': 1, 'two': 2, 'three': 3}
>>> e = {'six': 6, 'seven': 7}
>>> {'zero': 0, **d, 'five': 5, **e}
{'five': 5, 'seven': 7, 'two': 2, 'one': 1, 'three': 3, 'six': 6, 'zero': 0}

また、1回の関数呼び出しで複数のイテラブルを解凍できます。

>>> range(*[1, 10], *[2])
range(1, 10, 2)

(PEPリンクを提供してくれたmgilsonに感謝します。)

10
Meysam Sadeghi 2020-01-08 04:37.

TL; DR

下記のための6つのユースケースである***Pythonプログラミングでは:

  1. *args:を使用して任意の数の位置引数を 受け入れるにはdef foo(*args): pass、ここでfoo任意の数の位置引数を受け入れます。つまり、次の呼び出しが有効ですfoo(1)foo(1, 'bar')
  2. **kwargs:を使用して任意の数のキーワード引数を def foo(**kwargs): pass受け入れるには、ここで 'foo'は任意の数のキーワード引数を受け入れます。つまり、次の呼び出しは有効ですfoo(name='Tom')foo(name='Tom', age=33)
  3. *args, **kwargs:を使用して任意の数の位置引数とキーワード引数を 受け入れるにはdef foo(*args, **kwargs): pass、ここでfoo任意の数の位置引数とキーワード引数を受け入れます。つまり、次の呼び出しが有効ですfoo(1,name='Tom')foo(1, 'bar', name='Tom', age=33)
  4. *:を使用してキーワードのみの引数を適用 するにはdef foo(pos1, pos2, *, kwarg1): pass、ここ*でfooはpos2の後のキーワード引数のみを受け入れるためfoo(1, 2, 3)、TypeErrorが発生しますが、問題foo(1, 2, kwarg1=3)はありません。
  5. *_(注:これは慣例のみです)を使用して、より多くの位置引数にこれ以上関心を示さないこと:(慣例 def foo(bar, baz, *_): passにより)動作中に引数fooのみを使用しbarbaz他を無視することを意味します。
  6. \**_(注:これは慣例のみです)を使用して、これ以上のキーワード引数に関心がないことを表すには、 def foo(bar, baz, **_): pass(慣例により)動作中に引数fooのみを使用しbar、他のbaz引数を無視することを意味します。

ボーナス: Python 3.8以降では/、関数定義で使用して、位置のみのパラメーターを適用できます。次の例では、パラメータaとbは位置のみであり、cまたはdは位置またはキーワードであり、eまたはfはキーワードである必要があります。

def f(a, b, /, c, d, *, e, f):
    pass
9
Lochu'an Chang 2016-11-09 06:50.

他の人が言及していない例を挙げたい

*ジェネレーターを開梱することもできます

Python3ドキュメントの例

x = [1, 2, 3]
y = [4, 5, 6]

unzip_x, unzip_y = zip(*zip(x, y))

unzip_xは[1、2、3]になり、unzip_yは[4、5、6]になります。

zip()は、複数のirtable引数を受け取り、ジェネレーターを返します。

zip(*zip(x,y)) -> zip((1, 4), (2, 5), (3, 6))
6
quiet_penguin 2015-08-16 18:23.

関数呼び出しに加えて、* argsと** kwargsはクラス階層で役立ち__init__、Pythonでメソッドを作成する必要もありません。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())

また、そのサブクラスインスタンスにのみ意味のある新しい属性を持つサブクラスは、Baseクラス__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')

完全なコードはここにあります

6
Raj 2019-07-10 16:59.

ニックの答えに基づいて...

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


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


def three_params(param1, *param2, **param3):
    print(param1)
    print(param2)
    print(param3)


foo(1, 2, 3, 4, 5)
print("\n")
bar(1, a=2, b=3)
print("\n")
three_params(1, 2, 3, 4, s=5)

出力:

1
(2, 3, 4, 5)

1
{'a': 2, 'b': 3}

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

基本的に、任意の数の位置引数で* argsを使用でき、任意の名前付き引数(またはkwargs、別名キーワード引数)で** kwargsを使用できます。

3
Harvey 2018-05-02 02:54.

*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キーワード付きの可変長の引数を関数に渡すことができます。**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.
3
RBF06 2019-04-03 02:43.

TL; DR

関数に渡された引数をlistdictそれぞれ関数本体にパックします。このように関数シグネチャを定義すると、次のようになります。

def func(*args, **kwds):
    # do stuff

任意の数の引数とキーワード引数を使用して呼び出すことができます。非キーワード引数argsは関数本体内で呼び出されるリストにパックされ、キーワード引数kwdsは関数本体内で呼び出されるdictにパックされます。

func("this", "is a list of", "non-keyowrd", "arguments", keyword="ligma", options=[1,2,3])

今関数が呼び出される関数本体、内部で、2つのローカル変数があるargsリスト持つ値である["this", "is a list of", "non-keyword", "arguments"]kwdsされdictた値は、{"keyword" : "ligma", "options" : [1,2,3]}


これは逆に、つまり発信者側からも機能します。たとえば、次のように定義された関数がある場合:

def f(a, b, c, d=1, e=10):
    # do stuff

呼び出しスコープにあるイテラブルまたはマッピングを解凍することで、それを呼び出すことができます。

iterable = [1, 20, 500]
mapping = {"d" : 100, "e": 3}
f(*iterable, **mapping)
# That call is equivalent to
f(1, 20, 500, d=100, e=3)
2
amir jj 2016-10-27 02:48.

関数で両方を使用する良い例は次のとおりです。

>>> def foo(*arg,**kwargs):
...     print arg
...     print kwargs
>>>
>>> a = (1, 2, 3)
>>> b = {'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(*a,**b)
(1, 2, 3)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,**b) 
((1, 2, 3),)
{'aa': 11, 'bb': 22}
>>>
>>>
>>> foo(a,b) 
((1, 2, 3), {'aa': 11, 'bb': 22})
{}
>>>
>>>
>>> foo(a,*b)
((1, 2, 3), 'aa', 'bb')
{}
2
thanhtang 2016-11-27 11:09.

この例では、あなたが覚えて役立つだろう*args**kwargsとさえsuper一度にPythonで、継承。

class base(object):
    def __init__(self, base_param):
        self.base_param = base_param


class child1(base): # inherited from base class
    def __init__(self, child_param, *args) # *args for non-keyword args
        self.child_param = child_param
        super(child1, self).__init__(*args) # call __init__ of the base class and initialize it with a NON-KEYWORD arg

class child2(base):
    def __init__(self, child_param, **kwargs):
        self.child_param = child_param
        super(child2, self).__init__(**kwargs) # call __init__ of the base class and initialize it with a KEYWORD arg

c1 = child1(1,0)
c2 = child2(1,base_param=0)
print c1.base_param # 0
print c1.child_param # 1
print c2.base_param # 0
print c2.child_param # 1
1
dreftymac 2019-12-07 06:36.

環境

  • python 3.x
  • で開梱 **
  • 文字列フォーマットで使用

文字列フォーマットで使用

このスレッドの回答に加えて、他では言及されていない別の詳細があります。これは、ブラッド・ソロモンの答えを拡張したものです

で解凍する**と、Pythonを使用するときにも役立ちstr.formatます。

これは、Pythonのf-strings f-stringで実行できることと多少似ていますが、変数を保持するdictを宣言するオーバーヘッドが追加されています(f-stringはdictを必要としません)。

簡単な例

  ## init vars
  ddvars = dict()
  ddcalc = dict()
  pass
  ddvars['fname']     = 'Huomer'
  ddvars['lname']     = 'Huimpson'
  ddvars['motto']     = 'I love donuts!'
  ddvars['age']       = 33
  pass
  ddcalc['ydiff']     = 5
  ddcalc['ycalc']     = ddvars['age'] + ddcalc['ydiff']
  pass
  vdemo = []

  ## ********************
  ## single unpack supported in py 2.7
  vdemo.append('''
  Hello {fname} {lname}!

  Today you are {age} years old!

  We love your motto "{motto}" and we agree with you!
  '''.format(**ddvars)) 
  pass

  ## ********************
  ## multiple unpack supported in py 3.x
  vdemo.append('''
  Hello {fname} {lname}!

  In {ydiff} years you will be {ycalc} years old!
  '''.format(**ddvars,**ddcalc)) 
  pass

  ## ********************
  print(vdemo[-1])

1
etoricky 2020-06-18 18:05.

引数として3つの項目を持つ関数が与えられました

sum = lambda x, y, z: x + y + z
sum(1,2,3) # sum 3 items

sum([1,2,3]) # error, needs 3 items, not 1 list

x = [1,2,3][0]
y = [1,2,3][1]
z = [1,2,3][2]
sum(x,y,z) # ok

sum(*[1,2,3]) # ok, 1 list becomes 3 items

三角形、円、長方形のアイテムが入ったこのおもちゃを想像してみてください。そのバッグは直接はまりません。これらの3つのアイテムを取り出すには、バッグを開梱する必要があります。Python *演算子は、この解凍プロセスを実行します。

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする&nbsp;

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

Total War:Warhammer:Kotakuレビュー

Total War:Warhammer:Kotakuレビュー

私はこのゲームを嫌う準備ができていました。先週の前に、Total War:Warhammerについての私の考えがありました:それでもここに私は、私の手にある完成品であり、私は変わった男です。

涙の道:軍事化された帝国主義勢力がスタンディングロックキャンプを占領

涙の道:軍事化された帝国主義勢力がスタンディングロックキャンプを占領

スタンディングロックスー族のメンバーと水の保護者は、ノースダコタ州のスタンディングロックにあるオセティサコウィンキャンプを去ります。(Twitter経由のCNNスクリーンショット)火と煙がスカイラインを覆い、スタンディングロックスー族のメンバーと水の保護者が、聖なるものを守りながら建てた家、オセティサコウィン(セブンカウンシルファイアーズ)キャンプから行進し、太鼓を打ち、歌い、祈りました。ダコタアクセスパイプラインとしても知られる「ブラックスネーク」からの土地。

シアーズとKマートはイヴァンカ・トランプの商品を自分たちで取り除いています

シアーズとKマートはイヴァンカ・トランプの商品を自分たちで取り除いています

写真:APシアーズとKマートは、イヴァンカ・トランプのトランプホームアイテムのコレクションも、誰も購入したくないために削除しました。シアーズとKマートの両方の親会社であるシアーズホールディングスは、土曜日のABCニュースへの声明で、彼らが気にかけていると辛抱強く説明しましたトランプラインを売り続けるにはお金を稼ぐことについてあまりにも多く。

ポテトチップスでたった10分でスペインのトルティーヤを作る

ポテトチップスでたった10分でスペインのトルティーヤを作る

伝統的なスペインのトルティーヤは通常、オリーブオイルで柔らかくなるまで調理されたポテトから始まります(30分以上かかる場合があります)が、ケトルで調理されたポテトチップスの助けを借りてわずか10分でテーブルに置くことができます。上のビデオはすべてがバラバラにならないように裏返す方法を含め、レシピ全体を説明しますが、必要なのは4〜5個の卵と3カップのケトルチップスだけです。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language