【问题标题】:How do you create python methods(signature and content) in code?如何在代码中创建 python 方法(签名和内容)?
【发布时间】:2010-10-04 17:43:44
【问题描述】:

我创建了一个生成新类并向类中添加一些方法的方法,但是有一个奇怪的错误,我不确定发生了什么:

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?

【问题讨论】:

  • 介意修改代码的缩进吗?特别是在 python 中,它的正确性非常重要。
  • 如果您仍在学习 Python,我建议您在这里尝试另一种解决方案:正如您所发现的,动态类创建可能会让您感到困惑!如何在其他地方定义一个泛型类并根据图像自定义其属性?不完全是你现在所拥有的,但很接近..

标签: python django dynamic methods lambda


【解决方案1】:

对于在方法范围内定义的函数,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 函数时记住它,而不是在调用时(它总是取最后一张图像)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2020-02-16
    • 2016-11-02
    • 2013-01-16
    相关资源
    最近更新 更多