Python - Berorientasi Objek

Python telah menjadi bahasa berorientasi objek sejak ada. Karena itu, membuat dan menggunakan kelas dan objek sangatlah mudah. Bab ini membantu Anda menjadi ahli dalam menggunakan dukungan pemrograman berorientasi objek Python.

Jika Anda tidak memiliki pengalaman sebelumnya dengan pemrograman berorientasi objek (OO), Anda mungkin ingin berkonsultasi dengan kursus pengantar tentang itu atau setidaknya tutorial semacam itu sehingga Anda memiliki pemahaman tentang konsep dasar.

Namun, berikut adalah pengenalan kecil Pemrograman Berorientasi Objek (OOP) untuk membawa Anda dengan cepat -

Tinjauan Terminologi OOP

  • Class- Prototipe yang ditentukan pengguna untuk objek yang mendefinisikan sekumpulan atribut yang mencirikan objek kelas. Atributnya adalah anggota data (variabel kelas dan variabel instan) dan metode, diakses melalui notasi titik.

  • Class variable- Variabel yang digunakan bersama oleh semua instance kelas. Variabel kelas didefinisikan di dalam kelas tetapi di luar metode kelas mana pun. Variabel kelas tidak digunakan sesering variabel instan.

  • Data member - Variabel kelas atau variabel instan yang menyimpan data yang terkait dengan kelas dan objeknya.

  • Function overloading- Penetapan lebih dari satu perilaku ke fungsi tertentu. Operasi yang dilakukan bervariasi menurut tipe objek atau argumen yang terlibat.

  • Instance variable - Variabel yang didefinisikan di dalam metode dan hanya dimiliki oleh instance kelas saat ini.

  • Inheritance - Pengalihan karakteristik kelas ke kelas lain yang diturunkan darinya.

  • Instance- Objek individu dari kelas tertentu. Sebuah object obj yang termasuk dalam class Circle, misalnya, adalah turunan dari class Circle.

  • Instantiation - Pembuatan instance kelas.

  • Method - Jenis fungsi khusus yang didefinisikan dalam definisi kelas.

  • Object- Contoh unik dari struktur data yang ditentukan oleh kelasnya. Objek terdiri dari anggota data (variabel kelas dan variabel instan) dan metode.

  • Operator overloading - Penetapan lebih dari satu fungsi ke operator tertentu.

Membuat Kelas

The kelas pernyataan menciptakan definisi kelas baru. Nama kelas segera mengikuti kelas kata kunci diikuti oleh titik dua sebagai berikut -

class ClassName:
   'Optional class documentation string'
   class_suite
  • Kelas memiliki string dokumentasi, yang dapat diakses melalui ClassName .__ doc__ .

  • The class_suite terdiri dari semua pernyataan komponen mendefinisikan anggota kelas, atribut data dan fungsi.

Contoh

Berikut adalah contoh kelas Python sederhana -

class Employee:
   'Common base class for all employees'
   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
  • Variabel empCount adalah variabel kelas yang nilainya dibagi di antara semua instance kelas ini. Ini dapat diakses sebagai Employee.empCount dari dalam kelas atau di luar kelas.

  • Metode pertama __init __ () adalah metode khusus, yang disebut konstruktor kelas atau metode inisialisasi yang dipanggil Python saat Anda membuat instance baru dari kelas ini.

  • Anda mendeklarasikan metode kelas lain seperti fungsi normal dengan pengecualian bahwa argumen pertama untuk setiap metode adalah self . Python menambahkan argumen diri ke daftar untuk Anda; Anda tidak perlu memasukkannya saat memanggil metode.

Membuat Objek Instance

Untuk membuat instance kelas, Anda memanggil kelas tersebut menggunakan nama kelas dan meneruskan argumen apa pun yang diterima metode __init__ .

"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)

Mengakses Atribut

Anda mengakses atribut objek menggunakan operator titik dengan objek. Variabel kelas akan diakses menggunakan nama kelas sebagai berikut -

emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

Sekarang, menyatukan semua konsep -

#!/usr/bin/python

class Employee:
   'Common base class for all employees'
   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

"This would create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This would create second object of Employee class"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Name :  Zara ,Salary:  2000
Name :  Manni ,Salary:  5000
Total Employee 2

Anda dapat menambah, menghapus, atau mengubah atribut kelas dan objek kapan saja -

emp1.age = 7  # Add an 'age' attribute.
emp1.age = 8  # Modify 'age' attribute.
del emp1.age  # Delete 'age' attribute.

