Python基礎-*args和**kwargs魔法變數

阿里瓜瓜發表於2017-08-31

 

在學習Python時,總會遇到*args和**kwargs這兩個魔法變數,那麼它們到底是什麼?

首先,並不是必須寫成*args和**kwargs。只有變數前面的*(星號)才是必須的,你也可以寫成*var 和**vars,而寫成*args 和**kwargs只是一個通俗的命名約定。 

1 *args的用法

*args和**kwargs主要用於函式定義。你可以將不定數量的引數傳遞給一個函式。

這裡的不定的意思是:預先並不知道函式使用者會傳遞多少個引數給你,所以在這個場景下使用這兩個關鍵字。

  • *args是用來傳送一個非鍵值對的可變數量的引數列表給一個函式。

   這裡有個例子幫你理解這個概念:

def test_var_args(f_arg, *argv):
    print("first normal arg:", f_arg)
    for arg in argv:
        print("another arg through *argv:", arg)
    
test_var_args('google', 'python', 'java', 'c++')
('first normal arg:', 'google')
('another arg through *argv:', 'python')
('another arg through *argv:', 'java')
('another arg through *argv:', 'c++')

2 **kwargs的用法

  • **kwargs允許你將不定長度的鍵值對(字典),作為引數傳遞給一個函式。如果你想要在一個函式裡處理帶名字的引數,你應該使用**kwargs。       
def greet_me(**kwargs):
    for key, value in kwargs.items():
        print("{0} == {1}".format(key, value))
        
greet_me(name="google", website="www.google.com", level=1)
website == www.google.com
name == google
level == 1

現在你可以看出我們怎樣在一個函式裡,處理了一個鍵值對引數了。

這就是**kwargs的基礎,而且你可以看出它有多麼管用。接下來讓我們談談,怎樣使用*args和**kwargs來呼叫一個引數為列表或者字典的函式。

3 使用*args和**kwargs來呼叫函式

那現在我們將看到怎樣使用*args和**kwargs來呼叫一個函式。假設你有這樣一個函式

def test_args_kwargs(arg1, arg2, arg3):
        print("arg1:", arg1)
        print("arg2:", arg2)
        print("arg3:", arg3)

你可以使用*args或**kwargs來給這個函式傳遞引數。下面是怎樣做:

# 首先使用*args:
args = ("two", 3, 5)
print "首先使用*args"
test_args_kwargs(*args)
print "\n"

# 現在使用**kwargs:       
print "首先使用**kwargs" 
kwargs = {"arg3": 3, "arg2": "two", "arg1": 5}
test_args_kwargs(**kwargs)
首先使用*args
('arg1:', 'two')
('arg2:', 3)
('arg3:', 5)


首先使用**kwargs
('arg1:', 5)
('arg2:', 'two')
('arg3:', 3)

如果你想在函式裡同時使用標準引數、*args和**kwargs這三種引數, 順序是這樣的:

some_func(fargs, *args, **kwargs)

4 什麼時候使用它們?

  •  這還真的要看你的需求而定。最常見的用例是在寫函式裝飾器的時候。
  •  此外它也可以用來做猴子補丁(monkey patching)。猴子補丁的意思是在程式執行時(runtime)修改某些程式碼。
  •  舉個例子,你有一個類,裡面有個叫get_info的函式會呼叫一個API並返回相應的資料。如果想測試它,可以把API呼叫替換成一些測試資料。例如:
import someclass2
def get_info(self, *args):
        return "Test data"

someclass.get_info = get_info

 

相關文章