1

このGenshi Tutorialを読んでいると、次の例が表示されます。

from formencode import Schema, validators

class LinkForm(Schema):
    username = validators.UnicodeString(not_empty=True)
    url = validators.URL(not_empty=True, add_http=True, check_exists=False)
    title = validators.UnicodeString(not_empty=True)

この例を理解する限り、クラスを継承する新しいクラスを作成し、Schemaこのクラスにはusernameurl、 の3 つのメソッドが含まれますtitle。ただし、以前はdef.

とにかく、私の質問はそれについてではありません。クラスの定義を動的にすることが可能かどうか知りたいです。urlたとえば、クラスに参加したくない、またはクラスに参加したくない場合titleがあります。if実行可能のようです( if-statementが満たされている場合にのみ、URLに値を使用して割り当てるだけです。

しかし、フォームに入力したいフィールドが事前にわからない場合はどうすればよいでしょうか? たとえば、ユーザー名、URL、およびタイトルがあります。しかし、後で or が必要な場合はどうでしょうcityage。私はそのようなことをすることができます:

from formencode import Schema, validators

class LinkForm(Schema):

    __init__(self, fields):
          for field in fields:
               condition = fields[field]
               field = validators.UnicodeString(condition)

うまくいかないと思います。この場合の回避策はありますか?

4

3 に答える 3

2

はい、インスタンスにメソッドを動的に追加できます。いいえ、やりたいことはできません。

イニシャライザでメソッドをインスタンスにバインドできます。残念ながら、そこにあるのは記述子であり、それらはクラスにバインドする必要があります。

于 2013-07-22T05:40:26.807 に答える
1

私なら逆に、最初に使用する可能性のあるすべてのフォーム フィールドを定義し、後で不要なものを削除します。

あなたが持っている場合:

from formencode import Schema, validators

class LinkForm(Schema):
    username = validators.UnicodeString(not_empty=True)
    url = validators.URL(not_empty=True, add_http=True, check_exists=False)
    title = validators.UnicodeString(not_empty=True)

次のいずれかを実行できます。

def xy():
    my_form = LinkForm()
    del my_form.url
    …

…またはこれ:

def xy():
    class CustomLinkForm(LinkForm):
        pass
    if …:
        del CustomLinkForm.url
    …

免責事項: 私は FormEncode に詳しくないので、これら 2 つのバージョンのどちらが実際に機能するかは、内部の仕組みに依存する可能性があります。

于 2013-07-22T05:49:36.997 に答える
0

もちろん、後にいくつかの引数を持つコンストラクターを使用できます。selfこれらの引数は、たとえば、クラスの一部のメンバーの値になります。

__init__(self, fields):
          self.fields = []
          for field in fields:
               self.fields = self.fields + field 

Dive into Pythonでこれを参照してください

class FileInfo(UserDict):
    "store file metadata"               
    def __init__(self, filename=None): 
         UserDict.__init__(self)      
         self["name"] = filename 
  1. モジュールや関数と同じように、クラスも doc 文字列を持つことができます (そして持つべきです)。

  2. initは、クラスのインスタンスが作成された直後に呼び出されます。これをクラスのコンストラクターと呼ぶのは魅力的ですが、正しくありません。コンストラクターのように見え (慣例により、initはクラスに対して定義された最初のメソッドです)、コンストラクターのように動作し (クラスの新しく作成されたインスタンスで実行される最初のコード部分です)、さらにはコンストラクターのように聞こえるため、魅力的です。 (「init」は確かにコンストラクターっぽい性質を示唆しています)。initが呼び出されるまでにオブジェクトが既に構築されており、クラスの新しいインスタンスへの有効な参照が既に存在するため、不正解です。しかし、initは Python のコンストラクターに最も近いものであり、ほぼ同じ役割を果たします。

  3. initを含むすべてのクラス メソッドの最初の引数は、常にクラスの現在のインスタンスへの参照です。慣例により、この引数は常に self という名前になります。initメソッドでは、self は新しく作成されたオブジェクトを参照します。他のクラス メソッドでは、メソッドが呼び出されたインスタンスを参照します。メソッドを定義するときは明示的に self を指定する必要がありますが、メソッドを呼び出すときは指定しません。Python が自動的に追加します。

  4. initメソッドは任意の数の引数を取ることができ、関数と同様に、引数をデフォルト値で定義して、呼び出し元のオプションにすることができます。この場合、filename のデフォルト値は Python の null 値である None です。

後の例では、この継承されたクラスを呼び出して、継承されたクラスを処理する方法を学習することに注意してください__init()__

クラス変数またはインスタンス変数に関する質問ではないことに答えるには、これを参照してください

クラス定義で定義された変数はクラス変数です。それらはすべてのインスタンスで共有されます。インスタンス変数を作成するには、self.name = value を使用してメソッドに設定できます。クラス変数とインスタンス変数の両方に「self.name」という表記でアクセスできます。この方法でアクセスすると、インスタンス変数は同じ名前のクラス変数を隠します。クラス変数はインスタンス変数のデフォルトとして使用できますが、可変値を使用すると予期しない結果が生じる可能性があります。新しいスタイルのクラスの場合、記述子を使用して、実装の詳細が異なるインスタンス変数を作成できます。

于 2013-07-22T05:37:26.650 に答える