Alih-alih menggunakan pernyataan normal untuk mengakses atribut, Anda dapat menggunakan fungsi berikut -

  • Itu getattr(obj, name[, default]) - untuk mengakses atribut objek.

  • Itu hasattr(obj,name) - untuk memeriksa apakah ada atribut atau tidak.

  • Itu setattr(obj,name,value)- untuk mengatur atribut. Jika atribut tidak ada, maka atribut itu akan dibuat.

  • Itu delattr(obj, name) - untuk menghapus atribut.

hasattr(emp1, 'age')    # Returns true if 'age' attribute exists
getattr(emp1, 'age')    # Returns value of 'age' attribute
setattr(emp1, 'age', 8) # Set attribute 'age' at 8
delattr(empl, 'age')    # Delete attribute 'age'

Atribut Kelas Bawaan

Setiap kelas Python terus mengikuti atribut bawaan dan mereka dapat diakses menggunakan operator titik seperti atribut lainnya -

  • __dict__ - Kamus yang berisi namespace kelas.

  • __doc__ - String dokumentasi kelas atau tidak ada, jika tidak ditentukan.

  • __name__ - Nama kelas.

  • __module__- Nama modul di mana kelas didefinisikan. Atribut ini adalah "__main__" dalam mode interaktif.

  • __bases__ - Tupel yang mungkin kosong yang berisi kelas-kelas dasar, dalam urutan kemunculannya dalam daftar kelas dasar.

Untuk kelas di atas, mari kita coba mengakses semua atribut ini -

#!/usr/bin/python

class Employee:
   'Common base class for all employees'
   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__

Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Employee.__doc__: Common base class for all employees
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount':
<function displayCount at 0xb7c84994>, 'empCount': 2, 
'displayEmployee': <function displayEmployee at 0xb7c8441c>, 
'__doc__': 'Common base class for all employees', 
'__init__': <function __init__ at 0xb7c846bc>}

Objek Penghancur (Pengumpulan Sampah)

Python menghapus objek yang tidak diperlukan (tipe bawaan atau instance kelas) secara otomatis untuk mengosongkan ruang memori. Proses di mana Python secara berkala mengambil kembali blok memori yang tidak lagi digunakan disebut Pengumpulan Sampah.

Pengumpul sampah Python berjalan selama eksekusi program dan dipicu ketika jumlah referensi objek mencapai nol. Jumlah referensi objek berubah seiring dengan perubahan jumlah alias yang mengarah ke objek tersebut.

Jumlah referensi objek meningkat ketika diberi nama baru atau ditempatkan dalam wadah (daftar, tupel, atau kamus). Jumlah referensi objek berkurang saat dihapus dengan del , referensinya dipindahkan, atau referensinya keluar dari ruang lingkup. Saat jumlah referensi objek mencapai nol, Python mengumpulkannya secara otomatis.

a = 40      # Create object <40>
b = a       # Increase ref. count  of <40> 
c = [b]     # Increase ref. count  of <40> 

del a       # Decrease ref. count  of <40>
b = 100     # Decrease ref. count  of <40> 
c[0] = -1   # Decrease ref. count  of <40>

Anda biasanya tidak akan melihat saat pengumpul sampah menghancurkan instance yatim piatu dan mengambil kembali ruangnya. Tapi kelas bisa mengimplementasikan metode khusus __del __ () , disebut destruktor, yang dipanggil ketika instance akan dimusnahkan. Metode ini dapat digunakan untuk membersihkan sumber daya non memori yang digunakan oleh sebuah instance.

Contoh

Penghancur __del __ () ini mencetak nama kelas dari instance yang akan dihancurkan -

#!/usr/bin/python

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, "destroyed"

pt1 = Point()
pt2 = pt1
pt3 = pt1
print id(pt1), id(pt2), id(pt3) # prints the ids of the obejcts
del pt1
del pt2
del pt3

Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -

3083401324 3083401324 3083401324
Point destroyed

Note- Idealnya, Anda harus mendefinisikan kelas Anda dalam file terpisah, kemudian Anda harus mengimpornya ke file program utama Anda menggunakan pernyataan import .

Warisan Kelas

Daripada memulai dari awal, Anda bisa membuat kelas dengan menurunkannya dari kelas yang sudah ada dengan mencantumkan kelas induk dalam tanda kurung setelah nama kelas baru.

Kelas anak mewarisi atribut dari kelas induknya, dan Anda dapat menggunakan atribut tersebut seolah-olah mereka didefinisikan di kelas anak. Kelas anak juga bisa mengganti anggota data dan metode dari induknya.

Sintaksis

