[英]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.