2009-02-01 25 views
3

我已經創建了一個生成一個新的類,並增加了一些方法進級,但有一個奇怪的錯誤的方法,我不知道發生了什麼:如何在代碼中創建python方法(簽名和內容)?

def make_image_form(image_fields): 
    ''' Takes a list of image_fields to generate images ''' 
    images = SortedDict() 
    for image_name in image_fields: 
     images[image_name] = forms.ImageField(required=False) 
    new_form = type('ListingImagesForm2', (forms.BaseForm,), {'base_fields' : images}) 
    #now we add the validation methods to the class 
    for image_name in image_fields: 
     print "image name is: ", image_name 
     setattr(new_form, 'clean_' + image_name, lambda self: self._clean_photo(image_name)) 
    #Add the _clean_photo method to the class 
    setattr(new_form, '_clean_photo', _clean_photo) 
    return new_form 

這是我的方法,它需要一個image_fields列表(我在Django中創建一個站點),並創建一大堆ImageField字段,並創建一個類ListingImagesForm2,並將圖像字段分配給該類。

問題在於創建方法,更具體地說是方法內容。

在循環:

for image_name in image_fields: 
    print "image name is: ", image_name 
    setattr(new_form, 'clean_' + image_name, lambda self: self._clean_photo(image_name)) 

正確創建簽名的方法(例如clean_pic_1,clean_pic_2 ...),但我認爲這是在lambda表達式的一個問題,因爲_clean_photo方法總是叫具有相同的圖像名稱(恰好是image_fields列表中的最後一個圖像名稱)。

有沒有比使用lambda表達式創建動態方法內容(代碼)更好的方法?

爲什麼我的lambda表達式只傳遞_clean_photo for循環中的最後一個image_name?

+0

注意修改代碼的縮進?尤其在python中,它非常重要,它是正確的。 – 2009-02-01 01:14:28

回答

4

對於在方法範圍中定義的函數,Python代碼的行爲如此。 使用這個代替:

for image_name in image_fields: 
    print "image name is: ", image_name 
    setattr(new_form, 'clean_' + image_name, 
      lambda self, iname=image_name: self._clean_photo(iname)) 

默認關鍵字參數的使用使得Python的記得它在lambda函數創建的時間,而不是在它的通話時間(當它總是拿最後一個圖像)。

相關問題