2014-05-19 45 views
4

雖然我對Python的* args和** kwargs有一個大概的理解(我認爲),但我很難理解如何將它們從一個函數傳遞到另一個函數。這裏是我的模型:如何通過Python args和kwargs?

from pdb import set_trace as debug 
from django.db import models 

class Person(models.Model): 
    name = models.CharField(max_length=30) 

    def __unicode__(self): 
     return u'%s' % self.name 

    def save_name_for(self, *args, **kwargs): 
     self.name = 'Alex' 
     return self 

    def save_name(self, *args, **kwargs): 
     debug() 
     self.save_name_for(self, args, kwargs) 
     self.save() 

我已經分割保存一個名稱到上面的兩個函數。通過這種方式,我可以通過單元測試save_name_for方法來單元測試我通常將所有的邏輯放入save_name方法中的邏輯。

當我運行此的解釋,並停止在save_name方法,爲我所期望的,我看到:

(Pdb) args 
self = 
args = (1, 2) 
kwargs = {'last': 'Doe', 'first': 'John'} 

如果我再踏進save_name_for方法,我看到:

(Pdb) args 
self = 
args = (<Person: >, (1, 2), {'last': 'Doe', 'first': 'John'}) 
kwargs = 

有沒有辦法將save_name方法接收到的kwargs直接傳入save_name_for方法,以便它們出現在後者的kwargs中?我希望看到這樣的事情在save_name_for方法的名稱空間:

(Pdb) args 
self = 
args = (1, 2) 
kwargs = {'last': 'Doe', 'first': 'John'} # <= I want this 

我知道我可以在save_name解析它們,然後將它們傳遞明確地save_name_for但似乎相當不雅。我也認爲我可能會這樣做,因爲參數是一個元組...

kwargs = args[2] 

...但它似乎沒有工作。參數[2]只是一切(我不明白這一點)。有沒有Pythonic的方式來做到這一點?

回答

5

你語法鏡像參數語法傳遞它們:

self.save_name_for(*args, **kwargs) 

請注意,您不需要在self通過; save_name_for已經綁定。

+1

我認爲應該是'** kwargs',而不是'* kwargs',對嗎? –

+1

@BryanOakley:完全正確,不確定多餘的傾斜角度。 –

+0

謝謝Martijn。是的,我只是測試它,它需要是「** kwargs」,而不是「* kwargs」。不知道爲什麼我不想嘗試這個。 – William

7

***操作符用於兩種不同的情況。

  1. 當作爲函數定義的一部分使用時,

    def save_name_for(self, *args, **kwargs): 
    

    它被用來表示的位置或關鍵字 參數的任意數量的,分別。要記住的一點是, 函數內部args將是一個元組,並kwargs將是一個 字典

  2. 當用作函數調用的一部分使用時,

    args = (1, 2) 
    kwargs = {'last': 'Doe', 'first': 'John'} 
    self.save_name_for(*args, **kwargs) 
    

    ***充當拆包運營args必須是 可迭代的kwargs必須是類似字符的args 中的項目將被解包並作爲位置參數發送到函數 ,並且kwargs中的鍵/值對將被髮送到函數 關鍵字參數。因此,

    self.save_name_for(*args, **kwargs) 
    

    相當於

    self.save_name_for(1, 2, last='Doe', first='John') 
    

也是saltycrane blog參見用於與實施例的說明。

相關問題