2009-02-01 7 views
3

나는 새로운 클래스를 생성하고 클래스에 몇 가지 방법을 추가하지만 이상한 버그가있는 방법을 만들었습니다, 나는 무슨 일이 일어나고 있는지 확실하지 않다 :코드에서 파이썬 메소드 (서명 및 내용)를 어떻게 작성합니까?

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 (나는 장고에서 사이트를 만들고있다.)의 목록을 가져 와서 ImageField 필드를 만들고, ListImagesForm2 클래스를 만들고 이미지 필드를 클래스에 할당한다.

문제는 메서드, 특히 메서드 콘텐츠를 만드는 데 있습니다. 루프에서

:

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 ...)하지만 난 _clean_photo 방법은 항상 호출로 람다 식에 문제가 있다고 생각 동일한 이미지 이름 (image_fields 목록에서 마지막 이미지 이름이됩니다).

람다 식을 사용하는 것보다 동적 메서드 콘텐츠 (코드)를 만드는 데 유용한 방법이 있습니까?

그리고 왜 내 람다 표현식은 for 루프에서 _clean_photo의 마지막 image_name 만 전달할 수 있습니까?

+0

코드의 들여 쓰기를 수정 하시겠습니까? 파이썬에서 특히, 그것이 옳다는 것이 매우 중요합니다. –

+0

아직 파이썬을 배우고 있다면, 대체 솔루션을 사용해보십시오. 찾은 것처럼 동적 클래스 생성이 혼란 스러울 수 있습니다! 일반 클래스를 다른 곳에서 정의하고 이미지를 기반으로 속성을 사용자 정의하는 방법은 어떻습니까? 지금 당신이 가진 것만은 아니지만 닫습니다. –

답변

4

파이썬 코드는 메소드 범위에 정의 된 함수에서 이와 같이 작동합니다. 사용이 대신 :

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)) 

기본 키워드 인수의 사용은 파이썬이 수는 람다 함수 작성시 아닌 (항상 마지막 이미지를 취할 것)의 호출시를 기억한다.