Skip to content

12. Sınıflar ve nesneler

Sınıf, nesnelerin oluşturulduğu kalıptır. Nesne, bir sınıfın örneği olarak tanımlanır.

Image

Not: [shared] dosyası, projenin [Sources Root] klasörüne yerleştirilmiştir.

12.1. [classes_01] betiği: bir Objet sınıfı

[classes_01] komut dosyası, sınıfların artık kullanılmayan bir kullanım şeklini göstermektedir:


# bir sınıf
class Objet(object):
    """une classe Objet vide"""


# [Objet] türündeki tüm değişkenler, yapısı gereği özniteliklere sahip olabilir
obj1 = Objet()
obj1.attr1 = "un"
obj1.attr2 = 100
# nesneyi görüntüler
print(f"objet1=[{obj1}, {type(obj1)},{id(obj1)},{obj1.attr1},{obj1.attr2}]")
# nesneyi değiştirir
obj1.attr2 += 100
# nesneyi görüntüler
print(f"objet1=[{obj1.attr1},{obj1.attr2}]")
#, obj1 referansını obj2'ye atar
obj2 = obj1
# obj2'nin işaret ettiği nesneyi değiştirir
obj2.attr2 = 0
# iki nesneyi de görüntüler - obj1 artık değiştirilmiş bir nesneye işaret eder
print(f"objet1=[{obj1.attr1},{obj1.attr2}]")
print(f"objet2=[{obj2.attr1},{obj2.attr2}]")
# obj1 ve obj2 aynı nesneye işaret ediyor
print(f"objet1=[{obj1}, {id(obj1)},{obj1.attr1},{obj1.attr2}]")
print(f"objet2=[{obj2}, {id(obj2)},{obj2.attr1},{obj2.attr2}]")
print(obj1 == obj2)
# obj1 örneğinin türü
print(f"type(obj1)={type(obj1)}")
print(f"isinstance(obj1,Objet)={isinstance(obj1, Objet)}, isinstance(obj1,object)={isinstance(obj1, object)}")
# Python'da her tür bir nesnedir
print(f"type(4)={type(4)}")
print(f"isinstance(4, int)={isinstance(4, int)}, isinstance(4, object)={isinstance(4, object)}")

Notlar:

  • 2-3. satırlar: boş bir [Objet] sınıfı;
    1. satır: Sınıf üç farklı biçimde tanımlanabilir:
    2. class Nesne;
    3. class Nesne();
    4. class Nesne(object);
  • satır 3: başka bir yorum biçimi. Önüne üç " işareti konulan bu yorum, birden fazla satıra yayılabilir;
    1. satır: Objet sınıfının örneklenmesi. Sonuç, 24-26. satırlarda gösterileceği gibi bir adrestir;
  • satır 8-9: nesnenin iki özniteliğinin doğrudan başlatılması;
  • satır 17: referansların kopyalanması. obj1 ve obj2 değişkenleri, aynı nesneye işaret eden iki işaretçidir (referans);
    1. satır: [obj2] tarafından işaret edilen nesne değiştirilir. [obj1] ve [obj2] aynı nesneye işaret ettiğinden, 21. ve 22. satırlardaki [obj1, obj2] nesnelerinin görüntülenmesi, [obj1] tarafından işaret edilen nesnenin değiştiğini gösterecektir;
  • 24-26. satırlar: Bu satırlar, [obj1] ve [obj2] değişkenlerinin eşit olduğunu göstermeyi amaçlamaktadır. 26. satırın görüntülenmesi bunu gösterecektir. Bu karşılaştırmada, [obj1] ve [obj2] adresleri eşittir;
  • Her Python nesnesi, [id(objet)] ifadesiyle elde edilen benzersiz bir numara ile tanımlanır. 24. ve 25. satırlar, [obj1] ve [obj2] tarafından işaret edilen nesnelerin numaralarının aynı olduğunu gösterecek ve böylece bu iki referansın aynı nesneye işaret ettiğini ortaya koyacaktır;
  • 27-29. satırlar: [isinstance(expr,Type)] işlevi, [expr] ifadesinin türü [Type] ise True değerini döndürür. Burada, [obj1]'in [Objet] türünde olduğunu göreceğiz; bu doğal görünse de, aynı zamanda [object] türündedir. [object] sınıfı, tüm Python sınıflarının üst sınıfıdır. Sınıf mirasının özelliği gereği, bir alt sınıf F, üst sınıfı P’nin tüm özelliklerine sahiptir ve [isinstance(instance de F, P)] işlevi True değerini döndürür;
  • 30-32. satırlar: [int] türünün de bir [object] türü olduğunu gösterir. Tüm Python türleri [object] sınıfından türetilir;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_01.py
