2013-11-11 8 views
1

? Что такое 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) 

Имя будет всегда первым пунктом и фамилия второго, даже если у меня есть п элементы?

ответ

7

Нет, порядок атрибутов обычно не гарантирован, так как 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])) 
+0

Для тех, кто заинтересован в подробном объяснении этого, я рекомендую книгу Марти Алчина * Pro Django *, которая выходит на определенную глубину. –

+0

Полезно знать о взломе Django, спасибо. (+1) – NPE

+0

Конечно, это было до метода '__prepare__' в 3.x, что позволяет изменить базовый метод, используемый для поиска атрибутов (например, OrderedDict) ... –

1

новый класс создается инстанцировании метакласса, довольно много, как вы создаете новый экземпляр объекта с помощью инстанцировании класс. Класс заявление типа:

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

эквивалентно следующий вызов, где type является питон по умолчанию метакласс:

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

Поскольку пространство имен класса передается вперед, как Dict, и dicts имеют произвольные порядок, порядок не сохраняется.

Один из способов сохранить заказ, записанный где-то, - это сам класс TextField, регистрирующий порядок, в котором он был вызван для каждого набора параметров. Затем вы можете восстановить порядок, в котором были объявлены поля. Вероятно, это то, что делает Django под капотом.

Смежные вопросы