Pertanyaan Bagaimana cara mengganti __setattr__ dan __getattribute__ dengan benar pada kelas-kelas gaya baru dengan Python?


Saya ingin mengganti kelas Python saya __getattribute__ dan __setattr__ metode. Kasus penggunaan saya adalah yang biasa: Saya memiliki beberapa nama khusus yang ingin saya tangani, dan saya ingin perilaku default untuk hal lain. Untuk __getattribute__, sepertinya saya bisa meminta perilaku default hanya dengan membesarkan AttributeError. Namun, bagaimana saya bisa mencapai hal yang sama di __setattr__? Berikut adalah contoh sepele, menerapkan kelas dengan bidang yang tidak berubah "A", "B", dan "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?
            ???

Apa yang menggantikan tanda tanya? Dengan kelas-kelas gaya lama, jawabannya rupanya self.__dict__[name] = value, tetapi dokumentasi menunjukkan bahwa ini salah untuk kelas gaya baru.


32
2017-08-12 15:10


asal


Jawaban:


Nya

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

dengan Python 2, atau

super().__setattr__(name, value)

dengan Python 3.

Juga, membesarkan AttributeError aku s tidak bagaimana Anda kembali ke perilaku default untuk __getattribute__. Anda kembali ke default dengan

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

pada Python 2 atau

return super().__getattribute__(name)

pada Python 3.

Pemeliharaan AttributeError melompati penanganan default dan pergi ke __getattr__, atau hanya menghasilkan AttributeError dalam kode panggilan jika tidak ada __getattr__.

Lihat dokumentasi di Menyesuaikan Akses Atribut.


31
2017-08-12 15:15



SomeSuperclass.__setattr__(self, name, value) ?


5
2017-08-12 15:12