1. 理論的説明:
*parameters と **parameters は Python パラメーターの重要な知識です。これらはすべて変数パラメーター (任意のパラメーター) と呼ばれます。コード内では* args、 **kwargsがよく見られます。
関数として定義されている場合: 一致しないパラメータを収集してタプルまたは辞書オブジェクトを形成します
1. * パラメータは、一致しないすべての位置パラメータを収集してタプル オブジェクトを形成し、ローカル変数 args はこのタプル オブジェクトを指します。
2. ** パラメータは、一致しないキーワード パラメータをすべて収集して dict オブジェクトを形成し、ローカル変数 kwargs はこの dict オブジェクトを指します。
def temp(*args,**kwargs):
pass
関数として呼び出す場合: unpack 関数
1. * パラメータは、タプル オブジェクトの各要素を解凍し、それを位置パラメータとして関数に 1 つずつ渡すために使用されます。
2. ** パラメータは、dict オブジェクトの各要素を解凍し、それをキーワード パラメータとして関数に 1 つずつ渡すために使用されます。
my_tuple = ("wang","yuan","wai")
temp(*my_tuple)
#---等同于---#
temp("wangyuan","yuan","wai")
my_dict = {"name":"wangyuanwai","age":32}
temp(**my_dict)
#----等同于----#
temp(name="wangyuanwai",age=32)
2、*引数の 例
当面はこれらの基本概念を理解できないのが普通であり、完全に理解するにはプロセスが必要です...次のいくつかの * args の例でこれらの概念を説明します。Python を学習するすべての学生に役立つことを願っています。!
1) 2 つの位置パラメータを持つ関数 print_str
def print_str(first, second):
print(first)
print(second)
パラメーターを 1 つだけ指定して print_str() 関数を呼び出すとどうなりますか?
In [31]: print_str("hello")
TypeError: print_str() missing 1 required positional argument: 'second'
TypeError: インタプリタは、コンソールの print_str() 関数に 2 つの引数が必要であることを伝えますが、print_str() 関数に渡した引数は 1 つだけです。
考え中: print_str() 関数を変更して、1 つのパラメーター、2 つのパラメーター、またはさらに多くの変数数値パラメーターを受け入れるようにするにはどうすればよいでしょうか?
2) 1 つのパラメータまたは可変数のパラメータを受け入れるように print_str() 関数を変更します。
print_str() 関数の最後のパラメータを可変パラメータ *sec に変更します。
def print_str(first, *second):
print(first)
print(second)
この時点で、別のパラメータを渡して print_str() 関数を呼び出して、今回何が起こるかを見てみましょう。
In [34]: print_str("hello")
hello
()
今度は、それ以上エラーは報告されず、渡された最初の文字列パラメータ「hello」が出力され、渡されたパラメータなしの *2 番目は、タプル オブジェクトの文字列表現、つまり括弧「()」を出力します。注: () は要素が 0 のタプル オブジェクトを意味します。
考えてみます: なぜ 2 番目の変数がタプル オブジェクトになるのでしょうか? 私たちは学び続けます!
3) もう 1 つの実験、print_str() 関数に 4 つの引数を渡します...何が起こるでしょうか?
In [35]: print_str("hello","美女","小猫","青蛙")
hello
('美女', '小猫', '青蛙')
最初のパラメータ「hello」は通常、最初の行に出力されます。
2 番目のパラメーター「beauty」、3 番目のパラメーター「kitten」、および 4 番目のパラメーター「frog」は、関数内で新しいタプル オブジェクトにアセンブルされ、この新しいタプル オブジェクトは変数 Second に割り当てられます。このとき、ローカル変数は変数 Second はタプル オブジェクトを指します
説明: 関数の呼び出し時に渡されるパラメータは、関数内で左から右の順に使用されます。左端のパラメータが位置パラメータによって最初に使用され(一致し)、残りの一致しないパラメータはすべて自動的に使用されます。新しいタプル オブジェクトに収集され、ローカル変数 2 番目はこの新しいタプル オブジェクトを指します。
注: * パラメータは一致しない位置パラメータのみを収集します
4) print_str() 関数を呼び出すときに * パラメータが直接渡されるとどうなりますか?
def print_str(first, *second):
print(first)
print(second)
コンソール呼び出し:
In [38]: numbers_strings = ("1","2","3","4","5")
...: print_str(*numbers_strings) # 注意这里的*numbers_strings
1
('2', '3', '4', '5')
説明: *numbers_strings が関数呼び出しに出現する場合、それはアンパック (「*」文字の後にタプル オブジェクトが続く) と呼ばれ、numbers_strings 自体がタプル オブジェクトであるため、タプルのアンパックとも呼ばれます。要素はアンパックされます。位置パラメータに 1 つずつ入力されて関数に渡されるため、次の 2 つのステートメントは等価です。
print_str(*数値文字列)
に相当
print_str("1","2","3","4","5")
5) 変数パラメータを定義していない関数が呼び出された場合、* パラメータが渡されるとどうなりますか?
def print_str(first, second):
print(first)
print(second)
コンソール呼び出し:
In [40]: numbers_strings = ("1","2")
...: print_str(*numbers_strings)
1
2
print_str(*数値文字列)
に相当
print_str("1","2")
タプルのアンパック プロセス中に、各要素が順番に位置パラメータに入れられます。これは、タプルのアンパック関数の次の特性を示しています。
1. 可変パラメータで使用可能
2. 可変パラメータを定義しない関数でも使用可能
タプルのアンパック関数は完全に別の関数です
もう一度説明します: *パラメータは、関数の異なる位置に現れると、異なる機能を持ちます。
1. 関数定義に * パラメータが出現する場合、それは可変パラメータを意味します
2. 関数呼び出し内に * パラメータが出現する場合、それはアンパック関数を意味します。
注: タプルを解凍するときは、タプル内の要素の数が関数の位置パラメータの合計数と一致している必要があります。
3、**kwargs の例
1) 関数定義ではパラメータ名の前に ** が 2 つあります。
def printStr(**anything):
print(anything)
2 つのキーワード引数を指定して printStr 関数を呼び出して、何が起こるか見てみましょう。
In [42]: printStr(first = 5, second = 100)
{'first': 5, 'second': 100}
出力結果は dict オブジェクトの文字列形式ですが、なぜ何かが dict になるのでしょうか?
説明: 関数が呼び出されたときに、受信キーワード パラメータに一致する位置パラメータがある場合、その位置パラメータがこれらのキーワード パラメータより優先して使用され (一致し)、残りのすべての未使用 (一致しない) キーワード パラメータが関数内でアセンブルされます。 dict オブジェクトの場合、dict オブジェクトはアセンブリ後に変数名に割り当てられます。この時点では、ローカル変数 anything は dict オブジェクトを指します。
注: **パラメータは一致しないキーワード引数のみを収集します
2) 関数呼び出し時に辞書解凍関数を使用する(dictオブジェクトの前に**を追加)
def printStr(first, **dict):
print(str(first) + "\n")
print(dict)
コンソール呼び出し:
In [44]: printDic = {"name": "tyson", "age":"99"}
...: printStr(100, **printDic)
100
{'name': 'tyson', 'age': '99'}
#等同于
In [45]: printDic = {"name": "tyson", "age":"99"}
...: printStr(100, name = "tyson", age = "99")
100
{'name': 'tyson', 'age': '99'}
説明: 関数が呼び出されるとき、辞書の展開を示すために dict オブジェクトの前に ** を追加します。辞書オブジェクト内の各キーと値のペアの要素を 1 つずつキーワード パラメーターに変換し、関数に渡します。真ん中。
4. まとめ
Python 構文では、*parameters と **parameters が関数定義のパラメーター リストに同時に表示される場合、パラメーター リストが任意の数のパラメーターを受け入れることができることを意味し、これらを総称して変数パラメーターと呼びます。
関数が定義されているとき
1. *args は、任意の数 (0 を含む) の位置パラメータを受け入れることができることを意味します。関数が呼び出されるとき、すべての未使用 (一致しない) 位置パラメータは関数内でタプル オブジェクトに自動的にアセンブルされ、このタプル オブジェクトはローカル変数 args に割り当てられます
2. **kwargs は、任意の数 (0 を含む) のキーワード パラメータを受け入れることができることを示します。関数が呼び出されると、すべての未使用 (一致しない) キーワード パラメータが関数内の dict オブジェクトにアセンブルされ、dict オブジェクトはローカル変数 kwargs への代入
注: 関数が定義されるとき、両方が同時に存在するため、*args は **kwargs の前に配置する必要があります
関数が呼び出されたとき
1. *args は、アンパックされたタプル オブジェクト内の各要素が、呼び出された関数に位置パラメーターとして渡されることを意味します。
2. **kwargs は、解凍された辞書オブジェクト内の各要素が、呼び出された関数にキーワード パラメーターとして渡されることを意味します。
注意事項
1. 可変パラメータ、可変個数のパラメータは0パラメータも含めて複数渡すことができます。
2. 変数パラメータは、共通パラメータ (位置パラメータ、必須パラメータ、選択パラメータなどとも呼ばれます) とデフォルト値パラメータの後に定義する必要があります。これは、変数パラメータが前に定義されている場合、変数パラメータはすべての [一致しない] パラメータを収集するためです。 、通常のパラメータとデフォルト値パラメータはすべて可変パラメータに収集されるため、受信パラメータと一致することはできません。
def printStr(普通参数,默认值参数name="王员外",*参数,**参数):
pass
3. *パラメータは**パラメータの前に定義する必要があります
def printStr(普通参数,*参数,**参数):
pass
4. *args パラメータを含む関数を呼び出す場合、タプル オブジェクトを直接渡さないでください。タプル オブジェクトを渡した場合、そのタプル オブジェクトは関数内で組み立てられたタプル オブジェクト内の不一致要素になるだけです。タプルのアンパック構文、アンパック構文 *tuple を使用して、タプル オブジェクトの要素を渡すことができます。
temp = (1,2,3,4,5)
def my_first(*args):
print(args)
my_first(temp) #temp只算一个参数,除非你有这个需求
my_first(*temp) #OK
5. **kwargs パラメータを含む関数を呼び出すときは、辞書オブジェクトを直接渡さないでください。辞書オブジェクトは 1 つのパラメータとしてのみカウントされ、辞書オブジェクトは準拠していないため、この時点でエラーが報告されます。キーワードパラメータの文法指定、および辞書オブジェクトが使用可能 辞書アンパック構文、アンパック構文: **dict
my_book = {"first":"小当家", "seoncd": "我是baby"}
def my_blood(**kwargs):
print(kwargs)
my_blood(my_book) #作为一个字典对象传入
my_blood(**my_book) #一个一个的关键字参数传入
6. * パラメータの変数名。通常は変数名 args を使用します。単なる提案です。任意に呼び出すことができます。これは単なるローカル変数名です。
7. ** パラメータの変数名。通常は変数名 kwargs を使用します。単なる提案です。好きな名前を付けることができます。これはローカル変数名でもあります。
位置パラメータ、デフォルト値パラメータ、および可変パラメータを持つ関数 (参考)
def my_first_blood(first_name,last_name,age=0,*args,**kwargs):
print(first_name)
print(last_name)
print(age)
for ele in args:
print(ele)
for key,value in kwargs.items():
print(key)
print(value)
呼び出し方法:
n [47]: my_first_blood("王", "员外")
王
员外
0
In [48]:
...: my_first_blood("王", "员外", 32)
王
员外
32
In [49]: my_first_blood("王", "员外", 32, "北京", "海淀", style="开心")
王
员外
32
北京
海淀
style
开心
キーワード引数のみを渡す関数でエラーが発生する
def temp(say, **kwargs):
print(say)
print(kwargs)
temp(fk=100, hello=1000)
位置パラメータsayは受信キーワードパラメータfkおよびhelloと一致できないため、この呼び出しはエラーになります。キーワード パラメーターは、位置パラメーターで使用する前に、位置パラメーターの名前と一致する必要があります。次のように変更します。
In [52]: temp(10,fk=100, hello=1000)
10
{'fk': 100, 'hello': 1000}
アンパック関数はタプルだけでなく、リスト、文字列、範囲も可能です
first = (1,2,3)
second = [1,2,3]
third = "123"
fourth = range(4)
print(*first)
print(*second)
print(*third)
print(*fourth)
5. システム記述例の再利用
上記の理論を例を通じて検証するには、次のコードを参照してください。
1. デフォルト値を持つパラメータ
アスタリスク (*) のパラメータを理解する前に、デフォルト値のパラメータを見てみましょう。関数の定義は次のとおりです。
def defaultValueArgs(common, defaultStr = "default", defaultNum = 0):
print("Common args:", common)
print("Default String:", defaultStr)
print("Default Number:", defaultNum)
(1) デフォルト値(defaultStr、defaultNum)を持つパラメータがパラメータを渡さない場合に呼び出します。
In [26]: defaultValueArgs("Test")
Common args: Test
Default String: default
Default Number: 0
(2) デフォルト値を持つパラメータ(defaultStr、defaultNum)は、呼び出し時に直接渡すこともできます(以下の例ではdefaultStr)、または「argsName = value」の形式で記述することもできます(以下の例ではdefaultNum)。
In [27]: defaultValueArgs("Test", "Str", defaultNum=1)
Common args: Test
Default String: Str
Default Number: 1
In [28]: defaultValueArgs("Test", defaultNum=1)
Common args: Test
Default String: default
Default Number: 1
注: 関数が定義されている場合、デフォルト値を持つ最初のパラメータ以降のすべてのパラメータにはデフォルト値がなければなりません。そうしないと、実行時にエラーが報告されます。
def defaultValueArgs(common, defaultStr = "default", defaultNum):
print("Common args:", common)
print("Default String:", defaultStr)
print("Default Number:", defaultNum)
コンパイル出力:
SyntaxError: non-default argument follows default argument
2. アスタリスク (*) の付いた関数パラメータ
1 つのパラメーターを持つ関数は次のように定義されます。
def singalStar(common, *rest):
print("Common args: ", common)
print("Rest args: ", rest)
(1) アスタリスク (*) の付いたパラメータは渡されません。
In [3]: singalStar("hello")
Common args: hello
Rest args: ()
アスタリスク (*) の付いたパラメータは、パラメータが渡されない場合、デフォルトで空のタプルになります。
(2) アスタリスク (*) が付いたパラメータが複数の値で渡される場合 (その数が関数定義のパラメータの数以上である場合):
In [4]: singalStar("hello", "world", 000)
Common args: hello
Rest args: ('world', 0)
2 番目の方法では、アスタリスク パラメータが複数の受信パラメータを 1 つのタプルに結合していることを理解するのは難しくありません。
(3) アスタリスクパラメータにタプル型の値を直接渡す場合:
In [5]: singalStar("hello", ("world", 000))
Common args: hello
Rest args: (('world', 0),)
この時点で、渡されたタプル値はアスタリスク パラメータのタプル内の要素として使用されます。
(4) タプルをアスタリスクパラメータのパラメータ値として使用したい場合は、タプル値の前に「*」を追加するだけです。
In [6]: singalStar("hello", *("world", 000))
Common args: hello
Rest args: ('world', 0)
In [7]: singalStar("hello", *("world", 000), "123")
Common args: hello
3. 2 つのアスタリスク (**) が付いた関数パラメータ
2 つのアスタリスク (**) が付いた関数は次のように定義されます。
(1) 二重アスタリスク (**) パラメーターは値を渡しません。
In [9]: doubleStar("hello")
Common args: hello
Double args: {}
二重アスタリスク (**) の付いたパラメーターは、値が渡されない場合、デフォルトで空の辞書になります。
(2) 複数のパラメーターが渡される場合の二重アスタリスク (**) パラメーター (その数は関数定義内のパラメーターの数以上です):
In [10]: doubleStar("hello", "Test", 24)
TypeError: doubleStar() takes 1 positional argument but 3 were given
In [11]: doubleStar("hello", x = "Test", y = 24)
Common args: hello
Double args: {'x': 'Test', 'y': 24}
二重アスタリスク パラメータは、受け取った複数のパラメータを辞書に結合していることがわかりますが、この時点でデフォルト値を渡す「args = value」メソッドを採用する必要があるという点で単一アスタリスクとは異なります。 =が辞書のキーとなり、「=」以降のフィールドが辞書の値となります。
(3) アスタリスクパラメータのパラメータ値として辞書を使用したい場合はどうすればよいですか? 単一のアスタリスク パラメータと同様に、「 ** 」は辞書値の前に追加され、その後に値を追加することはできません。
In [12]: doubleStar("hello", {"name": "Test", "age": 24})
TypeError: doubleStar() takes 1 positional argument but 2 were given
In [13]: doubleStar("hello", **{"name": "Test", "age": 24}, {"name": "Test2", "age": 24})
SyntaxError: positional argument follows keyword argument unpacking
In [14]: doubleStar("hello", **{"name": "Test", "age": 24}, **{"name": "Test2", "age": 24})
TypeError: __main__.doubleStar() got multiple values for keyword argument 'name'
In [16]: doubleStar("hello", **{"name": "Test", "age": 24}, **{"name1": "Test1", "age1": 24})
Common args: hello
Double args: {'name': 'Test', 'age': 24, 'name1': 'Test1', 'age1': 24}
In [15]: doubleStar("hello", **{"name": "Test", "age": 24})
Common args: hello
Double args: {'name': 'Test', 'age': 24}
4. 場合によっては、単一アスタリスク関数パラメータと二重アスタリスク関数パラメータが一緒に使用されます。
In [17]: def singalAndDoubleStar(common, *single, **double):
...: print("Common args: ", common)
...: print("Single args: ", single)
...: print("Double args: ", double)
In [18]: singalAndDoubleStar("hello")
Common args: hello
Single args: ()
Double args: {}
In [19]: singalAndDoubleStar("hello", "world", 000)
Common args: hello
Single args: ('world', 0)
Double args: {}
In [20]: singalAndDoubleStar("hello", "world", 000, {"name": "Test", "age": 24})
Common args: hello
Single args: ('world', 0, {'name': 'Test', 'age': 24})
Double args: {}
In [21]: singalAndDoubleStar("hello", "world", 000, **{"name": "Test", "age": 24})
Common args: hello
Single args: ('world', 0)
Double args: {'name': 'Test', 'age': 24}
In [22]: singalAndDoubleStar("hello", ("world", 000), {"name": "Test", "age": 24})
Common args: hello
Single args: (('world', 0), {'name': 'Test', 'age': 24})
Double args: {}
In [23]: singalAndDoubleStar("hello", *("world", 000), {"name": "Test", "age": 24})
Common args: hello
Single args: ('world', 0, {'name': 'Test', 'age': 24})
Double args: {}
In [24]: singalAndDoubleStar("hello", *("world", 000), **{"name": "Test", "age": 24})
Common args: hello
Single args: ('world', 0)
Double args: {'name': 'Test', 'age': 24}
参考記事
1. * を含む Python パラメーターと ** を含むパラメーター
2. Python 関数パラメータの**_ kwargs **_ Python 関数パラメータ