Atribut Kelas Metamorfosis

Sebuah catatan pendek dari seri "Kamu diperingatkan."

Beralih dari bahasa pemrograman klasik ke Python membawa banyak kejutan.
Baca dokumentasinya:
Secara umum, variabel instance adalah untuk data yang unik untuk setiap instance dan variabel kelas adalah untuk atribut dan metode yang digunakan bersama oleh semua instance kelas
Mari kita coba main-main

class Vessel: #class attribute vtype = "boat" #instance attribute def __init__(self, name): self.name = name #    def __str__(self): res= '>>' for a in inspect.getmembers( self): if not a[0].startswith("__"): res += f"{a[0]}={a[1]:<14}" for a in inspect.getmembers( self.__class__): if not a[0].startswith("__"): res += f"__class__.{a[0]}={a[1]:<14}" return res 


Buat dua objek, periksa nilai semua atribut:

 Iowa = Vessel("Iowa") Drum=Vessel("Drum") printAttr(Iowa, Drum) >>name=Iowa vtype=boat __class__.vtype=boat >>name=Drum vtype=boat __class__.vtype=boat 

Sejauh ini, seperti yang diharapkan.

Mari kita coba untuk mengubah vtype: ini dapat dilakukan dengan dua cara, yang pada dasarnya hanya berbeda dari sintaks yang sama

 Vessel.vtype = "USS boat" printAttr(Iowa, Drum) >>name=Iowa vtype=USS boat __class__.vtype=USS boat >>name=Drum vtype=USS boat __class__.vtype=USS boat Iowa.__class__.vtype = 'USS WW2 Boat' printAttr(Iowa, Drum) >>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat >>name=Drum vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat 

Dan lagi, semuanya beres.

Sekarang mari kita coba melakukan hal yang sama melalui atribut objek.

 Drum.vtype = 'submarine' printAttr(Iowa, Drum) >>name=Iowa vtype=USS WW2 Boat __class__.vtype=USS WW2 Boat >>name=Drum vtype=submarine __class__.vtype=USS WW2 Boat 

Dan di sini adalah kejutan pertama: meskipun fakta bahwa vtype adalah atribut kelas, tiba-tiba itu menjadi atribut objek.

Periksa:

 Vessel.vtype = "NAVY Museum" >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=submarine __class__.vtype=NAVY Museum 

bagaimana jika ...

  del Drum.vtype >>name=Iowa vtype=NAVY Museum __class__.vtype=NAVY Museum >>name=Drum vtype=NAVY Museum __class__.vtype=NAVY Museum 

Dan lagi atribut kelas.

Ungkapan berikut tidak lagi berlalu

 del Drum.vtype printAttr(Iowa, Drum) del Drum.vtype AttributeError: vtype 

Dan contoh terakhir meniru override kelas dan menghapus atribut vtype.

 Drum.vtype = 'submarine' del Vessel.vtype printAttr(Iowa, Drum) >>name=Iowa >>name=Drum vtype=submarine 

Jika Anda mulai berurusan dengan namespace, perilaku ini menjadi dapat dimengerti.
Namun, untuk programmer yang sebelumnya bekerja dengan bahasa normal, ini setidaknya tampak aneh. Dan jika kita berbicara tentang proyek-proyek besar yang didukung oleh beberapa generasi pengembang, ini bisa berubah menjadi kegagalan tenggat waktu, dll.

Mempertimbangkan konsep Python bahwa semuanya terbuka untuk semua orang, mengapa tidak membuat akses ke atribut "keren" hanya melalui __class__ atau analognya. Menurut pendapat saya, ini setidaknya akan entah bagaimana melindungi terhadap kejutan dan membuat saya berpikir 10 kali sebelum menetapkan sesuatu ke atribut kelas di tingkat objek.

Pembaruan: Teks PrintAttr

 def printAttr(*o): for a in o: print(a) 

Source: https://habr.com/ru/post/id427065/


All Articles