Kelas turunan dideklarasikan seperti kelas induknya; Namun, daftar kelas dasar untuk mewarisi diberikan setelah nama kelas -

class SubClassName (ParentClass1[, ParentClass2, ...]):
   'Optional class documentation string'
   class_suite

Contoh

#!/usr/bin/python

class Parent:        # define parent class
   parentAttr = 100
   def __init__(self):
      print "Calling parent constructor"

   def parentMethod(self):
      print 'Calling parent method'

   def setAttr(self, attr):
      Parent.parentAttr = attr

   def getAttr(self):
      print "Parent attribute :", Parent.parentAttr

class Child(Parent): # define child class
   def __init__(self):
      print "Calling child constructor"

   def childMethod(self):
      print 'Calling child method'

c = Child()          # instance of child
c.childMethod()      # child calls its method
c.parentMethod()     # calls parent's method
c.setAttr(200)       # again call parent's method
c.getAttr()          # again call parent's method

Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Calling child constructor
Calling child method
Calling parent method
Parent attribute : 200

Dengan cara serupa, Anda dapat menjalankan kelas dari beberapa kelas induk sebagai berikut -

class A:        # define your class A
.....

class B:         # define your class B
.....

class C(A, B):   # subclass of A and B
.....

Anda bisa menggunakan fungsi issubclass () atau isinstance () untuk memeriksa hubungan dua kelas dan instance.

  • Itu issubclass(sub, sup) fungsi boolean mengembalikan nilai true jika subclass yang diberikan sub memang subclass dari superclass sup.

  • Itu isinstance(obj, Class)Fungsi boolean mengembalikan nilai true jika obj adalah turunan dari kelas kelas atau merupakan turunan dari subkelas Kelas

Metode Utama

Anda selalu dapat mengganti metode kelas induk Anda. Salah satu alasan untuk mengganti metode induk adalah karena Anda mungkin menginginkan fungsionalitas khusus atau berbeda di subkelas Anda.

Contoh

#!/usr/bin/python

class Parent:        # define parent class
   def myMethod(self):
      print 'Calling parent method'

class Child(Parent): # define child class
   def myMethod(self):
      print 'Calling child method'

c = Child()          # instance of child
c.myMethod()         # child calls overridden method

Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Calling child method

Metode Base Overloading

Tabel berikut mencantumkan beberapa fungsionalitas umum yang dapat Anda ganti di kelas Anda sendiri -

Sr.No. Metode, Deskripsi & Contoh Panggilan
1

__init__ ( self [,args...] )

Pembuat (dengan argumen opsional apa pun)

Panggilan Sampel: obj = className (args)

2

__del__( self )

Destruktor, menghapus sebuah objek

Contoh Panggilan: del obj

3

__repr__( self )

Representasi string yang berharga

Panggilan Sampel: repr (obj)

4

__str__( self )

Representasi string yang dapat dicetak

Panggilan Sampel: str (obj)

5

__cmp__ ( self, x )

Perbandingan objek

Panggilan Sampel: cmp (obj, x)

Operator Beban Berlebih

Misalkan Anda telah membuat kelas Vektor untuk mewakili vektor dua dimensi, apa yang terjadi jika Anda menggunakan operator plus untuk menambahkannya? Kemungkinan besar Python akan membentak Anda.

Anda bisa, bagaimanapun, mendefinisikan metode __add__ di kelas Anda untuk melakukan penambahan vektor dan kemudian operator plus akan berperilaku sesuai harapan -

Contoh

#!/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

Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -

Vector(7,8)

Menyembunyikan Data

Atribut objek mungkin atau mungkin tidak terlihat di luar definisi kelas. Anda perlu memberi nama atribut dengan awalan garis bawah ganda, dan atribut tersebut tidak akan langsung terlihat oleh orang luar.

Contoh

#!/usr/bin/python

class JustCounter:
   __secretCount = 0
  
   def count(self):
      self.__secretCount += 1
      print self.__secretCount

counter = JustCounter()
counter.count()
counter.count()
print counter.__secretCount

Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -

1
2
Traceback (most recent call last):
   File "test.py", line 12, in <module>
      print counter.__secretCount
AttributeError: JustCounter instance has no attribute '__secretCount'

Python melindungi anggota tersebut dengan mengubah nama secara internal untuk memasukkan nama kelas. Anda dapat mengakses atribut seperti object._className__attrName . Jika Anda akan mengganti baris terakhir Anda sebagai berikut, maka itu bekerja untuk Anda -

.........................
print counter._JustCounter__secretCount

Ketika kode di atas dijalankan, itu menghasilkan hasil sebagai berikut -

1
2
2