スターオペレーターとはどういう意味ですか?[重複]
-
05-10-2019 - |
質問
この質問にはすでに答えがあります:
- ** (二重星/アスタリスク) と * (星/アスタリスク) はパラメーターに対して何をしますか? 19 件の回答
- 関数呼び出し内のアスタリスク 3 つの答え
は何ですか *
Python の演算子 means (次のようなコードなど) zip(*x)
または f(**k)
?
- インタプリタ内部ではどのように処理されるのでしょうか?
- パフォーマンスにまったく影響はありませんか?速いですか、それとも遅いですか?
- それが役立つのはどんなときで、そうでないのはどんなときでしょうか?
- 関数宣言または呼び出しで使用する必要がありますか?
解決
シングルスター *
シーケンス/コレクションをポジショナル引数に梱包するので、これを行うことができます。
def sum(a, b):
return a + b
values = (1, 2)
s = sum(*values)
これにより、タプルが展開され、実際には次のように実行されます。
s = sum(1, 2)
ダブルスター **
同じことをして、辞書のみを使用して、したがって引数の名前が付けられています。
values = { 'a': 1, 'b': 2 }
s = sum(**values)
組み合わせることもできます。
def sum(a, b, c, d):
return a + b + c + d
values1 = (1, 2)
values2 = { 'c': 10, 'd': 15 }
s = sum(*values1, **values2)
asを実行します:
s = sum(1, 2, c=10, d=15)
セクションも参照してください 4.7.4-引数リストを開梱します Pythonドキュメントの。
さらに、実行する関数を定義できます *x
と **y
引数では、これにより、関数が宣言に具体的に指定されていない任意の数の位置および/または指名された引数を受け入れることができます。
例:
def sum(*values):
s = 0
for v in values:
s = s + v
return s
s = sum(1, 2, 3, 4, 5)
または **
:
def get_a(**values):
return values['a']
s = get_a(a=1, b=2) # returns 1
これにより、宣言することなく、多数のオプションパラメーターを指定できます。
繰り返しますが、組み合わせることができます。
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
他のヒント
1つの小さなポイント:これらは演算子ではありません。演算子は、既存の値から新しい値を作成するために式で使用されます(たとえば、1+2は3になります。 *および**は、関数宣言と呼び出しの構文の一部です。
これは、関数呼び出しを「保存」したい場合に特に役立ちます。
たとえば、関数「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
ADD(TEST [0]、test [1])のようなものを手動で行う以外に、ADDを呼び出す他の方法はありません。また、変数数の変数がある場合、コードは必要なすべてのIFステートメントでかなり醜くなる可能性があります。
これが役立つもう1つの場所は、工場オブジェクト(あなたのためにオブジェクトを作成するオブジェクト)を定義するためのものです。クラスの工場があると仮定します。それは車のオブジェクトを作り、それらを返します。 myFactory.make_car( 'red'、 'bmw'、 '335ix')が車( 'red'、 'bmw'、 '335ix')を作成してから返します。
def make_car(*args):
return Car(*args)
これは、スーパークラスのコンストラクターを呼び出す場合にも役立ちます。
これは拡張呼び出し構文と呼ばれます。から ドキュメンテーション:
構文 *expression が関数呼び出しに出現する場合、expression はシーケンスとして評価される必要があります。このシーケンスの要素は、追加の位置引数であるかのように扱われます。位置引数 x1,..., xN があり、expression がシーケンス y1, ..., yM として評価される場合、これは M+N の位置引数 x1, ..., xN, y1, ... を使用した呼び出しと同等です。 ...、yM。
そして:
構文 **expression が関数呼び出しに出現する場合、expression はマッピングとして評価される必要があり、その内容は追加のキーワード引数として扱われます。キーワードが式と明示的なキーワード引数の両方に出現する場合、TypeError 例外が発生します。
関数コールでは、シングルスターがリストを別々の引数に変換します(例: zip(*x)
と同じです zip(x1,x2,x3)
もしも x=[x1,x2,x3]
)そして、ダブルスターは辞書を別々のキーワード引数に変えます(例: f(**k)
と同じです f(x=my_x, y=my_y)
もしも k = {'x':my_x, 'y':my_y}
.
関数定義では、それはその逆です。単一の星は任意の数の引数をリストに変え、ダブルスタートは任意の数のキーワード引数を辞書に変えます。例えば def foo(*x)
「fooは任意の数の引数を取り、リストxからアクセスできます(すなわち、ユーザーが呼び出す場合 foo(1,2,3)
, x
そうなるでしょう [1,2,3]
)" と def bar(**k)
「barは任意の数のキーワード引数を取得し、辞書kからアクセスできます(すなわち、ユーザーが呼び出す場合 bar(x=42, y=23)
, k
そうなるでしょう {'x': 42, 'y': 23}
)".