2012-06-09 40 views
1

基類看起來像這樣(代碼來自Django的,但問題是沒有具體的Django):在(* args,** kwargs)python中處理參數初始值的簡單方法是什麼?

class BaseModelForm(BaseForm): 
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, 
       initial=None, error_class=ErrorList, label_suffix=':', 
       empty_permitted=False, instance=None): 

class ModelForm(BaseModelForm): 
    __metaclass__ = ModelFormMetaclass 

派生類看起來是這樣的:

class MyForm(forms.ModelForm): 
    def __init__(self, data=None, files=None, *args, **kwargs): 
     super(EdocForm, self).__init__(data, files, *args, **kwargs) 
     self.Meta.model.get_others(data, files, kwargs.get('instance', None)) 

如果編碼器通過實例作爲克瓦格斯這一切都很好,應該工作,但如果他們不這樣做,並將其傳遞給參數呢?處理* args和** kwargs時,提取實例的方法是什麼?誠然,在這種情況下,實例在參數中的機會很小,但如果它是第三個參數而不是第五個(不包括self)。

回答

0

在接受*args,如果獲取instance事項MyForm一種方式來處理這種情況,是明確包含instance作爲關鍵字參數MyForm,添加實例kwargs,然後傳上來kwargs。

class MyForm(forms.ModelForm): 
    def __init__(self, data=None, files=None, instance=None, *args, **kwargs): 
     kwargs['instance'] = instance 
     super(EdocForm, self).__init__(data, files, *args, **kwargs) 

需要注意的是,如果有人把實例作爲第三位置的說法,他們將作出非常明確的錯誤,因爲實例的最後一個參數BaseModelForm。

但是,處理這種情況的更好方法是明確不允許附加的位置參數。例如:

class MyForm(forms.ModelForm): 
    def __init__(self, data=None, files=None, **kwargs): 
     super(EdocForm, self).__init__(data, files, *args, **kwargs) 
     self.Meta.model.get_others(data, files, kwargs.get('instance', None)) 

這樣,MyForm只能使用最多2個位置參數來調用。任何更多和Python解釋器將生成一個TypeError: <func> takes exactly 2 arguments (# given)

如果您需要使用instance參數,則應明確將其包含在MyForm的關鍵字參數中。否則,你至少應該在文檔字符串中注意它的功能。

如果你繼承BaseModelForm,它有一個self.instance變量,你可以直接通過超級訪問它。例如。 self.instance = super(EdocForm, self).instance。這樣,你可以讓超類處理它需要做的任何事情,併爲實例進行後期處理。 (小心超語法...你需要兩個類和個體經營)

+0

因此,也許廢除所有的位置參數,並迫使kwargs避免以無意的方式使用它會更好。只需要使文檔字符串拼出真正的參數。不是可以想象的最佳解決方案,但它可能是我唯一可以設計的唯一解決方案。 – boatcoder

+0

我想你可以在Python中的'我們都是同意的成年人'這個概念下面提交。另外,如果您是BaseModelForm的子類,並且它有一個self.instance變量,則可以通過super直接訪問它。例如。 'self.instance = super(EdocForm,self).instance'。這樣,你可以讓超類處理它需要做的任何事情,併爲實例進行後期處理。 –

+0

不知道爲什麼我沒有想到這一點。 DOOH! – boatcoder

1

那麼在Django如果實例未通過或它的設置不正確則變得無和初始化然後會爲你 http://docs.nullpobug.com/django/trunk/django.forms.models-pysrc.html#BaseModelForm 創建一個新的實例,但是,這不是你的問題。 如果其他變量設置不正確,可能會引發異常。

如果你想檢查用戶是否正確使用了你的API,那麼它真的取決於你,而在python中這可能是相當令人生畏的,並且檢查實例類型不是很pythonic,雖然有很激烈的爭論網絡關於它是一個好的還是壞的東西,以便擁有如此動態類型的語言。一方面,你可以在動態類型語言中非常高效,另一方面你可以有真正令人討厭的錯誤,其解決方案不是那麼明顯,但是從我自己的經驗來看。

我相信一致性是系統可能具有的最關鍵的東西之一,因此我傾向於始終使用關鍵字值,全部設置爲None,然後簡單地執行斷言以確保所有必需的都不是None。 ,你可以有一個功能,只是檢查你的參數是好的。根據我自己的經驗,關鍵字參數往往是最靈活的,因爲您不需要跟蹤訂單,您可以通過讓被叫方記住它的名字來支付價格。

如果你真的需要「實例」,那麼你可以遍歷使用isinstance獲得實例變量指定參數和/或kwargs,但就像我說如果你堅持,這是不是很Python的....

+0

是啊,這是我在想什麼。我希望有人有這樣做的pythonic方法。 getarg('實例')確實找到了推導路徑並且神奇地做到了。 – boatcoder

相關問題