Python 3 - Nesne Yönelimli

Python, var olduğu andan beri nesne yönelimli bir dil olmuştur. Bu nedenle, sınıflar ve nesneler oluşturmak ve kullanmak düpedüz kolaydır. Bu bölüm, Python'un nesne yönelimli programlama desteğini kullanma konusunda uzman olmanıza yardımcı olur.

Nesne yönelimli (OO) programlamayla ilgili daha önce herhangi bir deneyiminiz yoksa, temel kavramları kavramak için bununla ilgili bir giriş kursuna veya en azından bir tür öğreticiye başvurmak isteyebilirsiniz.

Bununla birlikte, işte size yardımcı olmak için Nesne Yönelimli Programlamanın (OOP) küçük bir tanıtımı -

OOP Terminolojisine Genel Bakış

  • Class- Sınıfın herhangi bir nesnesini karakterize eden bir öznitelik kümesini tanımlayan bir nesne için kullanıcı tanımlı bir prototip. Öznitelikler veri üyeleri (sınıf değişkenleri ve örnek değişkenleri) ve yöntemlerdir ve nokta notasyonu ile erişilir.

  • Class variable- Bir sınıfın tüm örnekleri tarafından paylaşılan bir değişken. Sınıf değişkenleri bir sınıf içinde ancak sınıfın yöntemlerinden herhangi birinin dışında tanımlanır. Sınıf değişkenleri, örnek değişkenler kadar sık ​​kullanılmaz.

  • Data member - Bir sınıf ve nesneleriyle ilişkili verileri tutan bir sınıf değişkeni veya örnek değişkeni.

  • Function overloading- Belirli bir işleve birden fazla davranışın atanması. Gerçekleştirilen işlem, ilgili nesnelerin veya argümanların türüne göre değişir.

  • Instance variable - Bir yöntem içinde tanımlanan ve yalnızca bir sınıfın geçerli örneğine ait olan bir değişken.

  • Inheritance - Bir sınıfın özelliklerinin ondan türetilen diğer sınıflara aktarılması.

  • Instance- Belirli bir sınıfa ait bireysel bir nesne. Örneğin, Circle sınıfına ait bir nesne obj, Circle sınıfının bir örneğidir.

  • Instantiation - Bir sınıfın bir örneğinin oluşturulması.

  • Method - Sınıf tanımında tanımlanan özel bir işlev türü.

  • Object- Sınıfı tarafından tanımlanan benzersiz bir veri yapısı örneği. Bir nesne hem veri üyelerini (sınıf değişkenleri ve örnek değişkenleri) hem de yöntemleri içerir.

  • Operator overloading - Belirli bir operatöre birden fazla işlev atanması.

Sınıf Oluşturma

Sınıf deyimi yeni bir sınıf tanımını oluşturur. Sınıfın adı hemen anahtar kelime şu sınıfını aşağıdaki gibi iki nokta üst üste -

class ClassName:
   'Optional class documentation string'
   class_suite
  • Sınıf, aracılığıyla erişilebilen bir dokümantasyon dizesine sahiptir. ClassName.__doc__.

  • class_suite sınıf üyelerini, veri niteliklerini ve fonksiyonları tanımlayan tüm bileşen ifadelerinden oluşur.

Misal

Aşağıda basit bir Python sınıfı örneği verilmiştir -

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)
  • Değişken empCount değeri bu sınıfta tüm örnekleri arasında paylaşılan bir sınıf değişkendir. Bu, Employee.empCount olarak sınıfın içinden veya dışından erişilebilir .

  • İlk yöntem __init __ () , bu sınıfın yeni bir örneğini oluşturduğunuzda Python'un çağırdığı sınıf yapıcısı veya başlatma yöntemi olarak adlandırılan özel bir yöntemdir.

  • Her yöntemin ilk bağımsız değişkeninin self olması dışında normal işlevler gibi diğer sınıf yöntemlerini bildirirsiniz . Python sizin için listeye self argümanı ekler ; yöntemleri aradığınızda eklemenize gerek yoktur.

Örnek Nesneleri Oluşturma

Bir sınıfın örneklerini oluşturmak için, sınıf adını kullanarak sınıfı çağırır ve __init__ yönteminin kabul ettiği bağımsız değişkenleri iletirsiniz .

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

Özelliklere Erişim

Nesne ile nokta operatörünü kullanarak nesnenin niteliklerine erişirsiniz. Sınıf değişkenine aşağıdaki gibi sınıf adı kullanılarak erişilebilir -

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

