Skip to main content

Python type() Fonksiyonu Açıklaması

Python’daki type() fonksiyonu, aslında iki işlevi birden yerine getirir:

  1. Bir nesnenin tam olarak hangi sınıfa ait olduğunu öğrenmek,
  2. Çalışma zamanında (runtime) dinamik olarak yeni sınıflar oluşturmak.

Bu yazıda type() fonksiyonunun söz dizimini (syntax), hazır ve özel sınıflarla kullanım örneklerini, dinamik sınıf oluşturmadaki rolünü ve isinstance() ile arasındaki farkları göreceğiz.

Fonksiyon oldukça basit bir yapıya sahiptir. Lafı uzatmadan hemen söz dizimine bakalım.

Python type() Fonksiyonunun Söz Dizimi

Python’da birçok yerleşik (built-in) fonksiyon vardır. Bunlardan biri olan type(), bir nesnenin türünü öğrenmek için kullanılır.

Söz dizimi şu şekildedir:

type(object)
type(name, bases, dict)

Tek argüman verildiğinde type() fonksiyonu, nesnenin tipini döndürür. Bu değer aslında nesnenin __class__ özniteliğiyle aynıdır.

Üç argüman verildiğinde ise yeni bir tip (class) döndürür. Yani çalışma anında (runtime) dinamik bir sınıf oluşturabilirsin.

  • "isim" (name) → Oluşturulacak sınıfın adı olur. Bu, sınıfın __name__ özniteliğine denk gelir.
  • "tabanlar" (bases) → Sınıfın miras alacağı sınıfları belirtir. Bu da sınıfın __bases__ özniteliğine karşılık gelir.
  • "sözlük" (dict) → Sınıfın gövdesini (metod ve özelliklerini) tanımlar. Bu da sınıfın __dict__ özniteliğiyle aynıdır.

Kısacası:

  • 1 argüman → Tip öğrenme (object.__class__)
  • 3 argüman → Dinamik sınıf oluşturma (__name__, __bases__, __dict__)

Bu farkı bilmek, hem günlük tip kontrollerinde hem de daha ileri seviye dinamik programlamada işine çok yarar. 🐍

Python type() Fonksiyonu Örnekleri

Şimdi type() fonksiyonunun kullanımına dair bazı örneklere bakalım.

1. Bir Python nesnesinin tipini bulmak

x = 10
print(type(x))
# <class 'int'>

s = 'abc'
print(type(s))
# <class 'str'>

from collections import OrderedDict

od = OrderedDict()
print(type(od))
# <class 'collections.OrderedDict'>

class Veri:
pass

d = Veri()
print(type(d))
# <class '__main__.Veri'>
Output
<class 'int'>
<class 'str'>
<class 'collections.OrderedDict'>
<class 'main.Veri'>

Dikkat edersen, type() fonksiyonu nesnenin tipini modül adıyla birlikte döndürüyor.

Bizim yazdığımız Python dosyası herhangi bir ayrı modül değil, doğrudan çalıştırılan bir script olduğu için modül adı otomatik olarak __main__ oluyor.

Yani özel sınıflar tanımladığında, çıktı içinde __main__.<SınıfAdı> ifadesini görmen normaldir.

2. Python Sınıflarından Detayları Çıkarmak

Diyelim ki elimizde birkaç sınıf var. Bu sınıflardan bazı meta verileri alabiliriz. Bunun için sınıfların şu öznitelikleri işimize yarar:

  • __class__ → Nesnenin ait olduğu sınıf
  • __bases__ → Sınıfın miras aldığı taban sınıflar
  • __dict__ → Sınıfın sahip olduğu metotlar ve özellikler
  • __doc__ → Sınıfın dökümantasyon (docstring) metni

Bu öznitelikler sayesinde sınıfın yapısını daha yakından inceleyebiliriz.

class Veri:
"""Veri Sınıfı"""
v_id = 10

class AltVeri(Veri):
"""AltVeri Sınıfı"""
av_id = 20

Haydi bu sınıfların bazı özelliklerini ekrana yazdıralım.

print(Veri.__class__)     
# <class 'type'>

print(Veri.__bases__)
# (<class 'object'>,)

print(Veri.__dict__)
# {'__module__': '__main__', 'v_id': 10, '__doc__': 'Veri Sınıfı', ...}

print(Veri.__doc__)
# Veri Sınıfı


print(AltVeri.__class__)
# <class 'type'>

print(AltVeri.__bases__)
# (<class '__main__.Veri'>,)

print(AltVeri.__dict__)
# {'__module__': '__main__', 'av_id': 20, '__doc__': 'AltVeri Sınıfı', ...}

print(AltVeri.__doc__)
# AltVeri Sınıfı
Output:
<class 'type'>
(<class 'object'>,)
{'module': 'main', 'doc': 'Veri Sınıfı', 'v_id': 10, 'dict': <attribute 'dict' of 'Veri' objects>, 'weakref': <attribute 'weakref' of 'Veri' objects>}
Veri Sınıfı

<class 'type'>
(<class 'main.Veri'>,)
{'module': 'main', 'doc': 'AltVeri Sınıfı', 'av_id': 20}
AltVeri Sınıfı

Benzer sınıfları type() fonksiyonunu kullanarak da oluşturabiliriz.

Veri1 = type("Veri1", (object,), {"__doc__": "Veri1 Sınıfı", "v_id": 10})
AltVeri1 = type("AltVeri1", (Veri1,), {"__doc__": "AltVeri1 Sınıfı", "av_id": 20})