objet1=[<__main__.Objet object at 0x0000025C3F469BB0>, <class '__main__.Objet'>,2595221838768,un,100]
objet1=[un,200]
objet1=[un,0]
objet2=[un,0]
objet1=[<__main__.Objet object at 0x0000025C3F469BB0>, 2595221838768,un,0]
objet2=[<__main__.Objet object at 0x0000025C3F469BB0>, 2595221838768,un,0]
True
type(obj1)=<class '__main__.Objet'>
isinstance(obj1,Objet)=True, isinstance(obj1,object)=True
type(4)=<class 'int'>
isinstance(4, int)=True, isinstance(4, object)=True

Process finished with exit code 0

12.2. [classes_02] betiği: bir Personne sınıfı

[classes_02] betiği, bir sınıfın özniteliklerinin genel olduğunu gösterir: bu özniteliklere sınıfın dışından doğrudan erişilebilir. Burada yine sınıfların tavsiye edilmeyen bir kullanım şekli söz konusudur. Yine de bu örneği veriyoruz çünkü bazen bu tür kodlarla karşılaşılabilir (Python bunu kabul eder) ve bu durumda onu anlayabilmek gerekir.


# Personne sınıfı
class Personne:
    # sınıfın öznitelikleri
    # bildirilmemiş - dinamik olarak oluşturulabilir

    # yöntem
    def identité(self: object) -> str:
        # ilk bakışta, mevcut olmayan öznitelikleri kullanıyor
        return f"[{self.prénom},{self.nom},{self.âge}]"


# ---------------------------------- main
# özellikler genel ve dinamik olarak oluşturulabilir
# sınıfın örneklenmesi
p = Personne()
# sınıf özniteliklerinin doğrudan başlatılması
p.prénom = "Paul"
p.nom = "de la Hûche"
p.âge = 48
# sınıf yönteminin çağrılması
print(f"personne={p.identité()}")
# p örneğinin türü
print(f"type(p)={type(p)}")
print(f"isinstance(Personne)={isinstance(p, Personne)}, isinstance(object)={isinstance(p, object)}")

Notlar:

  • 2-9. satırlar: bir yöntem içeren bir sınıf;
    1. satır: Bir sınıfın herhangi bir yönteminin ilk parametresi, geçerli nesneyi belirten self nesnesi olmalıdır. [identité] yöntemi bir karakter dizisi döndürür;
    1. satır: [Personne] nesnesinin örneklenmesi;
  • satır 16-19: nesnenin özniteliklerinin dinamik olarak oluşturulabileceğini gösterir (bunlar sınıf tanımında mevcut değildir);
    1. satır: sınıfın öznitelikleri [self.attribut] notasyonu ile belirtilir;
  • 23-24. satırlar, [p] nesnesinin hem [Personne] sınıfının hem de [object] sınıfının bir örneği olduğunu gösterecektir;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_02.py
personne=[Paul,de la Hûche,48]
type(p)=<class '__main__.Personne'>
isinstance(Personne)=True, isinstance(object)=True

Process finished with exit code 0

12.3. [classes_03] komut dosyası: Oluşturucuya sahip Personne sınıfı

[classes_03] betiği, bir sınıfın normal kullanımını gösterir:


# Personne sınıfı
class Personne:
    # yapıcı - üç özniteliği başlatır
    def __init__(self: object, prénom: str, nom: str, âge: int):
        # ad: kişinin adı
        # soyadı: kişinin soyadı
        # yaş: kişinin yaşı

        self.prénom = prénom
        self.nom = nom
        self.âge = âge

    # sınıfın özniteliklerini bir karakter dizesi biçiminde döndürür
    def identité(self: object) -> str:
        return f"[{self.prénom},{self.nom},{self.âge}]"


# ---------------------------------- ana
# bir Kişi nesnesi
p = Personne("Paul", "de la Hûche", 48)
# bir yöntemin çağrılması
print(f"personne={p.identité()}")

