他のすべてのオブジェクトに基本クラスが使用されるシステムを構築しようとしています。すべての基本オブジェクトには内部で_fields
という辞書があり、基本クラスの実装で情報を格納できます。__setattr__と__getattr__を組み合わせると、無限ループが発生します
基本クラスの実装は非常に簡単です:
class A(object):
def __init__(self, fields=dict()):
self._fields = fields
クラスの実装は、そのsuper()
に__init__
呼び出しでフィールドを設定することができます。
私が追加したいのは、@property
デコレータを関数群全体に追加することなく、フィールドをプロパティとしてアクセスできることです。私はそうのように、基本クラスで、この目的のために__getattr__
をオーバーライドしました:
class A(object):
def __init__(self, fields=dict()):
self._fields = fields
def __getattr__(self, name):
if hasattr(self, name):
return object.__getattribute__(self, name)
elif name in self._fields:
return self._fields.get(name)
else:
raise AttributeError
今、このクラスの実装は次のように動作することができます:
class A_impl(A):
def __init__(self):
super(A_impl, self).__init__(
fields=dict(
val_1="foo",
val_2="",
val_3="bar",
)
)
このクラスの実装を作成したことによって得られあなた行うためのオプション:
test = A_imp()
print test.val_1
print test.val_2
print test.val_3
を返します。
私もそうのようなクラスを変更し、@property
デコレータを経由して、これを無効にすることができます:私はリターンのためにデータを操作することができます
class A_impl(A):
def __init__(self):
super(A_impl, self).__init__(
fields=dict(
val_1="foo",
val_2="",
val_3="bar",
)
)
@property
def val_1(self):
return self._fields.get('val_1') + "_getter"
。唯一の問題は、をに設定することができれば、私は記述子設定関数を実装する必要があります。これは、多くの複製作業を作成するプロパティ記述子を作成する必要があります。私がここで避けたいと思っているすべての私の分野の記述子。self._field[name] = value
をデフォルトとして選択する必要がある記述子セッター関数を手動で実装する場合、基本クラスの__setattr__
関数を実装しました。基本クラスは次のようになります(__getattr__
と同様)。
class A(object):
def __init__(self, fields=dict()):
self._fields = fields
def __getattr__(self, name):
if hasattr(self, name):
return object.__getattribute__(self, name)
elif name in self._fields:
return self._fields.get(name)
else:
raise AttributeError
def __setattr__(self, name, value):
if hasattr(self, name):
object.__setattr__(self, name, value)
elif name in self._fields:
self._fields[name] = value
else:
raise AttributeError
は今、私は再び同じコード・テストを実行する場合:
test = A_imp()
print test.val_1
print test.val_2
print test.val_3
それは瞬時に無限ループにはまり、それは__setattr__
で起動しますが、右後__getattr__
にジャンプして、それをループし続けます。
私はこれに関するstackoverflowに関する多くの質問を読んできましたが、それを理解できませんでした。このため、このテストケースをきれいに理解するためです。うまくいけば、誰かが私のためにこれを明確にし、私が問題を解決するのを助けることができます。
「hasattr」は不要です。 – o11c