Python中的*和**(轉載+合成---一文搞懂Python的*傳參)

Python中的*和**(轉載)

參考鏈接:

https://blog.csdn.net/qq_32252957/article/details/80887960
https://www.cnblogs.com/beiluowuzheng/p/8461518.html

簡介:

Python中的*與**操作符使用最多的就是兩種用法。

1.用做運算符,即*表示乘號,**表示次方。

2.用於指定函數傳入參數的類型的。
*用於參數前面,表示傳入的多個參數將按照元組的形式存儲,是一個元組;

**用於參數前則表示傳入的(多個)參數將按照字典的形式存儲,是一個字典。

*args必須要在**kwargs,否則將會提示語法錯誤"SyntaxError: non-keyword arg after keyword arg."

代碼展示:

def func(*args):
  print(type(args))
  for index, item in enumerate(args):
    '''
    enumerate()是python的內置函數
    對於一個可迭代的(iterable)/可遍歷的對象(list, str,tuple),enumerate將其組成一個索引序列,利用它可以同時獲得索引和值
    >>> list1 = ['life', 'is', 'too', 'short', 'you', 'need', 'python.']
    >>> for index, item in enumerate(list1):
    ...     print(index, item)
    ...
    0 life
    1 is
    2 too
    3 short
    4 you
    5 need
    6 python.
    '''
    # 下面的參數化打印的教程待會兒寫,可以直接搜python format。
    print("{}:{}".format(index, item))
 
def function(**kwarg):
  print(type(kwarg))
  for key, value in kwarg.items():
    print("{}:{}".format(key, value))
 
 
def main():
  func("python", "golang")
  function(a = "python", b = "golang")
 
if __name__ == '__main__':
  main()
 
'''
結果: 
<class 'tuple'>
0:python
1:golang
<class 'dict'>
a:python
b:golang
[Finished in 0.5s]
'''

對比總結:

參考的這篇博客基本上把最重要的信息講清楚,且演示出來了。
因爲最近在看別人的代碼,發現用了很多的kwargs,但是之前看Python的基礎教程時,很少遇到這東西,這次需要系統的拿出來練習一下。
我們來看看這兩個關鍵詞, args是arguments(參數)的縮寫,kwargs是key word arguments的縮寫,從字面意思就能看出來,kwargs對應的就是字典中的key和值,因此也可以便於記憶。
另外,我們需要第三個實驗,就是即有*args,又有
kwargs,還有普通的參數,需要明白這三者之間的順序。以及對應的打印展示:

1. 單獨使用*args

>>> def foo(*args):
...     print(args)
...
>>> foo("fruit", "animal", "human")
('fruit', 'animal', 'human')
>>> foo(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
>>> arr = [1, 2, 3, 4, 5]  # 如果我們希望將一個數組形成元組,需要在傳入參數的前面 加上一個*
>>> foo(arr)
([1, 2, 3, 4, 5],)
>>> foo(*arr)
(1, 2, 3, 4, 5)

2. 單獨使用**kwargs

>>> def foo(**kwargs):
...     for key, value in kwargs.items():
...         print("%s=%s" % (key, value))
...
>>> foo(a=1, b=2, c=3)
a=1
b=2
c=3

3.(*)和(**)一起使用

>>> def foo(*args, **kwargs):
...     print("args:", args)
...     print("kwargs:", kwargs)
...
>>> foo(1, 2, 3, a=1, b=2)
args: (1, 2, 3)
kwargs: {'a': 1, 'b': 2}
>>> arr = [1, 2, 3]
>>> foo(*arr, a=1, b=2)
args: (1, 2, 3)
kwargs: {'a': 1, 'b': 2}

4.混合使用+普通參數+默認參數

>>> def foo(name, *args, middle=None, **kwargs):
...     print("name:", name)
...     print("args:", args)
...     print("middle:", middle)
...     print("kwargs:", kwargs)
...
# 第一個hello沒有指定形參,直接被name捕獲
# 剩下的纔會被*args捕獲,但是由於沒有指定middle的值,因此採用了默認值
# 剩下的都被**kwargs捕獲了。
>>> foo("hello", 1, 2, 3, a=1, b=2, c=3)
name: hello
args: (1, 2, 3)
middle: None
kwargs: {'a': 1, 'b': 2, 'c': 3}
# 第二次測試,hello仍然被name捕獲
# 123被*args捕獲
# 因爲指定了middle值,因此不是默認值。
# 剩下的仍然被**kwargs撿垃圾
>>> foo("hello", 1, 2, 3, middle="world", a=1, b=2, c=3)
name: hello
args: (1, 2, 3)
middle: world
kwargs: {'a': 1, 'b': 2, 'c': 3}

# 這裏的第三個實驗,纔是精髓;
# 先創建一個字典,裏面有五個鍵值對,將這字典傳入函數中。
# 函數會先尋找name這個鍵的值,爲hello;
# 接下來因爲沒有元組,因此args爲()
# 再來尋找middle這個鍵值,找到了值爲world
# 剩下沒人要的都被存到了kwargs裏面了。
>>> my_foo = {"name": "hello", "middle": "world", "a": "1", "b": "2", "c": "3"}
>>> foo(**my_foo)
name: hello
args: ()
middle: world
kwargs: {'a': '1', 'b': '2', 'c': '3'}

再加上我自己的一些探索:
1.定義的字典順序打亂對結果的影響;

  • 沒有影響

2.傳入字典的時候,不加**有何區別

  • 不加**,變量名就是一個變量,無法匹配到各個值,不知道是不是因爲指針的關係,有明白的大佬可以在評論區解釋一下,多謝!
def dict_foo(name, *args, middle=None, **kwargs):
    print("name:", name)
    print("args:", args)
    print("middle:", middle)
    print("kwargs:", kwargs)

    print("-"*20)

    for k, v in kwargs.items():
        print("{}:{}".format(k, v))
        
## 打印結果----
name: {'middle': 'world', 'name': 'hello', 'a': 1}
args: ()
middle: None
kwargs: {}
--------------------
name: hello
args: ()
middle: world
kwargs: {'a': 1}
--------------------
a:1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章