Python berorientasikan objek
Python telah menjadi bahasa berorientasikan objek dari awal kerana ini, adalah mudah untuk mencipta kelas dan objek dalam Python. Dalam bab ini kami akan memperkenalkan pengaturcaraan berorientasikan objek dalam Python secara terperinci.
Jika anda belum pernah didedahkan kepada bahasa pengaturcaraan berorientasikan objek sebelum ini, anda mungkin perlu terlebih dahulu memahami beberapa ciri asas bahasa berorientasikan objek dan membentuk konsep asas berorientasikan objek dalam fikiran anda, yang akan membantu anda Mempelajari pengaturcaraan berorientasikan objek dengan mudah dalam Python.
Seterusnya, mari kita fahami secara ringkas beberapa ciri asas berorientasikan objek.
Pengenalan kepada teknologi berorientasikan objek
Kelas (Kelas): digunakan untuk menerangkan koleksi objek dengan sifat dan kaedah yang sama. Ia mentakrifkan sifat dan kaedah yang biasa kepada setiap objek dalam koleksi. Objek ialah contoh kelas.
Pembolehubah kelas: Pembolehubah kelas adalah perkara biasa di seluruh objek yang di instantiated. Pembolehubah kelas ditakrifkan di dalam kelas dan di luar badan fungsi. Pembolehubah kelas biasanya tidak digunakan sebagai pembolehubah contoh.
Ahli data: Pembolehubah kelas atau pembolehubah ins digunakan untuk memproses data yang berkaitan dengan kelas dan objek instancenya.
Penulisan semula kaedah: Jika kaedah yang diwarisi daripada kelas induk tidak dapat memenuhi keperluan subkelas, ia boleh ditulis semula. , juga dikenali sebagai kaedah mengatasi.
Pembolehubah tika: Pembolehubah yang ditakrifkan dalam kaedah hanya bertindak pada kelas tika semasa.
Warisan: Iaitu, kelas terbitan mewarisi medan dan kaedah kelas asas. Warisan juga membenarkan objek kelas terbitan untuk dianggap sebagai objek kelas asas. Sebagai contoh, terdapat reka bentuk sedemikian: objek jenis Anjing berasal daripada kelas Haiwan, yang menyerupai perhubungan "ialah-a" (contohnya, Anjing ialah Haiwan).
Instansiasi: Cipta tika kelas, objek khusus kelas.
Kaedah: Fungsi yang ditakrifkan dalam kelas.
Objek: Contoh struktur data yang ditakrifkan oleh kelas. Objek termasuk dua ahli data (pembolehubah kelas dan pembolehubah contoh) dan kaedah.
Buat kelas
Gunakan penyataan kelas untuk mencipta kelas baharu, diikuti dengan kelas ialah nama kelas dan berakhir dengan titik bertindih, sebagai dalam contoh berikut:
class ClassName: '类的帮助信息' #类文档字符串 class_suite #类体
Maklumat bantuan kelas boleh dilihat melalui ClassName.__doc__.
class_suite terdiri daripada ahli kelas, kaedah dan atribut data.
Instance
Berikut ialah contoh kelas Python yang mudah:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: '所有员工的基类' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary
pembolehubah empCount ialah pembolehubah kelas, nilainya akan berada dalam kelas ini Shared antara semua kejadian. Anda boleh mengaksesnya menggunakan Employee.empCount dalam kelas dalam atau kelas luar.
Kaedah pertama __init__() ialah kaedah khas, dipanggil pembina atau kaedah permulaan kelas, yang dipanggil apabila contoh kelas ini dicipta Kaedah
Buat objek contoh
Untuk mencipta tika kelas, anda menggunakan nama kelas dan menerima argumen melalui kaedah __init__.
"创建 Employee 类的第一个对象" emp1 = Employee("Zara", 2000) "创建 Employee 类的第二个对象" emp2 = Employee("Manni", 5000)
Mengakses Sifat
Anda boleh menggunakan titik (.) untuk mengakses sifat objek. Gunakan nama kelas berikut untuk mengakses pembolehubah kelas:
emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Contoh penuh:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: '所有员工的基类' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary "创建 Employee 类的第一个对象" emp1 = Employee("Zara", 2000) "创建 Employee 类的第二个对象" emp2 = Employee("Manni", 5000) emp1.displayEmployee() emp2.displayEmployee() print "Total Employee %d" % Employee.empCount
Laksanakan kod di atas dan hasil output adalah seperti berikut:
Name : Zara ,Salary: 2000 Name : Manni ,Salary: 5000 Total Employee 2
Anda boleh menambah, padam, dan ubah suai atribut kelas , seperti yang ditunjukkan di bawah:
emp1.age = 7 # 添加一个 'age' 属性 emp1.age = 8 # 修改 'age' 属性 del emp1.age # 删除 'age' 属性
Anda juga boleh menggunakan fungsi berikut untuk mengakses atribut:
getattr(obj, name[ , lalai]): akses harta objek.
hasattr(obj,name) : Semak sama ada atribut wujud.
setattr(obj,nama,nilai): Tetapkan atribut. Jika harta itu tidak wujud, harta baru dicipta.
delattr(obj, nama): Padamkan atribut.
hasattr(emp1, 'age') # 如果存在 'age' 属性返回 True。 getattr(emp1, 'age') # 返回 'age' 属性的值 setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8 delattr(empl, 'age') # 删除属性 'age'
Atribut kelas terbina dalam Python
__dict__: atribut kelas (mengandungi kamus yang terdiri daripada atribut data kelas)
__doc__: Rentetan dokumentasi kelas
__name__: Nama kelas
__modul__: Definisi kelas Modul di mana ia terletak (nama penuh kelas ialah '__main__.className', jika kelas terletak dalam modul mymod yang diimport, maka className.__module__ adalah sama dengan mymod)
__bases__: semua kelas induk kelas Elemen konstituen (mengandungi tuple yang terdiri daripada semua kelas induk)
Contoh memanggil atribut kelas terbina dalam Python adalah sebagai berikut:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Employee: '所有员工的基类' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print "Total Employee %d" % Employee.empCount def displayEmployee(self): print "Name : ", self.name, ", Salary: ", self.salary print "Employee.__doc__:", Employee.__doc__ print "Employee.__name__:", Employee.__name__ print "Employee.__module__:", Employee.__module__ print "Employee.__bases__:", Employee.__bases__ print "Employee.__dict__:", Employee.__dict__
Hasil keluaran melaksanakan kod di atas adalah seperti berikut:
Employee.__doc__: 所有员工的基类 Employee.__name__: Employee Employee.__module__: __main__ Employee.__bases__: () Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}
pemusnahan objek python (pengumpulan sampah)
Seperti bahasa Java, Python menggunakan teknologi mudah yang dipanggil pengiraan rujukan untuk mengesan objek dalam ingatan.
Secara dalaman, Python merekodkan bilangan rujukan yang dimiliki oleh setiap objek yang digunakan.Pembolehubah penjejakan dalaman, dipanggil kaunter rujukan.
Apabila objek dicipta, kiraan rujukan dibuat Apabila objek tidak diperlukan lagi. Iaitu, apabila kiraan rujukan objek ini menjadi 0, ia adalah sampah yang dikumpul. Tetapi kitar semula bukanlah "segera"; Jurubahasa akan mengitar semula ruang memori yang diduduki oleh objek sampah pada masa yang sesuai.
a = 40 # 创建对象 <40> b = a # 增加引用, <40> 的计数 c = [b] # 增加引用. <40> 的计数 del a # 减少引用 <40> 的计数 b = 100 # 减少引用 <40> 的计数 c[0] = -1 # 减少引用 <40> 的计数
Mekanisme kutipan sampah bukan sahaja menyasarkan objek dengan kiraan rujukan 0, tetapi juga boleh mengendalikan rujukan bulat. Rujukan bulat berlaku apabila dua objek merujuk antara satu sama lain, tetapi tiada pembolehubah lain merujuk kepada mereka. Dalam kes ini, pengiraan rujukan sahaja tidak mencukupi. Pengumpul sampah Python sebenarnya adalah kaunter rujukan dan pengumpul sampah kitaran. Selain pengiraan rujukan, pemungut sampah juga melihat objek yang telah diperuntukkan dalam jumlah yang besar (dan yang belum dimusnahkan oleh pengiraan rujukan). Dalam kes ini, jurubahasa akan berhenti seketika dan cuba membersihkan sebarang gelung yang tidak dirujuk.
Instance
Destructor __del__, __del__ dipanggil apabila objek dimusnahkan Apabila objek tidak lagi digunakan, kaedah __del__ berjalan:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Point: def __init__( self, x=0, y=0): self.x = x self.y = y def __del__(self): class_name = self.__class__.__name__ print class_name, "销毁" pt1 = Point() pt2 = pt1 pt3 = pt1 print id(pt1), id(pt2), id(pt3) # 打印对象的id del pt1 del pt2 del pt3
di atas Hasil daripada berjalan. contohnya adalah seperti berikut:
3083401324 3083401324 3083401324 Point 销毁
Nota: Biasanya anda perlu mentakrifkan kelas dalam fail berasingan,
Warisan kelas
Objek- berorientasikan Salah satu faedah utama yang dibawa oleh pengaturcaraan ialah penggunaan semula kod, dan salah satu cara untuk mencapai penggunaan semula ini adalah melalui mekanisme pewarisan. Warisan boleh difahami sepenuhnya sebagai hubungan jenis dan subjenis antara kelas.
Perkara yang perlu diberi perhatian: Sintaks warisan nama kelas Terbitan kelas (Nama kelas asas): //... Nama kelas asas ditulis dalam kurungan, dan kelas asas ialah Ia dinyatakan dalam tuple apabila kelas ditakrifkan.
Sesetengah ciri warisan dalam ular sawa:
1: Dalam warisan, pembinaan kelas asas (__init__() kaedah) tidak akan dipanggil secara automatik, ia perlu Panggilnya secara khusus dalam pembina kelas terbitannya.
2: Apabila memanggil kaedah kelas asas, anda perlu menambah awalan nama kelas kelas asas, dan anda perlu membawa pembolehubah parameter diri. Berbeza daripada memanggil fungsi biasa dalam kelas, anda tidak perlu membawa parameter diri
3: Python sentiasa terlebih dahulu mencari kaedah jenis yang sepadan, jika ia tidak dapat mencari yang sepadan kaedah dalam kaedah kelas terbitan, ia mula mencari satu demi satu dalam kelas asas. (Mula-mula cari kaedah panggilan dalam kelas ini, dan kemudian cari dalam kelas asas jika anda tidak menemuinya).
Jika lebih daripada satu kelas disenaraikan dalam tuple warisan, maka ia dipanggil "warisan berbilang".
Sintaks:
Pengisytiharan kelas terbitan, serupa dengan kelas induknya, dengan senarai kelas asas yang diwarisi mengikut nama kelas, seperti berikut:
class SubClassName (ParentClass1[, ParentClass2, ...]): 'Optional class documentation string' class_suite
Instance:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Parent: # 定义父类 parentAttr = 100 def __init__(self): print "调用父类构造函数" def parentMethod(self): print '调用父类方法' def setAttr(self, attr): Parent.parentAttr = attr def getAttr(self): print "父类属性 :", Parent.parentAttr class Child(Parent): # 定义子类 def __init__(self): print "调用子类构造方法" def childMethod(self): print '调用子类方法 child method' c = Child() # 实例化子类 c.childMethod() # 调用子类的方法 c.parentMethod() # 调用父类方法 c.setAttr(200) # 再次调用父类的方法 c.getAttr() # 再次调用父类的方法
Hasil pelaksanaan kod di atas adalah seperti berikut:
调用子类构造方法 调用子类方法 child method 调用父类方法 父类属性 : 200
Anda boleh mewarisi berbilang kelas
class A: # 定义类 A ..... class B: # 定义类 B ..... class C(A, B): # 继承类 A 和 B .....
Anda boleh menggunakan issubclass() atau isinstance( ) kaedah untuk menguji.
issubclass() - Fungsi Boolean untuk menentukan sama ada kelas ialah subkelas atau turunan kelas lain, sintaks: issubclass(sub,sup)
isinstance(obj, Class) Fungsi Boolean mengembalikan benar jika obj ialah objek instance bagi kelas Class atau objek instance subclass Class.
Penulisan semula kaedah
Jika fungsi kaedah kelas induk anda tidak dapat memenuhi keperluan anda, anda boleh mengatasi kaedah kelas induk anda dalam subkelas :
Contoh:
#!/usr/bin/python # -*- coding: UTF-8 -*- class Parent: # 定义父类 def myMethod(self): print '调用父类方法' class Child(Parent): # 定义子类 def myMethod(self): print '调用子类方法' c = Child() # 子类实例 c.myMethod() # 子类调用重写方法
Hasil output untuk melaksanakan kod di atas adalah seperti berikut:
调用子类方法
Kaedah beban asas asas
Jadual berikut menyenaraikan beberapa biasa Anda boleh mengatasi fungsi dalam kelas anda sendiri:
Nombor siri | Kaedah, penerangan & panggilan mudah | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 |
Kaedah panggilan mudah: obj = className(args) | ||||||||||||
2 | < 🎜>__del__ ( self )<🎜> Kaedah pemusnah, padam objek Kaedah panggilan mudah: dell obj | ||||||||||||
<🎜>__repr__( self )<🎜> Tukar kepada borang yang dibaca oleh jurubahasa Kaedah panggilan mudah: repr(obj)< /em> | |||||||||||||
4 | <🎜>__str__( self )<🎜> Digunakan untuk menukar nilai kepada Borang yang boleh dibaca manusia Kaedah panggilan mudah : str(obj) | ||||||||||||
5 | <🎜>__cmp__ ( diri, x )<🎜> Perbandingan objek Kaedah panggilan mudah: cmp(obj, x) |
Operator overloading
Python juga menyokong operator overloading, contohnya adalah seperti berikut:
#!/usr/bin/python class Vector: def __init__(self, a, b): self.a = a self.b = b def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) v2 = Vector(5,-2) print v1 + v2
Hasil pelaksanaan kod di atas adalah seperti berikut:
Vector(7,8)
Atribut kelas Atribut peribadi kelas
__private_attrsdengan kaedah : bermula dengan dua garis bawah, mengisytiharkan bahawa atribut itu peribadi dan tidak boleh digunakan atau secara langsung diakses di luar kelas. Apabila digunakan dalam kaedah di dalam kelas self.__private_attrs.
Kaedah kelas
Dalam kelas, anda boleh menggunakan kata kunci def untuk mentakrifkan kaedah untuk kelas Berbeza daripada definisi fungsi umum, kaedah kelas mesti mengandungi parameter diri, iaitu parameter pertama.
Kaedah peribadi kelas
__kaedah_pribadi: Bermula dengan dua garis bawah, kaedah diisytiharkan sebagai kaedah persendirian dan tidak boleh dipanggil di luar kelas. Memanggil self.__private_methods
instance
#!/usr/bin/python # -*- coding: UTF-8 -*- class JustCounter: __secretCount = 0 # 私有变量 publicCount = 0 # 公开变量 def count(self): self.__secretCount += 1 self.publicCount += 1 print self.__secretCount counter = JustCounter() counter.count() counter.count() print counter.publicCount print counter.__secretCount # 报错,实例不能访问私有变量
Python di dalam kelas dengan menukar nama untuk memasukkan nama kelas:
1 2 2 Traceback (most recent call last): File "test.py", line 17, in <module> print counter.__secretCount # 报错,实例不能访问私有变量 AttributeError: JustCounter instance has no attribute '__secretCount'
Python tidak membenarkan instantiation Kelas mengakses data peribadi, tetapi anda boleh menggunakan object._className__attrName untuk mengakses atribut Gantikan baris terakhir kod di atas dengan kod berikut:
......................... print counter._JustCounter__secretCount
Laksanakan kod di atas dan pelaksanaan. keputusan adalah seperti berikut:
1 2 2 2