4

以下のコードに示すように__setattr__、メソッドをオーバーロードするクラスの一部である dict に値を設定するために使用できないのはなぜですか? 私はそれが存在しないことを期待してb.helloいました。

class MyClass():

    datastore = {}

    def __init__(self):
        self.datastore = {}

    def __getattr__(self, key):
        return self.datastore[key]

    def __setattr__(self, key, value):
        self.datastore[key] = value

a = MyClass()
b = MyClass()

a.hello = "err"

print a.hello # err
print b.hello # err
4

2 に答える 2

3

b.hellodatastoreクラスのオブジェクトではなく、クラス自体の属性であるため、文字列「err」を出力します。したがって、 で初期化すると、aからbもアクセスできます。

datastore = {}したがって、クラスからを削除します。

さらに、Python docsから:

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

したがって、コードを次のように変更します。

class MyClass(object): # Use new style classes
    def __init__(self):
        object.__setattr__(self, 'datastore', {}) # This prevents infinite recursion when setting attributes

    def __getattr__(self, key):
        return self.datastore[key]

    def __setattr__(self, key, value):
        self.datastore[key] = value

a = MyClass()
b = MyClass()

a.hello = "err"

print a.hello # Works
print b.hello # Gives an error
于 2013-04-23T14:20:01.707 に答える