Şimdi, tüm kavramları bir araya getirirsek -

#!/usr/bin/python3

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)

Yukarıdaki kod çalıştırıldığında, aşağıdaki sonucu verir -

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

İstediğiniz zaman sınıfların ve nesnelerin niteliklerini ekleyebilir, kaldırabilir veya değiştirebilirsiniz -

emp1.salary = 7000  # Add an 'salary' attribute.
emp1.name = 'xyz'  # Modify 'age' attribute.
del emp1.salary  # Delete 'age' attribute.

Niteliklere erişmek için normal ifadeleri kullanmak yerine aşağıdaki işlevleri kullanabilirsiniz -

  • getattr(obj, name[, default]) - nesnenin özniteliğine erişmek için.

  • hasattr(obj,name) - bir özniteliğin var olup olmadığını kontrol etmek için.

  • setattr(obj,name,value)- bir öznitelik ayarlamak için. Eğer öznitelik yoksa, o zaman yaratılacaktır.

  • delattr(obj, name) - bir özniteliği silmek için.

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

Yerleşik Sınıf Özellikleri

Her Python sınıfı yerleşik öznitelikleri izler ve bunlara diğer öznitelikler gibi nokta operatörü kullanılarak erişilebilir -

  • __dict__ - Sınıfın ad alanını içeren sözlük.

  • __doc__ - Sınıf dokümantasyon dizesi veya tanımlanmamışsa hiçbiri.

  • __name__ - Sınıf adı.

  • __module__- Sınıfın tanımlandığı modül adı. Bu özellik, etkileşimli modda "__main__" dir.

  • __bases__ - Temel sınıf listesindeki görülme sırasına göre temel sınıfları içeren muhtemelen boş bir demet.

Yukarıdaki sınıf için tüm bu özelliklere erişmeye çalışalım -

#!/usr/bin/python3

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)

emp1 = Employee("Zara", 2000)
emp2 = Employee("Manni", 5000)
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__ )

Yukarıdaki kod çalıştırıldığında, aşağıdaki sonucu verir -

Employee.__doc__: Common base class for all employees
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: (<class 'object'>,)
Employee.__dict__: {
   'displayCount': <function Employee.displayCount at 0x0160D2B8>, 
   '__module__': '__main__', '__doc__': 'Common base class for all employees', 
   'empCount': 2, '__init__': 
   <function Employee.__init__ at 0x0124F810>, 'displayEmployee': 
   <function Employee.displayEmployee at 0x0160D300>,
   '__weakref__': 
   <attribute '__weakref__' of 'Employee' objects>, '__dict__': 
   <attribute '__dict__' of 'Employee' objects>
}

Nesneleri Yok Etme (Çöp Toplama)

Python, bellek alanını boşaltmak için gereksiz nesneleri (yerleşik türler veya sınıf örnekleri) otomatik olarak siler. Python'un artık kullanılmayan bellek bloklarını periyodik olarak geri talep ettiği işlem, Çöp Toplama olarak adlandırılır.

Python'un çöp toplayıcısı program yürütme sırasında çalışır ve bir nesnenin referans sayısı sıfıra ulaştığında tetiklenir. Bir nesnenin referans sayısı, onu gösteren takma adların sayısı değiştikçe değişir.

Yeni bir ad atandığında veya bir kaba (liste, kayıt veya sözlük) yerleştirildiğinde bir nesnenin referans sayısı artar. Del ile silindiğinde , referansı yeniden atandığında veya referansı kapsam dışına çıktığında nesnenin referans sayısı azalır . Bir nesnenin referans sayısı sıfıra ulaştığında, Python bunu otomatik olarak toplar.

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>

Normalde çöp toplayıcının öksüz bir örneği yok edip alanını geri aldığını fark etmezsiniz. Bununla birlikte, bir sınıf , örnek yok edilmek üzereyken çağrılan, yıkıcı adı verilen özel __del __ () yöntemini uygulayabilir . Bu yöntem, bir örnek tarafından kullanılan bellek dışı kaynakları temizlemek için kullanılabilir.

Misal

Bu __del __ () yıkıcı, yok edilmek üzere olan bir örneğin sınıf adını yazdırır -

#!/usr/bin/python3

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

Yukarıdaki kod çalıştırıldığında, aşağıdaki sonucu verir -

140338326963984 140338326963984 140338326963984
Point destroyed

Note- İdeal olarak, sınıflarınızı ayrı bir dosyada tanımlamalısınız, daha sonra bunları import deyimini kullanarak ana program dosyanıza aktarmalısınız .

