Pek yaygın olmayan bir sınıf tanımlama şekli

Merhaba arkadaşlar.

Bu başlık altında çok fazla kullanılmayan ama yine de geçerli olan bir sınıf tanımlama şeklinden bahsetmek istiyorum. Bu arada sınıflar ile sizin de eklemek istediğiniz bilgiler varsa, başlık altına mesajınızı paylaşın lütfen.

Genelde hiç bir özelliği olmayan bir sınıf tanımlanırken yaygın olarak aşağıdaki yazım şekli kullanılır:

>>> class Sinif: pass
>>> Sinif
<class '__main__.Sinif'>

Yukarıdaki tanımlama şeklinin dışında sınıflar şöyle de tanımlanabilir:

>>> degisken = type("Sinif", (), {})
>>> degisken
<class '__main__.Sinif'>

Yukarıdaki kodlar ismi "Sinif" olan bir bir sınıf oluşturur. degisken bu sınıfa erişebilmek için kullandığımız tanımlayıcıdır. Yani aşağıdaki gibi yazarsak bir hata alırız:

>>> Sinif
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'Sinif' is not defined
>>> 

Bu yüzden aşağıdaki kodu alt satıra eklediğimizde sınıfa kendi ismiyle erişebiliriz.

>>> globals()["Sinif"] = degisken
>>> Sinif
<class '__main__.Sinif'>

Not: Yukarıdaki örnekte sınıf tanımlayıcısının ismi degisken olarak belirlendi, daha sonradan da sınıfın kendi ismi global alanda tanımlandı. Ama aşağıdaki gibi yapılabilirdi tabi.

>>> Sinif = type("Sinif", (), {})

Şimdi gelin yavaş yavaş bu sınıfın içini biraz dolduralım.

>>> degisken = type(
        "Sinif", 
        (), 
        {
            "x": 1,
            "y": 2,
        }
    )
>>> # Sinif ismini tanımlayalım.
>>> globals()["Sinif"] = degisken
>>> #veya Sinif = degisken ikisi aynı şey.
>>> Sinif.x
1
>>> degisken.x
1

İstersek, oluşturduğumuz sınıfa bir fonksiyon da atayabiliriz.

>>> Sinif = type(
        "Sinif", 
        (), 
        {
            "x": 1,
            "y": 2,
            "topla1": lambda: Sinif.x + Sinif.y
            "topla2": lambda *args: sum(args)
        }
    )
>>> Sinif.topla1()
3
>>> Sinif.topla2(1, 2, 3)
6

Şimdi bu sınıfı miras alan başka bir sınıf oluşturalım:

>>> AltSinif = type(
        "AltSinif",
        (Sinif,),
        {}
    )
>>> AltSinif.topla2(1, 2, 3)
6

Yukarıdaki sınıfın sözlüğüne hiç bir argüman yazmadık ama, demet verisine Sinif yazdığımız için, Sınıf'ın sözlüğündeki bütün anahtar ve değerleri miras olarak aldı. Dilersek, bu sözlüğün içine fazladan özellik ekleyebiliriz.

Mesela şöyle:

>>> AltSinif = type(
        "AltSinif",
        (Sinif,),
        {
            "z": "Sinif nesnesi bu özelliğe sahip değildir."
        }
    )
>>> Sinif.z
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Sinif' has no attribute 'z'
>>> AltSinif.z
'Sinif nesnesi bu özelliğe sahip değildir.'

Şimdilik anlatacaklarım bu kadar. Ekleme yapmak isteyen arkadaşlar lütfen mesajlarınızı esirgemeyin.

Herkese keyifli günler dilerim.

9 Beğeni

__build_class__()

PyDoc ile Python’un iç mekanizmasını kurcalarken, __build_class__() diye, bir built-in fonksiyona denk geldim.

PyDoc’u çalıştırıp(python -m pydoc -p 8000 -b), şu adrese giderseniz, sizde görebilirsiniz.

http://localhost:8000/builtins.html#-__build_class__

Deneme fırsatı olmayanlar için;

__build_class__(func, name, /, *bases, [metaclass], **kwds) -> class
 
Internal helper function used by the class statement

Şeklinde bir açıklamsı var. Bende bu açıklamaya dayanarak şu şekilde bir deneme yaptım:

A = type("A", (),
  {
    "__init__":lambda self: print("Hello, World!")
  }
)

C = __build_class__(lambda:None, "C", A)

C()

Ve çıktısı ise şöyle oldu:

Hello, World!

Umarım faydalı olmuştur, herkese iyi forumlar. :slight_smile:

2 Beğeni