6

私はPythonの初心者で、Pythonのドット名検索プロセスを試すのに非常に苦労しています。これらの代入ステートメントが正常に機能するように、「make.py」でクラスまたは関数をコーディングするにはどうすればよいですか?

import make

make.a.dot.separated.name = 666
make.something.else.up = 123
make.anything.i.want = 777
4

1 に答える 1

19
#!/usr/bin/env python

class Make:
    def __getattr__(self, name):
        self.__dict__[name] = Make()
        return self.__dict__[name]

make = Make()

make.a.dot.separated.name = 666
make.anything.i.want = 777

print make.a.dot.separated.name
print make.anything.i.want

__getattr__名前付きの値が見つからない場合は、特別なメソッドが呼び出されます。この行make.anything.i.wantは、次と同等の処理を実行することになります。

m1 = make.anything    # calls make.__getattr__("anything")
m2 = m1.i             # calls m1.__getattr__("i")
m2.want = 777

上記の実装では、これらの呼び出しを使用して、不明なプロパティにアクセスするたび__getattr__にオブジェクトのチェーンを作成します。Makeこれにより、実際の値が割り当てられる最終的な割り当てまで、ドットアクセスを任意の深さでネストできます。

Pythonドキュメント-属性アクセスのカスタマイズ

object.__getattr__(self, name)

属性ルックアップが通常の場所で属性を検出しなかった場合に呼び出されます(つまり、インスタンス属性でも、のクラスツリーでも検出されませんself)。name属性名です。このメソッドは、(計算された)属性値を返すか、AttributeError例外を発生させる必要があります。

属性が通常のメカニズムで見つかった場合、__getattr__()は呼び出されないことに注意してください。__getattr__()(これはとの間の意図的な非対称性__setattr__()です。)これは、効率上の理由と__getattr__()、インスタンスの他の属性にアクセスする方法がないために行われます。少なくともインスタンス変数については、インスタンス属性ディクショナリに値を挿入しない(代わりに別のオブジェクトに値を挿入する)ことで、完全な制御を偽造できることに注意してください。__getattribute__()新しいスタイルのクラスで実際に完全な制御を取得する方法については、以下のメソッドを参照してください。

object.__setattr__(self, name, value)

属性の割り当てが試行されたときに呼び出されます。これは、通常のメカニズムの代わりに呼び出されます(つまり、値をインスタンスディクショナリに格納します)。nameは属性名、valueはそれに割り当てられる値です。

__setattr__()インスタンス属性に割り当てたい場合は、単に実行するべきではありませんself.name = value。これにより、それ自体が再帰的に呼び出されます。代わりに、インスタンス属性のディクショナリに値を挿入する必要がありますself.__dict__[name] = value。新しいスタイルのクラスの場合、インスタンスディクショナリにアクセスするのではなく、同じ名前の基本クラスメソッドを呼び出す必要があります(例:object.__setattr__(self, name, value)

于 2009-10-21T18:55:25.450 に答える