Yukarıdaki örnekte, bir Point sınıfının tanımının point.py içinde olduğu varsayılır ve içinde başka çalıştırılabilir kod yoktur.

#!/usr/bin/python3
import point

p1 = point.Point()

Sınıf Mirası

Sıfırdan başlamak yerine, ana sınıfı yeni sınıf adının ardından parantez içinde listeleyerek, onu önceden var olan bir sınıftan türeterek bir sınıf oluşturabilirsiniz.

Alt sınıf, üst sınıfının özniteliklerini devralır ve bu öznitelikleri alt sınıfta tanımlanmış gibi kullanabilirsiniz. Bir alt sınıf, üst öğenin veri üyelerini ve yöntemlerini de geçersiz kılabilir.

Sözdizimi

Türetilmiş sınıflar, ana sınıflarına çok benzer şekilde bildirilir; ancak, miras alınacak temel sınıfların bir listesi, sınıf adından sonra verilir -

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

Misal

#!/usr/bin/python3

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

Yukarıdaki kod çalıştırıldığında, aşağıdaki sonucu verir -

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

Benzer şekilde, aşağıdaki gibi birden çok ebeveyn sınıfından bir sınıfı sürdürebilirsiniz -

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

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

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

İki sınıfın ve örneklerin ilişkilerini kontrol etmek için issubclass () veya isinstance () işlevlerini kullanabilirsiniz.

  • issubclass(sub, sup) boolean işlevi, verilen alt sınıfsa True döndürür sub gerçekten de süper sınıfın bir alt sınıfıdır sup.

  • isinstance(obj, Class)obj , Class Class'ın bir örneğiyse veya Class'ın bir alt sınıfının bir örneğiyse boolean işlevi True döndürür

Geçersiz Kılma Yöntemleri

Her zaman üst sınıf yöntemlerinizi geçersiz kılabilirsiniz. Ebeveynin yöntemlerini geçersiz kılmanın bir nedeni, alt sınıfınızda özel veya farklı işlevler isteyebilmenizdir.

Misal

#!/usr/bin/python3

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

Yukarıdaki kod çalıştırıldığında, aşağıdaki sonucu verir -

Calling child method

Temel Aşırı Yükleme Yöntemleri

Aşağıdaki tablo, kendi sınıflarınızda geçersiz kılabileceğiniz bazı genel işlevleri listeler -

Sr.No. Yöntem, Açıklama ve Örnek Çağrı
1

__init__ ( self [,args...] )

Oluşturucu (isteğe bağlı bağımsız değişkenlerle)

Örnek Çağrı: obj = className (değiştirgeler)

2

__del__( self )

Destructor, bir nesneyi siler

Örnek Çağrı: del obj

3

__repr__( self )

Değerlendirilebilir dize gösterimi

Örnek Çağrı: repr (obj)

4

__str__( self )

Yazdırılabilir dize gösterimi

Örnek Çağrı: str (obj)

5

__cmp__ ( self, x )

Nesne karşılaştırması

Örnek Çağrı: cmp (obj, x)

Operatörlerin Aşırı Yüklenmesi

İki boyutlu vektörleri temsil etmek için bir Vector sınıfı oluşturduğunuzu varsayalım. Bunları eklemek için artı işlecini kullandığınızda ne olur? Büyük ihtimalle Python sana bağıracak.

Bununla birlikte, vektör toplamayı gerçekleştirmek için sınıfınızda __add__ yöntemini tanımlayabilirsiniz ve ardından artı operatörü beklentiye göre davranır -

Misal

#!/usr/bin/python3

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)

Yukarıdaki kod çalıştırıldığında, aşağıdaki sonucu verir -

Vector(7,8)

Veri Gizleme

Bir nesnenin nitelikleri, sınıf tanımının dışında görülebilir veya görünmeyebilir. Öznitelikleri çift alt çizgi önekiyle adlandırmanız gerekir ve bu öznitelikler daha sonra yabancılar tarafından doğrudan görülemeyecektir.

Misal

#!/usr/bin/python3

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

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

Yukarıdaki kod çalıştırıldığında, aşağıdaki sonucu verir -

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, adı sınıf adını içerecek şekilde dahili olarak değiştirerek bu üyeleri korur. Object._className__attrName gibi özniteliklere erişebilirsiniz . Son satırınızı aşağıdaki gibi değiştirirseniz, o zaman sizin için çalışır -

.........................
print (counter._JustCounter__secretCount)

Yukarıdaki kod çalıştırıldığında, aşağıdaki sonucu verir -

1
2
2