簡體   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