1

基本クラスは次のようになります(コードはDjangoから取得されますが、質問はDjango固有ではありません):

class BaseModelForm(BaseForm):
    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None,
                 initial=None, error_class=ErrorList, label_suffix=':',
                 empty_permitted=False, instance=None):

class ModelForm(BaseModelForm):
    __metaclass__ = ModelFormMetaclass

派生クラスは次のようになります。

class MyForm(forms.ModelForm):
    def __init__(self, data=None, files=None, *args, **kwargs):
        super(EdocForm, self).__init__(data, files, *args, **kwargs)
        self.Meta.model.get_others(data, files, kwargs.get('instance', None))

コーダーがインスタンスをkwargsとして渡す場合、これはすべて問題なく機能するはずですが、そうでない場合は、代わりにargsで渡しますか?*argsと**kwargsを処理するときにインスタンスを抽出するための正しい方法は何ですか?確かに、この場合、インスタンスがargsに含まれる可能性は低いですが、それが5番目ではなく3番目の引数である場合(自己を数えません)。

4

2 に答える 2

1

djangoでは、インスタンスが渡されないか、適切に設定されていない場合、Noneになり、initは新しいインスタンスを作成します http://docs.nullpobug.com/django/trunk/django.forms.models-pysrc.html #BaseModelForm しかし、これはあなたの質問ではありません。他の変数が適切に設定されていない場合、例外が発生する可能性があります。

ユーザーがAPIを適切に使用しているかどうかを確認したい場合は、本当にあなた次第です。Pythonでは、これは非常に困難な場合があり、インスタンスタイプの確認はそれほどPython的ではありません。ウェブ上では、かどうかについて非常に激しい議論があります。動的に型付けされる言語を持つことは良いことでも悪いことでもあります。一方では、動的に型付けされた言語で非常に生産的になることができ、他方では、解決策がそれほど明白ではない本当に厄介なバグを持つ可能性がありますが、それは私自身の経験によるものです。

一貫性はシステムが持つことができる最も重要なものの1つであると私は信じています。そのため、私は常にキーワード値を使用する傾向があり、すべてNoneに設定してから、必要なものがすべてNoneでないことを確認するために単にアサートを実行します。パラメータをチェックするだけの機能が良いです。私自身の経験から、キーワード引数は最も柔軟である傾向があります。注文を追跡する必要がないため、呼び出し先に名前を覚えてもらうことで代金を支払います。

'instance'が本当に必要な場合は、isinstanceを使用してargsやkwargsを反復処理してインスタンス変数を取得できますが、これはあまりPythonicではありません。

于 2012-06-09T04:56:55.493 に答える
0

を受け入れることを主張する場合、問題が発生した場合に*argsこの状況を処理する1つの方法は、キーワード引数として明示的にインクルードし、インスタンスをkwargsに追加してから、kwargsを渡すことです。instanceMyForminstanceMyForm

class MyForm(forms.ModelForm):
    def __init__(self, data=None, files=None, instance=None, *args, **kwargs):
        kwargs['instance'] = instance
        super(EdocForm, self).__init__(data, files, *args, **kwargs)

インスタンスがBaseModelFormの最後の引数であるため、誰かがインスタンスを3番目の位置引数として配置すると、非常に明示的なエラーが発生することに注意してください。

ただし、この状況を処理するためのより良い方法は、追加の位置引数を明確に許可しないことです。例えば:

class MyForm(forms.ModelForm):
    def __init__(self, data=None, files=None, **kwargs):
        super(EdocForm, self).__init__(data, files, *args, **kwargs)
        self.Meta.model.get_others(data, files, kwargs.get('instance', None))

このように、MyForm最大​​2つの位置引数でのみ呼び出すことができます。これ以上、Pythonインタープリターはを生成しTypeError: <func> takes exactly 2 arguments (# given)ます。

引数を使用する必要がある場合instanceは、キーワードargumentsに明示的に含める必要がありますMyForm。それができない場合は、少なくとも関数のdoc文字列に注意する必要があります。

BaseModelFormをサブクラス化していて、self.instance変数がある場合は、superを介して直接アクセスできます。例self.instance = super(EdocForm, self).instance:このようにして、スーパークラスにインスタンスで必要な処理を行わせ、後処理のためにインスタンスを取得します。(superの構文には注意してください...クラスと自己の両方が必要です)

于 2012-06-09T05:02:06.320 に答える