[Python] *args and **kwargs

這次來紀錄一個我以前剛學python的時候很容易一頭霧水的 - *args and **kwargs

其實python的tutorial網頁都有教學, 只是我都是用到才會去查

不過這次這東西還滿重要的(默.....)

Ref: http://docs.python.org/dev/tutorial/controlflow.html#more-on-defining-functions

來看網頁的範例

def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
    while True:
        ok = input(prompt)
        if ok in ('y', 'ye', 'yes'):
            return True
        if ok in ('n', 'no', 'nop', 'nope'):
            return False
        retries = retries - 1
        if retries < 0:
            raise IOError('refusenik user')
        print(complaint)

這是個很一般的function, 很單純的parameter, 有prompt, retries, complaint, 也有設定預設值, 看起來很美滿
那有趣的東西就要來了

def cheeseshop(kind, *arguments, **keywords):
    print("-- Do you have any", kind, "?")
    print("-- I'm sorry, we're all out of", kind)
    for arg in arguments:
        print(arg)
    print("-" * 40)
    keys = sorted(keywords.keys())
    for kw in keys:
        print(kw, ":", keywords[kw])

這時候看到兩個很有趣的東西 - *arguments還有**keywords, 先不解釋, 來看要怎麼呼叫

cheeseshop("Limburger", "It's very runny, sir.",
           "It's really very, VERY runny, sir.",
           shopkeeper="Michael Palin",
           client="John Cleese",
           sketch="Cheese Shop Sketch")

其實從呼叫的方法, 應該可以開始猜出這兩個東西的使用跟差異

首先kind, 就只是一般的argument, 他就只會接收一個argument: "Limburger"

再來是*argument, 這有專有名稱: Arbitrary Argument Lists, 也就是會接受任意個argument, 前提是他是一個一般的argument, 意思就是後面那些長的比較奇怪還有變數參雜在其中的, 並不會接收, 以及這邊收下來之後, 他其實是用tuple去儲存這些資料, 所以這邊會收到兩個*argument: "It's very runny, sir." 跟 "It's really very, VERY runny, sir."

最後一個是**keywords專有名稱: keyword arguments (這樣就知道為甚麼很多人用kwargs稱呼他), 最後這些帶有變數的argument, 就統統會被**keywords給接收, 這邊有一個重點, 他是用python的dictionary去接收的, 也就是說這是一個dict, 參數名稱也就不能重複不然會error, 而在function內部存取當然就可以直接使用keyword["shopkeeper"], keyword["client"], keyword["sketch"]

留言

這個網誌中的熱門文章

[Linux] Linux下查詢硬體記憶體資訊 Memory Information

[Other] Chrome 重新整理所有開啟頁面

[Python] Simple Socket Server