Python terkenal dengan kesederhanaan dan kebolehbacaannya, tetapi apabila melibatkan pengaturcaraan berorientasikan objek (OOP), terdapat beberapa mekanisme yang kurang dibincangkan yang penting untuk menulis kod yang mantap. Salah satu mekanisme tersebut adalah nama mencabul. Artikel ini akan membimbing anda tentang apakah nama mangling, sebab Python menggunakannya dan cara ia boleh membantu mengelakkan perlanggaran nama dalam hierarki kelas yang kompleks.
Python membenarkan kaedah dalam kelas ditindih oleh subkelas. Walau bagaimanapun, ini kadangkala boleh menyebabkan konflik nama apabila subkelas secara tidak sengaja mengatasi atribut atau kaedah daripada kelas induk. Name mangling ialah mekanisme yang digunakan Python untuk mengelakkan konflik ini, khususnya untuk atribut yang dimaksudkan untuk peribadi.
Name mangling dalam Python ialah ciri di mana jurubahasa menukar nama sifat kelas persendirian untuk meminimumkan risiko ia diakses dan ditindih secara tidak sengaja. Ini menyediakan tahap privasi dalam atribut kelas, walaupun ia tidak dikuatkuasakan dengan ketat. Walau bagaimanapun, ia bukanlah satu penguatkuasaan yang ketat.
Dalam Python, mana-mana pengecam dengan dua garis bawah utama (__) dan tidak lebih daripada satu garis bawah mengekor akan mengalami gangguan nama. Jurubahasa menukar nama dengan memberi awalan dengan nama kelas.
Untuk mengelakkan konflik penamaan, terutamanya dalam situasi apabila subkelas mungkin mempunyai pembolehubah sendiri yang mungkin mengatasi pembolehubah dalam kelas induk, Python melaksanakan name mangling. Name mangling menangani masalah ini.
from datetime import datetime, timedelta from time import time, sleep class Machine: def __init__(self, id): self.id = id self._started = time() def uptime(self): return time() - self._started class PetrolMachine(Machine): def __init__(self, id): super().__init__(id) self._started = datetime.now() def cost(self): duration = datetime.now() - self._started return duration/timedelta(seconds=60) *0.02 worked = PetrolMachine('12345') sleep(0.123) print(f"uptime : {worked.uptime():.2f}")
Dalam contoh ini, kelas Mesin menyimpan ID dan merekodkan masa mula menggunakan fungsi masa() Python. Apabila anda meminta masa aktif, ia mengira perbezaan antara masa semasa dan masa mula, yang disimpan sebagai nombor titik terapung. Subkelas PetrolMachine, bagaimanapun, menyimpan masa mula menggunakan datetime.now(). Apabila kita cuba mengira masa hidup, atur cara melemparkan ralat kerana ia menjangkakan start_time menjadi nombor titik terapung, tetapi ia kini menjadi objek datetime. Konflik penamaan ini boleh berlaku apabila atribut subkelas secara tidak sengaja mengatasi atribut kelas induk. Perpecahan nama membantu mengelakkan isu ini.
Jadi, bagaimanakah name mangling membantu menyelesaikan isu ini? Apabila atribut kelas diawali dengan dua garis bawah, Python menukar nama secara dalaman untuk memasukkan nama kelas sebagai awalan. Begini cara anda boleh mengubah suai kelas Mesin untuk mengelakkan percanggahan nama menggunakan penggubahan nama:
Kami boleh menyelesaikan ralat dengan menggunakan name mangling pada atribut __started dalam kelas Mesin, seperti ditunjukkan di bawah:
from datetime import datetime, timedelta from time import time, sleep class Machine: def __init__(self, id): self.id = id self.__started = time() def uptime(self): return time() - self.__started class PetrolMachine(Machine): def __init__(self, id): super().__init__(id) self._started = datetime.now() def cost(self): duration = datetime.now() - self._started return duration/timedelta(seconds=60) *0.02 worked = PetrolMachine('12345') sleep(0.123) print(f"uptime : {worked.uptime():.2f}")
Cara mudah untuk menyatakan nama yang bergelora ditunjukkan di bawah. Saya mempunyai KelasA kelas, yang mempunyai satu pembolehubah_peribadi, iaitu nama hancur.
class MyClass: def __init__(self): self.__private_var = "I am private" def get_private_var(self): return self.__private_var my_object = MyClass() print(my_object.get_private_var()) # This works print(my_object.__private_var)
Cetakan() kedua akan menimbulkan AttributeError kerana pembolehubah __private_var telah dimusnahkan nama. Secara dalaman, Python telah menukar nama kepada _MyClass__private_var, menjadikannya lebih sukar untuk mengakses dari luar kelas.
Walaupun nama Python yang merosakkan direka untuk menghalang akses tidak sengaja, ia tidak menguatkuasakan privasi yang ketat. Anda masih boleh mengakses atribut hancur dengan menggunakan nama hancur penuh, walaupun ini tidak digalakkan. Begini cara ia berfungsi: my_object._MyClass__private_var
print(my_object._MyClass__private_var)
Saya akan menerangkannya melalui contoh mudah
class MyClass: def __init__(self): self._protected_var = "I'm protected" self.__private_var__ = "I'm not mangled"
Dalam Python, garis bawah tunggal terkemuka (cth., _protected_var) menunjukkan bahawa atribut itu "dilindungi" dan tidak boleh diakses terus dari luar kelas. Walau bagaimanapun, Python tidak menguatkuasakan ini. Sebaliknya, nama dengan dua garis bawah utama (cth., __private_var) rosak untuk mengelakkan overriding secara tidak sengaja. Yang penting, nama dengan garis bawah berganda pada kedua-dua belah (cth., __istimewa__) tidak rosak dan dikhaskan untuk kes penggunaan khas seperti kaedah sihir.
_ Walaupun terdapat batasan ini, pemecahan nama kekal sebagai alat yang berguna dalam kit alat OOP Python. Walaupun ia bukan penguatkuasaan privasi yang ketat, ia membantu mengelakkan konflik penamaan dan mengatasi atribut yang tidak disengajakan. Memahami pemecahan nama akan membolehkan anda menulis kod yang lebih mantap dan boleh diselenggara, terutamanya apabila bekerja dengan hierarki kelas yang kompleks. Cuba dalam projek anda, dan kongsi pengalaman atau soalan anda dalam ulasan di bawah!_
Atas ialah kandungan terperinci Meneroka Nama Mangling dalam Python: Apa Itu dan Cara Ia Berfungsi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!