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)

n個のアイテムがある場合でも、ファーストネームは常に最初のアイテム、ラストネームは2番目のアイテムになりますか?

4

2 に答える 2

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]))
于 2013-11-11T17:25:39.743 に答える
1

新しいクラスは、クラスをインスタンス化して新しいインスタンス オブジェクトを作成するのとほぼ同じように、メタクラスをインスタンス化することによって作成されます。次のようなクラスステートメント:

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 は任意の順序であるため、順序は保持されません。

順序をどこかに記録しておく 1 つの方法は、TextFieldクラス自体に、パラメーターの各セットに対して呼び出された順序を登録させることです。その後、フィールドが宣言された順序を復元できます。これはおそらく、Django が内部で行っていることです。

于 2013-11-11T17:32:36.753 に答える