繁体   English   中英

类中属性的顺序

[英]Order of attributes in a class

在python中是否保证保持类中属性的顺序? 如何保证? 在手册中指定的地方?

这将字段声明性地定义为类属性:

class MyForm(Form):
    first_name = TextField(u'First Name', validators=[validators.required()])
    last_name  = TextField(u'Last Name', validators=[validators.optional()])
    ...


def get(self):
    form = MyForm(self.request.arguments)
    form=form
    self.render('forms.html', form=form)

即使我有n个项目,名字始终是第一个项目,姓氏始终是第二项目?

不,通常无法保证属性的顺序,因为Python将属性存储在字典中。

取而代之的是, wtforms使用特殊技巧来检测定义字段的顺序,从而解决此问题。 每次创建Field对象时,都会增加一个计数器,并为该字段实例分配一个唯一的编号。 这使对象可排序:

class UnboundField(object):
    _formfield = True
    creation_counter = 0

    def __init__(self, field_class, *args, **kwargs):
        UnboundField.creation_counter += 1
        # [...]
        self.creation_counter = UnboundField.creation_counter

因此, Field实例的creation_counter值每次将新字段添加到表单时都会增加。

然后, FormMeta类在字段上使用该值以正确的顺序对它们进行排序:

fields.sort(key=lambda x: (x[1].creation_counter, x[0]))

通过实例化一个元类来创建一个新类,就像您通过实例化该类来创建一个新的实例对象一样。 类声明如下:

class MyForm(Form):
    first_name = TextField(u'First Name', validators=[validators.required()])
    last_name  = TextField(u'Last Name', validators=[validators.optional()])    

等效于以下调用,其中type是默认的python元类:

MyForm = type('MyForm', (Form,), {'first_name': TextField(u'First Name', validators=[validators.required()]), 
                                  'last_name': TextField(u'Last Name', validators=[validators.optional()])}

由于类名称空间作为dict传递,并且dict具有任意顺序,因此不会保留该顺序。

保持顺序记录在某处的一种方法是让TextField类本身为每个参数集注册调用顺序。 然后,您可以恢复声明字段的顺序。 这可能是Django在后台执行的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM