仅向一个已定义的类发送多个参数

时间:2013-05-30 00:44:39

标签: python django

我对Python比较新,我来自Java,在编译时一切都非常明确,所以也许我在这里遗漏了一些东西。我有一个如此定义的类:

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file = forms.FileField()

然后我就像这样使用它:

...
form = UploadFileForm(request.POST, request.FILES)
...

我将两个参数传递给了这个类,为什么在运行时这不会给我带来某种异常?我试用它时运行正常。我知道Python确实接受了可变数量的参数,但在这种情况下我没有正确的语法。我想知道为什么这样做可以。

1 个答案:

答案 0 :(得分:8)

我认为你在这里混合了类和函数。

此:

class UploadFileForm(forms.Form):

...不是函数定义,它是类定义。它声明UploadFileForm的(唯一)超类是forms.Form

执行此操作时:

form = UploadFileForm(request.POST, request.FILES)

效果与此伪代码类似:

form = make new UploadFileForm
form.__init__(request.POST, request.FILES)

如果您定义了__init__方法,则会以formrequest.POSTrequest.FILES作为参数。

由于您没有定义__init__方法,因此您从父类继承了该方法,因此 it 获取这三个参数。


这几乎与以下Java伪代码完全相同:

class UploadFileForm extends forms.Form {
    static forms.CharField title = forms.CharField(50);
    static forms.FileField file = forms.FileField();
};

UploadFileForm form = new UploadFileForm(request.POST, request.FILES);

就像在Python中一样,它可以工作,因为你从基类继承了构造函数。在Form的某处,有一个这样的声明:

public Form(int verb, int obj) {
    // blah blah
}

而且,在Python中,同样的事情也是如此:

def __init__(self, verb, obj):
    # blah blah

换句话说,Python几乎与Java一样明确(事实上,稍微多一点,因为self参数是显式的)。


另请注意,您的Python类属性与Java中的静态成员等效。如果您想要普通的实例成员,通常会覆盖__init__并将其设置为self.title等。 (你没有这样做 - Python允许你随时添加新成员到你的对象。但它是显而易见的地方。)对于Django,这实际上很常见 - 您创建Django框架超类用于代表您填充初始实例属性的类属性。


最后,reference documentation for Django's forms.Form class实际上并没有显示参数,因为(至少)有四种常见的不同方法来构造Form子类,所有这些都是单独描述的:

MyForm() # creates an unbound form
MyForm(data) # creates a bound form
MyForm(data, files) # creates a bound file or image form
MyForm(initial=initial_data) # creates an unbound form with initial data

其中一些接受其他可选关键字参数。

实际的源代码here显示了真实的原型:

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

当然,并非所有关键字组合都有意义。

无论如何,你可以看到为什么他们没有尝试以简单的方式解释Form