Notlar:

    1. satır: Bir sınıfın oluşturucusunun adı __init__'tir. Diğer yöntemlerde olduğu gibi, ilk parametresi self'tir;
    1. satır: Bir Personne nesnesi, sınıfın oluşturucusu ile oluşturulur;
  • 13-15. satırlar: [identité] yöntemi, nesnenin içeriğini temsil eden bir karakter dizisi döndürür;
    1. satır: kişinin kimliği görüntülenir;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_03.py
personne=[Paul,de la Hûche,48]

Process finished with exit code 0

12.4. [classes_04] betiği: statik yöntemler

[modules] klasöründe, aşağıdaki [Utils] sınıfını (utils.py) tanımlıyoruz:

Image


class Utils:
    # statik yöntem
    @staticmethod
    def is_string_ok(string: str) -> bool:
        # string bir karakter dizisi mi
        erreur = not isinstance(string, str)
        if not erreur:
            # dize boş mu?
            erreur = string.strip() == ''
        # sonuç
        return not erreur

Notlar

    1. satır: [@staticmethod] anotasyonu, bu şekilde anotlanmış yöntemin bir sınıf yöntemi olduğunu ve bir örnek yöntemi olmadığını gösterir. Bu, anotlanmış yöntemin ilk parametresinin [self] anahtar sözcüğü olmaması gerçeğinden anlaşılabilir. Dolayısıyla statik yöntem, nesnenin özniteliklerine erişemez. Şu şekilde yazmak yerine:
