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