2017-01-20 5 views
-1

、私は重く、そのようなクラスを使用するコードをクリーンアップしたいと思います:私は__getattr__表記を維持されませんが、あるコンストラクタ引数を追加したい何オブジェクトのような__getattr__と辞書ですが、

class ADict(object): 
    pass 
#example usage 
a = ADict() 
a.attr = 1 

許可されたADictキーのリストは、__getattr____setattr__でチェックされます。それが良いアイデアかどうかとは別に、それは実行可能ですか?どうやって?ここに私の失敗した(ので、無限再帰の動作しません)です:

class ADict(object): 

    def __init__(self, keys): 
    object.__init__(self) 
    self.keys = keys 

    def __getattr__(self, attr): 
    print('hi1') 
    if attr not in object.__getattribute__(self.keys): 
     raise KeyError() 
    return object.__getattr__(self, attr) 

    def __setattr__(self, attr, value): 
    print('hi2') 
    if attr not in object.__getattribute__(self.keys): 
     raise KeyError() 
    return object.__setattr__(self, attr, value) 

a = ADict(['a']) 
a.b = 2 
+0

'もしattrがオブジェクトにないなら.__ getattribute __(self.keys):'なぜattrがself.keys'にないのですか?トレースバックを含む[mcve]を提供できますか? – jonrsharpe

+0

'namedtuple'を試してみませんか? – shx2

+0

@jonrsharpe:トレースバックには、再帰の上限に達したというメッセージがあります。私は "self.keys"と書くのを避けようとしていましたが、とにかく私はそれをやりました。 – d33tah

答えて

0

あなたが探しているものは、スロット魔法の変数です。基本的には、指定されたオブジェクトが持つことができるという属性を制限し、あなたがそれを定義した場合、あなたがされています。しかし

class ADict: 
    __slots__ = ['foo', 'bar', 'baz'] 

a = ADict() 
a.foo = 1    # this will work 

a.another_thing = 1 # this will throw an AttributeError 

あなたが持っていない限り、それは通常は良い考えではないとして、これを実装する前に、ドキュメントをよく見を持っていますアプリケーションのメモリ要件が非常に厳しい

+0

強調すると、 '__slots__'はメモリを節約するために意図されており、いくつかの注意点があります。例えば、クラスが '__slots__'を使用する場合、クラス変数の共通のイディオムを使用してインスタンス変数にデフォルト値を与えることはできません。それを使用する前に必ず文書をお読みください。 –

+0

@SergeBallesta:これは私のラップトップのPy2でのみ動作します。 – d33tah

関連する問題