u=Utils()
print(u.is_string_ok("abcd")

yerine şunu yazarız:

print(Utils.is_string_ok("abcd")

Yukarıda [Utils.is_string_ok] yazıldığı için, [is_string_ok] yöntemi bir sınıf yöntemi olarak adlandırılır (burada Utils sınıfı). Bunun için [Utils.is_string_ok] yöntemine [@staticmethod] anahtar sözcüğü eklenmelidir.

Statik [Utils.is_string_ok] yöntemi, burada bir verinin boş olmayan bir karakter dizisi olup olmadığını kontrol etmemizi sağlar.

[classes_04] komut dosyası, [Utils] sınıfını şu şekilde kullanır:


# uygulama yapılandırılıyor
import config

config = config.configure()

# syspath yapılandırıldı - içe aktarmalar yapılabilir
from utilitaires import Utils

print(Utils.is_string_ok("  "))
print(Utils.is_string_ok(47))
print(Utils.is_string_ok(" q "))
  • 1-4. satırlar: bir yapılandırma komut dosyası kullanılır;

[config.py] yapılandırma komut dosyası şöyledir:


def configure():
    import os

    # yapılandırma dosyasının bulunduğu klasör
    script_dir = os.path.dirname(os.path.abspath(__file__))

    # syspath'a eklenecek klasörlerin mutlak yolları
    absolute_dependencies = [
        f"{script_dir}/shared",
        "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/venv/lib/site-packages",
        "C:/myprograms/Python38/lib",
        "C:/myprograms/Python38/DLLs"
    ]

    # syspath güncelleniyor
    from myutils import set_syspath
    set_syspath(absolute_dependencies)

    # yapılandırma geri gönderiliyor
    return {}
    1. satır: [shared] klasörü Python Path'e eklenecektir;

Çalıştırma sonucu şöyledir:

1
2
3
4
5
6
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_04.py
False
False
True

Process finished with exit code 0

12.5. [classes_05] betiği: öznitelik geçerlilik denetimleri

[classes_05] komut dosyası yeni kavramlar getirir:

  • özel bir istisna türünün tanımlanması;
  • sınıfların varsayılan kimlik yöntemi olan [_str_] yönteminin tanımlanması;
  • özelliklerin tanımlanması;

# uygulama yapılandırılıyor
import config

config = config.configure()

# syspath yapılandırıldı - artık içe aktarmalar yapılabilir
from utilitaires import Utils


# [BaseException]'ten türetilen özel bir istisna sınıfı
class MyException(BaseException):
    # hiçbir işlem yapılmıyor: boş sınıf
    pass


# Personne sınıfı
class Personne:
    # yapıcı
    def __init__(self: object, prénom: str = "x", nom: str = "y", âge: int = 0):
        # ad: kişinin adı
        # soyadı: kişinin soyadı
        # yaş: kişinin yaşı

        # parametrelerin kaydedilmesi
        # başlatma işlemleri setter'lar aracılığıyla yapılacaktır
        self.prénom = prénom
        self.nom = nom
        self.âge = âge

    # sınıfın toString yöntemi
    def __str__(self: object) -> str:
        return f"[{self.__prénom},{self.__nom},{self.__âge}]"

    # alıcı yöntemleri
    @property
    def prénom(self) -> str:
        return self.__prénom

    @property
    def nom(self) -> str:
        return self.__nom

    @property
    def âge(self) -> int:
        return self.__âge

    # ayarlayıcılar
    @prénom.setter
    def prénom(self, prénom: str):
        # ad alanı boş olmamalıdır
        if Utils.is_string_ok(prénom):
            self.__prénom = prénom.strip()
        else:
            raise MyException("Le prénom doit être une chaîne de caractères non vide")

    @nom.setter
    def nom(self, nom: str):
        # ad alanı boş olmamalıdır
        if Utils.is_string_ok(nom):
            self.__nom = nom.strip()
        else:
            raise MyException("Le nom doit être une chaîne de caractères non vide")

    @âge.setter
    def âge(self, âge: int):
        # yaş, 0'dan büyük bir tamsayı olmalıdır
        erreur = False
        if isinstance(âge, int):
            if âge >= 0:
                self.__âge = âge
            else:
                erreur = True
        else:
            erreur = True
        # hata mı?
        if erreur:
            raise MyException("L'âge doit être un entier >=0")


# ---------------------------------- ana
# bir Kişi nesnesi
try:
    # Personne sınıfının örneklenmesi
    p = Personne("Paul", "de la Hûche", 48)
    # p nesnesinin görüntülenmesi
    print(f"personne={p}")
except MyException as erreur:
    # hatanın görüntülenmesi
    print(erreur)

# başka bir Kişi nesnesi
try:
    # Personne sınıfının örneklenmesi
    p = Personne("xx", "yy", "zz")
    # p nesnesinin görüntülenmesi
    print(f"personne={p}")
except MyException as erreur:
    # hata görüntüleme
    print(erreur)

# bu sefer parametre olmadan başka bir kişi
try:
    # Personne sınıfının örneklenmesi
    p = Personne()
    # p nesnesinin görüntülenmesi
    print(f"personne={p}")
except MyException as erreur:
    # hata mesajının görüntülenmesi
    print(erreur)

# sınıfın özel özniteliklerine erişilemiyor __attr
p.__prénom = "Gaëlle"
print(f"p.prénom={p.prénom}")
print(f"p.__prénom={p.__prénom}")
p.prénom = "Sébastien"
print(f"p.prénom={p.prénom}")
print(f"p.__prénom={p.__prénom}")

Notlar:

  • 10-13. satırlar: BaseException sınıfından türetilmiş bir MyException sınıfı (bu konuya biraz sonra değineceğiz). Bu sınıf, BaseException sınıfına herhangi bir işlevsellik eklemez. Yalnızca özel bir istisna tanımlamak amacıyla eklenmiştir;
    1. satır: Oluşturucunun parametreleri için varsayılan değerler vardır. Dolayısıyla p=Personne() işlemi, p=Personne("x","y",0) ile eşdeğerdir;
  • satır 34-45: Sınıfın özellikleri. Bunlar, [@property] anahtar sözcüğüyle işaretlenmiş yöntemlerdir. Özniteliklerin değerlerini döndürmek için kullanılırlar;
  • satır 47-77: Sınıfın ayarlayıcıları. Bunlar, [@attributsetter] anahtar sözcüğüyle işaretlenmiş yöntemlerdir. Özniteliklerin değerlerini ayarlamak için kullanılırlar;
  • satır 48-54: [prénom] özniteliğinin ayarlayıcısı. Bu yöntem, [prénom] özniteliğine her değer atandığında çağrılacaktır:
p=Personne(…)
p.prénom=valeur
  1. satır, [p.prénom(valeur)] yönteminin çağrılmasına neden olacaktır. Bir özniteliğe değer atamak için setter yöntemini kullanmanın avantajı, setter'ın bir işlev olması nedeniyle özniteliğe atanan değerin geçerliliğinin kontrol edilebilmesidir;

    1. satır: [prénom] özniteliğine atanan değerin boş olmayan bir karakter dizisi olup olmadığı kontrol edilir. Bunun için daha önce görülen [Utils.isStringOk] statik yöntemi kullanılır;
    1. satır: [prénom] özniteliğine atanan değerden dizenin başındaki ve sonundaki "boşluklar" temizlenir ve bu değer [self.__prénom] özniteliğine atanır. Dolayısıyla burada [prénom] özniteliği kullanılmamaktadır. Aksi takdirde sonsuz bir özyinelemeli çağrı oluşurdu. Herhangi bir öznitelik adı kullanılabilirdi. Tanımlayıcının başında iki alt çizgi bulunan [__prénom] özniteliğinin kullanılması özel bir anlam taşır: başında iki alt çizgi bulunan öznitelikler sınıfa özeldir. Bu, sınıfın dışından görülemedikleri anlamına gelir. Dolayısıyla şu şekilde yazamayız:
p=Personne(…)
p.__prénom=valeur

Aslında birazdan göreceğiz ki bunu yazmak mümkün, ancak bu işlem adı değiştirmez. Başka bir şey yapar;

  • 53-54. satırlar: isme atanan değer doğru değilse, bir istisna atılır. Böylece çağıran kod, çağrısının hatalı olduğunu anlar;
  • 35-37. satırlar: [prénom] özelliği. Bir ifadede [p.prénom] yazıldığında bu özellik her seferinde çağrılacaktır. Bu durumda [p.prénom()] yöntemi çağrılacaktır. 37. satırda, [__prénom] özniteliğinin değeri döndürülür; çünkü [prénom] özniteliğinin setter'ının, bu değeri özel [__prénom] özniteliğine atadığını görmüştük;
  • 56-62. satırlar: [nom] özniteliğinin setter'ı, [prénom] özniteliğinkine benzer şekilde oluşturulmuştur. Aynı durum, 64-77. satırlardaki [âge] özniteliği için de geçerlidir;
  • [prénom, nom, valeur] özellikleri, gerçekte [__prénom, __nom, __âge] olan gerçek öznitelikler olmasa da, bu özellikler öznitelik olarak kullanıldığından, bunlara sınıfın öznitelikleri olarak devam edeceğiz;
  • 19-28. satırlar: Sınıf oluşturucu, [prénom, nom, âge] özniteliklerinin ayarlayıcılarını örtük olarak kullanır. Nitekim, 26. satırda [self.prénom = prénom] yazıldığında, dolaylı olarak [prénom(self, prénom)] yöntemi çağrılacaktır. Böylece [prénom] parametresinin geçerliliği kontrol edilecektir. Aynı durum, diğer iki öznitelik olan [nom, âge] için de geçerlidir;
  • bu modelde, sınıfın [prénom, nom, âge] özniteliklerine hatalı değerler atanamaz;
  • 30-32. satırlar: __str__ işlevi, daha önce identité olarak adlandırılan yöntemin yerini almaktadır. [__str__] adı (önünde ve arkasında 2 alt çizgi olması) önemsiz değildir. Bunu daha sonra göreceğiz;
  • satır 83-86: bir kişinin örneklenmesi ve ardından kimliğinin görüntülenmesi;
    1. satır: nesne oluşturma;
    1. satır: görüntüleme. İşlem, p adlı kişiyi bir karakter dizisi biçiminde görüntülemeyi gerektirir. Python yorumlayıcısı, varsa p.__str__() yöntemini otomatik olarak çağırır. Bu yöntem, Java’da veya .NET dillerinde toString() yöntemiyle aynı işlevi görür;
  • 87-89. satırlar: MyException türünde olası bir istisnanın yönetimi. Ardından hata görüntülenir;
  • 91-99. satırlar: hatalı parametrelerle örneklendirilmiş ikinci bir kişi için de aynısı geçerlidir;
  • satır 102-109: varsayılan parametrelerle örneklendirilen üçüncü bir kişi için de aynısı geçerlidir: hiçbir parametre aktarılmaz. Bu durumda, burada kullanılanlar, oluşturucudaki bu parametrelerin varsayılan değerleridir;
  • satır 112-117: [__prénom] özniteliğinin özel olduğu ve dolayısıyla normalde sınıfın dışından erişilemez olduğu belirtilmişti. Bunu doğrulamak istiyoruz;
  • 112-114. satırlar: [__prénom] özniteliğine bir değer atıyoruz, ardından normalde aynı olması gereken [__prénom] ve [prénom] özniteliklerinin değerlerini kontrol ediyoruz;
  • satır 115-117: Bu sefer [prénom] özniteliğini başlatarak işlemi tekrarlıyoruz;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_05.py
personne=[Paul,de la Hûche,48]
L'âge doit être un entier >=0
personne=[x,y,0]
p.prénom=x
p.__prénom=Gaëlle
p.prénom=Sébastien
p.__prénom=Gaëlle

Process finished with exit code 0

Notlar

  • 5-6. satırlar: [p.__prénom = "Gaëlle"] atamasının, 5. satırdaki [prénom] özniteliğinin değerini değiştirmediğini görüyoruz;
  • 7-8. satırlar: [p.prénom = "Sébastien"] atamasının, [__prénom] özniteliğinin değerini değiştirmediği görülmektedir, 8. satır;

Bundan ne sonuç çıkarılabilir? Muhtemelen, [p.__prénom = "Gaëlle"] işlemi, sınıfa [__prénom] adlı bir public öznitelik oluşturmuştur, ancak bu öznitelik, sınıf içinde işlenen [__prénom] adlı private öznitelikten farklıdır;

12.6. [classes_06] komut dosyası: nesneyi başlatma yönteminin eklenmesi

[classes_06] komut dosyası, [Personne] sınıfına bir yöntem ekler:


# uygulama yapılandırılıyor
import config

config = config.configure()

# syspath yapılandırıldı - içe aktarmalar yapılabilir
from utilitaires import Utils


# [BaseException] sınıfından türetilen özel bir sınıf
class MyException(BaseException):
    # hiçbir işlem yapılmaz: boş sınıf
    pass


# Personne sınıfı
class Personne:
    # yapıcı
    def __init__(self: object, prénom: str = "x", nom: str = "y", âge: int = 0):
        # ad: kişinin adı
        # soyadı: kişinin soyadı
        # yaş: kişinin yaşı

        # parametrelerin kaydedilmesi
        # başlatma işlemleri setter'lar aracılığıyla yapılacaktır
        self.prénom = prénom
        self.nom = nom
        self.âge = âge

    # başka bir başlatma yöntemi
    def init_with_personne(self: object, p: object):
        # geçerli nesneyi p kişisiyle başlatır
        self.__init__(p.prénom, p.nom, p.âge)

    # sınıfın toString yöntemi
    def __str__(self: object) -> str:
        return f"[{self.__prénom},{self.__nom},{self.__âge}]"

    # alıcılar


    # ayarlayıcılar



# ---------------------------------- ana işlev
# bir Personne nesnesi
try:
    # Personne sınıfının örneklenmesi
    p = Personne("Paul", "de la Hûche", 48)
    # p nesnesinin görüntülenmesi
    print(f"personne={p}")
except MyException as erreur:
    # hata mesajının görüntülenmesi
    print(erreur)

# başka bir Kişi nesnesi
try:
    # Personne sınıfının örneklenmesi
    p = Personne("xx", "yy", "zz")
    # p nesnesinin görüntülenmesi
    print(f"p={p}")
except MyException as erreur:
    # hata mesajı görüntüleme
    print(erreur)

# bu sefer parametre olmadan başka bir kişi
try:
    # Personne sınıfının örneklenmesi
    p = Personne()
    # p nesnesinin görüntülenmesi
    print(f"p={p}")
except MyException as erreur:
    # hata mesajının görüntülenmesi
    print(erreur)

# kopyalanarak elde edilen başka bir Kişi
try:
    # Personne sınıfının örneklenmesi
    p2 = Personne()
    p2.init_with_personne(p)
    # p2 nesnesinin görüntülenmesi
    print(f"p2={p2}")
except MyException as erreur:
    # hata mesajı görüntüleme
    print(erreur)

Notlar:

  • Önceki komut dosyasıyla arasındaki fark 30-33. satırlarda yer almaktadır. initWithPersonne yöntemi eklenmiştir. Bu yöntem, __init__ oluşturucusunu çağırır. Tiplemeli dillerde olduğu gibi, parametrelerinin veya sonuçlarının niteliğine göre ayırt edilen aynı isimli yöntemlere sahip olma imkanı yoktur. Dolayısıyla, farklı parametrelerden (burada Personne türünde bir nesne) nesneyi oluşturan birden fazla oluşturucuya sahip olma imkanı yoktur;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_06.py
personne=[Paul,de la Hûche,48]
L'âge doit être un entier >=0
p=[x,y,0]
p2=[x,y,0]

Process finished with exit code 0

12.7. [classes_07] betiği: Personne nesnelerinin listesi

Artık [MyException] ve [Personne] sınıflarını, kodlarını yeniden yazmak zorunda kalmadan kullanabilmek için bir modüle yerleştiriyoruz:

Image

Her iki sınıf da yukarıdaki [myclasses.py] modülünde yer alacaktır.

[classes_07] komut dosyası, bir nesne listesi oluşturulabileceğini göstermektedir:


# uygulama yapılandırılıyor
import config

config = config.configure()

# syspath yapılandırıldı - içe aktarmalar yapılabilir
from myclasses import Personne

# ---------------------------------- ana
# kişi nesnelerinin listesi oluşturuluyor
groupe = [Personne("Paul", "Langevin", 48), Personne("Sylvie", "Lefur", 70)]
# bu kişilerin kimlik bilgileri
for i in range(len(groupe)):
    print(f"groupe[{i}]={groupe[i]}")

Notlar:

    1. satır: [Personne] sınıfını içe aktarıyoruz;
    1. satır: [Personne] türünde bir nesne listesi;
  • 13-14. satırlar: bu listeyi tarayarak her bir öğeyi görüntülüyoruz;
    1. satır: [print] işlevi, [groupe[i]] nesnesini temsil eden dizeyi görüntüler. Varsayılan olarak, bu nesnelerin [__str__] yöntemi çağrılır;

Sonuçlar


C:\Users\serge\.virtualenvs\cours-python-v02\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/v-02/classes/01/classes_07.py
groupe[0]=[Paul,Langevin,48]
groupe[1]=[Sylvie,Lefur,70]

Process finished with exit code 0

12.8. [classes_08] komut dosyası: Personne sınıfından türetilmiş bir sınıfın oluşturulması

[myclasses] modülünde, aşağıdaki [Enseignant] sınıfını tanımlıyoruz:


# Öğretmen sınıfı
class Enseignant(Personne):
    # yapıcı
    def __init__(self, prénom: str = "x", nom: str = "x", âge: int = 0, discipline: str = "x"):
        # ad: kişinin adı
        # soyadı: kişinin soyadı
        # yaş: kişinin yaşı
        # ders: öğretilen ders

        # ebeveynin baş harfi
        Personne.__init__(self, prénom, nom, âge)
        # diğer baş harfleri
        self.discipline = discipline

    # toString
    def __str__(self) -> str:
        return f"enseignant[{super().__str__()},{self.discipline}]"

    # özellikler
    @property
    def discipline(self) -> str:
        return self.__discipline

    @discipline.setter
    def discipline(self, discipline: str):
        # disiplin, boş olmayan bir dize olmalıdır
        if Utils.is_string_ok(discipline):
            self.__discipline = discipline
        else:
            raise MyException("La discipline doit être une chaîne de caractères non vide")
    1. satır: Enseignant sınıfını, Personne sınıfından türetilmiş bir sınıf olarak tanımlar. Türetilmiş bir sınıf, üst sınıfının tüm özelliklerine (öznitelikler ve yöntemler) ek olarak kendine özgü özelliklere de sahiptir;
    1. satır: [Enseignant] sınıfı, [discipline] adlı yeni bir özniteliği tanımlar;
    1. satır: Enseignant türetilmiş sınıfının oluşturucusu, Personne ana sınıfının oluşturucusunu çağırmalı ve beklenen parametreleri ona aktarmalıdır;
    1. satır: [super()] işlevi, üst sınıfı döndürür. Burada, üst sınıfın [__str__] işlevi çağrılır;
  • 19-30. satırlar: Yeni [discipline] özniteliğinin getter ve setter'ı tanımlanmaktadır;

[classes_08] betiği, [Enseignant] sınıfını şu şekilde kullanır:


# uygulama yapılandırılıyor
import config

config = config.configure()

# syspath yapılandırıldı - içe aktarmalar yapılabilir
from myclasses import Personne, Enseignant

# ---------------------------------- main
# Personne nesneleri ve türevlerinden oluşan bir dizi oluşturuluyor
groupe = [Enseignant("Paul", "Langevin", 48, "anglais"), Personne("Sylvie", "Lefur", 70)]
# bu kişilerin kimlik bilgileri
for i in range(len(groupe)):
    print(f"groupe[{i}]={groupe[i]}")

Notlar:

    1. satır: [myclasses.py] dosyasında tanımlanan [Personne] ve [Enseignant] sınıfları içe aktarılır;
  • 11-14. satırlar: Bir kişi grubu tanımlanır ve ardından bu grubun kimlik bilgileri görüntülenir;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_08.py
groupe[0]=enseignant[[Paul,Langevin,48],anglais]
groupe[1]=[Sylvie,Lefur,70]

Process finished with exit code 0

12.9. [classes_09] komut dosyası: Kişi sınıfından türetilen ikinci sınıf

[classes_09] komut dosyası, [Personne] sınıfından türetilen [Etudiant] sınıfını tanımlar. Bu sınıf, [myclasses] modülünde şu şekilde tanımlanmıştır:


# Öğrenci sınıfı
class Etudiant(Personne):
    # oluşturucu
    def __init__(self: object, prénom: str = "x", nom: str = "y", âge: int = 0, formation: str = "x"):
        Personne.__init__(self, prénom, nom, âge)
        self.formation = formation

    # toString
    def __str__(self: object) -> str:
        return f"étudiant[{super().__str__()},{self.formation}]"

    # özellikler
    @property
    def formation(self) -> str:
        return self.__formation

    @formation.setter
    def formation(self, formation: str):
        # eğitim, boş olmayan bir dize olmalıdır
        if Utils.is_string_ok(formation):
            self.__formation = formation
        else:
            raise MyException("La formation doit être une chaîne de caractères non vide")

[classes_09] komut dosyası, [Etudiant] sınıfını şu şekilde kullanır:


# uygulama yapılandırılıyor
import config

config = config.configure()

# syspath yapılandırıldı - içe aktarmalar yapılabilir
from myclasses import Personne, Enseignant, Etudiant

# ---------------------------------- main
# Personne nesneleri ve türevlerinden oluşan bir dizi oluşturuluyor
groupe = [Enseignant("Paul", "Langevin", 48, "anglais"), Personne("Sylvie", "Lefur", 70),
          Etudiant("Steve", "Boer", 22, "iup2 qualité")]
# bu kişilerin kimlik bilgileri
for personne in groupe:
    # kişinin görüntülenmesi
    print(personne)

Notlar:

  • Bu komut dosyası, bir öncekine benzerdir.

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_09.py
enseignant[[Paul,Langevin,48],anglais]
[Sylvie,Lefur,70]
étudiant[[Steve,Boer,22],iup2 qualité]

Process finished with exit code 0

12.10. [classes_10] komut dosyası: [__dict__] özelliği

[classes_10] komut dosyası, bundan sonra sık sık kullanacağımız [__dict__] özelliğini içerir:


# uygulama yapılandırılıyor
import config

config = config.configure()

# syspath yapılandırıldı - içe aktarmalar yapılabilir
from myclasses import Etudiant

# ---------------------------------- ana
# bir öğrencinin oluşturulması
étudiant=Etudiant("Steve", "Boer", 22, "iup2 qualité")
# özellik sözlüğü
print(étudiant.__dict__)

Açıklamalar

  • 1-4. satırlar: uygulama yapılandırılır;
    1. satır: [Etudiant] sınıfı içe aktarılır;
    1. satır: bir öğrenci nesnesi oluşturulur;
    1. satır: önceden tanımlanmış [__dict__] yöntemi kullanılır (kimlik numarasının önünde ve arkasında 2 karakter altı çizili);

Sonuçlar şöyledir:

1
2
3
4
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/classes/01/classes_10.py
{'_Personne__prénom': 'Steve', '_Personne__nom': 'Boer', '_Personne__âge': 22, '_Etudiant__formation': 'iup2 qualité'}

Process finished with exit code 0
    1. satırda, anahtarları nesnenin özellikleri olan ve ait oldukları sınıfın adıyla önekli bir sözlük elde edilir. Bu sözlüğü, nesne ile sözlük arasında bir köprü oluşturmak için kullanacağız;