2017-01-20 77 views
1

在以下情況下使用kargs是否正確?在下面的python代碼中使用kwargs是否正確?

我有一個函數需要在調用中有五個參數,其中兩個參數是可選的。所以,我可以刪除它:

def f(p1, p2, p3, p4, p5, o1=None, o2=None) 

def f(**kwargs) 

因爲我在做這樣的事情與PARAMS:

orig_path = "{0}/{1}/{3}/{4}".format(p1, p2, p3, p4) 

orig_path = "{p1}/{p2}/{p3}/{p4}".format(kwargs) 

我不知道哪種風格是Python中正確的方式在聲明中使用。有沒有任何指導尋找kwargs的正確使用?我在亞馬遜看到boto3 api通常使用kwargs構造,但是...

+3

使用第一個。然後單獨的函數就會告訴我們需要5個參數。這是某種信息獲取。它也可以在函數內部保存一些代碼。 (假設:p1-p5是必需的) – sascha

+2

@sascha您可能會將其作爲答案,並提到Python的Zen中的「顯式優於隱式」原則。 – blubberdiblub

+0

@blubberdiblub隨意提及它,因爲你提到的Python的禪是非常相關的。 – sascha

回答

1

作爲一個經驗法則,如果可以的話,您應該總是寫出所有參數在函數定義中,並且理想地給它們描述性名稱。

Zen of Python

明確優於隱式。

可讀性計數。

使參數明確有助於防止許多錯誤,例如調用函數的參數太多或太少,或者使用不存在的關鍵字參數。

它還有助於提高可讀性,因爲您可以很容易地從定義中發現函數期望的數量和參數以及可能的關鍵字參數的默認值。有時,甚至可以通過好的參數名稱來猜測函數的功能,而無需查看文檔。

有些IDE甚至可以在編寫呼叫時自動查找定義,並在打字時提醒您可能遇到的問題。當是確定以使用*args與012所以

def twiddle_knobs(*args, **kwargs): # WARNING: never do this! 
    my_radio.modify_control(radio.TUNEFREQ, max(min(args[0], 120.0), 85.0)) 
    my_radio.modify_control(radio.VOL_MASTER, args[1]/100.0) 

    if kwargs.get("panning") is not None: 
     my_radio.modify_control(radio.VOL_LEFT, min(1.0 - kwargs["panning"]/100.0, 1.0)) 
     my_radio.modify_control(radio.VOL_RIGHT, min(1.0 + kwargs["panning"]/100.0, 1.0)) 

    for control, param, default in ((radio.EQU_BASS, "bass",  6.0), 
            (radio.EQU_MID, "midrange", -2.0), 
            (radio.EQU_TREB, "treble", 1.5)): 

     my_radio.modify_control(control, kwargs.get(param, default), radio.DB) 

這樣做:

def twiddle_knobs(tuning, volume, panning=None, bass=6.0, midrange=-2.0, treble=1.5): 
    """Modify the most important radio controls.""" 

    my_radio.modify_control(radio.TUNEFREQ, value=max(min(tuning, 120.0), 85.0)) 
    my_radio.modify_control(radio.VOL_MASTER, value=(volume/100.0)) 

    if panning is not None: 
     my_radio.modify_control(radio.VOL_LEFT, value=min(1.0 - panning/100.0, 1.0)) 
     my_radio.modify_control(radio.VOL_RIGHT, value=min(1.0 + panning/100.0, 1.0)) 

    for control, value in ((radio.EQU_BASS, bass), 
          (radio.EQU_MID, midrange), 
          (radio.EQU_TREB, treble)): 

     my_radio.modify_control(control, value=value, unit=radio.DB) 

不要這樣做?對於*args

  • 的一個用途是當你需要接受的事情列表, 是的一致好評,並起到相同的作用。但是,也可以使用 僅使用普通參數,並讓調用方明確地通過 列表。有時,使用func([thing])調用該函數看起來似乎很難,但是,特別是在大多數時候只通過一個 或根本沒有任何東西。那些是*args將 改善的情況。

  • 而且,當你需要一些的位置和/或關鍵字 參數的功能接收到你不 有超過控制和你不想支配其他函數參數 允許來電者通過,然後*args*kwargs - 在您的顯式參數之後使用 - 是實現該目的的方式。

  • 如果你有一組關鍵字參數,服務於強烈 相關的功能,你可以不完全預定義前期什麼 關鍵字將,因爲它們可能取決於東西是 動態變化的,這也將是使用 *kwargs的好理由。

此列表並不詳盡,但它應該給你一個大致的想法。

相關問題