web-dev-qa-db-ja.com

Pythonの新しいスタイルのクラスで__setattr__と__getattribute__を適切にオーバーライドするにはどうすればよいですか?

Pythonクラスの__getattribute__および__setattr__メソッドをオーバーライドしたい。私のユースケースは通常のケースです。処理したい特別な名前がいくつかあり、 __getattribute__の場合、AttributeErrorを上げるだけでデフォルトの動作を要求できるようですが、__setattr__で同じことを実現するにはどうすればよいですか?以下は、不変フィールド「A」、「B」、および「C」を持つクラスを実装する簡単な例です。

class ABCImmutable(SomeSuperclass):
    def __getattribute__(self, name):
        if name in ("A", "B", "C"):
            return "Immutable value of %s" % name
        else:
            # This should trigger the default behavior for any other
            # attribute name.
            raise AttributeError()

    def __setattr__(self, name, value):
        if name in ("A", "B", "C"):
            raise AttributeError("%s is an immutable attribute.")
        else:
            # How do I request the default behavior?
            ???

疑問符の代わりに何がありますか?古いスタイルのクラスでは、答えは明らかにself.__dict__[name] = valueでしたが、ドキュメントでは、これが新しいスタイルのクラスでは間違っていることが示されています。

38
Ryan Thompson

それは

super(ABCImmutable, self).__setattr__(name, value)

in Python 2、または

super().__setattr__(name, value)

in Python 3。

また、AttributeErrorを上げると、notになり、__getattribute__のデフォルトの動作に戻ります。あなたはデフォルトにフォールバックします

return super(ABCImmutable, self).__getattribute__(name)

on Python 2または

return super().__getattribute__(name)

on Python 3。

AttributeErrorを上げると、デフォルトの処理をスキップして__getattr__に進むか、__getattr__がない場合は呼び出しコードにAttributeErrorを生成します。

属性アクセスのカスタマイズ のドキュメントを参照してください。

41
Hank Gay

SomeSuperclass.__setattr__(self, name, value)

6
Jeannot