print(Veri1.__class__)
# <class 'type'>

print(Veri1.__bases__)
# (<class 'object'>,)

print(Veri1.__dict__)
# {'__module__': '__main__', '__doc__': 'Veri1 Sınıfı', 'v_id': 10, ...}

print(Veri1.__doc__)
# Veri1 Sınıfı


print(AltVeri1.__class__)
# <class 'type'>

print(AltVeri1.__bases__)
# (<class '__main__.Veri1'>,)

print(AltVeri1.__dict__)
# {'__module__': '__main__', '__doc__': 'AltVeri1 Sınıfı', 'av_id': 20, ...}

print(AltVeri1.__doc__)
# AltVeri1 Sınıfı
Output:
<class 'type'>
(<class 'object'>,)
{'doc': 'Veri1 Sınıfı', 'v_id': 10, 'module': 'main', 'dict': <attribute 'dict' of 'Veri1' objects>, 'weakref': <attribute 'weakref' of 'Veri1' objects>}
Veri1 Sınıfı

<class 'type'>
(<class 'main.Veri1'>,)
{'doc': 'AltVeri1 Sınıfı', 'av_id': 20, 'module': 'main'}
AltVeri1 Sınıfı

Unutma, type() fonksiyonunu kullanarak oluşturduğumuz dinamik sınıflara fonksiyonlar (metotlar) da ekleyebiliriz.


type() Fonksiyonunun Gerçek Hayattaki Kullanımı

Python dinamik tipli (dynamically-typed) bir dil olduğu için, bir değişkenin tipini öğrenmek istediğinde type() fonksiyonunu kullanabilirsin.

Eğer bir fonksiyonunun sadece belirli tiplerde çalışmasını istiyorsan, bunun için isinstance() fonksiyonu daha doğru tercih olur.

Mesela, iki tam sayı üzerinde işlem yapan bir fonksiyon yazmak istediğimizi düşünelim. Bunu şu şekilde uygulayabiliriz:

def hesapla(x, y, op='topla'):
if not(isinstance(x, int) and isinstance(y, int)):
print(f'Hatalı Argüman Tipi - x:{type(x)}, y:{type(y)}')
raise TypeError('Uygun olmayan tip, sadece tam sayı (int) olmalı')

if op == 'fark':
return x - y
if op == 'carp':
return x * y
# varsayılan işlem toplama
return x + y

isinstance() fonksiyonu, girilen argümanların tipini doğrulamak için kullanılır.

Eğer tip kontrolü başarısız olursa, bu durumda type() fonksiyonu ile parametrelerin hangi tipte olduğunu ekrana yazdırabiliriz.

Yani özetle:

  • isinstance() → Doğrulama için
  • type() → Hata anında tipi göstermek için

Değişken Tiplerini Doğru Kontrol Etmek

type() bir nesnenin tam tipini öğrenmende faydalı olsa da, koşullu kontrollerde her zaman en iyi seçenek değildir. Özellikle de kalıtım (inheritance) işin içine girdiğinde.

  • type(obj) == SomeClass
    Bu kontrol, obj tam olarak SomeClass sınıfından türemişse True döner.
    Eğer obj, SomeClass’ın bir alt sınıfından (subclass) geliyorsa False döner.

  • isinstance(obj, SomeClass)
    Bu kontrol ise obj’nin hem SomeClass sınıfından hem de onun alt sınıflarından biri olup olmadığını kontrol eder.
    Yani daha esnek bir yöntemdir ve polimorfizm mantığıyla daha uyumludur.

Kısacası:

  • Kesin sınıf kontrolütype()
  • Esnek ve kalıtım dostu kontrolisinstance()

type() vs isinstance() İçin En İyi Kullanım Önerileri

  • Fonksiyonlarda / Metotlarda Tip Doğrulama
    Belirli bir tip veya onun alt sınıflarını kabul etmek istiyorsan isinstance() kullan. Bu yaklaşım fonksiyonlarını daha esnek ve dayanıklı hale getirir.

  • Kesin Tip Tanımlama
    Bir nesnenin tam olarak hangi sınıfa ait olduğunu öğrenmek ve temel sınıf ile alt sınıfları ayırt etmek istiyorsan type() kullan.
    Bu genelde günlük uygulamalarda çok sık gerekmez ama framework geliştirirken veya çok özel senaryolarda işine yarayabilir.

  • Hata Ayıklama ve Loglama
    Bir nesnenin türünü anlamak için ekrana bastırman gerekiyorsa type() gayet idealdir. Debug sırasında ya da log tutarken hızlıca nesnenin doğasını anlamana yardımcı olur.


Sonuç

Python’daki type() fonksiyonu, nesnelerin tam yapısını anlamak ve dinamik sınıf oluşturma gibi ileri seviye senaryolarda oldukça önemli bir araçtır.

  • Tek argümanlı hali → Nesnenin tam sınıfını öğrenmek, hata ayıklama ve içgörü (introspection) için çok faydalıdır.
  • Üç argümanlı hali → Dinamik sınıf oluşturma sayesinde güçlü metaprogramlama imkânları sunar.

Ancak uygulama mantığında tip kontrolü yaparken, özellikle kalıtım (inheritance) söz konusu olduğunda, geliştiricilerin daha çok isinstance() kullanması önerilir. Bu sayede kod hem daha esnek hem de polimorfizme uygun hale gelir.

Daha fazla Python konusu için şu yazımıza da göz atabilirsin: