koddla

Yazılımcıları bilgi ile güçlendirir.

Python’da veri tipi öğrenme

Diyelimki aşağıdaki gibi bir değişkenimiz var:

one = 1

Bu değişkenin veri tipini bilmek isteriz.

Elbette, Python’daki her şeyde olduğu gibi, bunu yapmanın doğru ve yanlış yolları var. Doğru yola bakalım:

type ile veri tipi sorgulama

>>> type(one)
<type 'int'>

Döndürülen cevabı kullanarak veri tipinin ismini öğrenelim. Bunun için nesnenin __name__ özelliğini kullanabiliriz. (Bu özellik objenin ismini öğrenebileceğimiz bir kaç dunder özeliğinden biri. Çift alt çizgili özellikler dunder olarak anılır – double under : dunder. )

>>> type(one).__name__
'int'

__class__ özelliğini kullanmayın

Python’da, alt çizgi ile başlayan özellikler semantik olarak genel API içerisinde yer almaz. Dolayısıyla bu özellikleri kullanmaktan kaçınmak yararlı olacaktır. (Tabiki mutlaka gerekli olduğu durumlar hariç.)

type fonksiyonu bize nesnenin sınıfını verdiğine göre, bu bilgiyi direkt bir şekilde almaktan kaçınırız:

>>> one.__class__

Kod yazarken genellikle bir nesnenin tipini öğrenmek istediğimizde aklımıza ilk gelen yol budur. Ne de olsa nesnenin hangi sınıfa ait olduğunu öğrenmek istiyoruz değil mi – bu sebeple type aklımıza gelmez. Örneğin, aşağıdakini yaparız:

class Foo(object):
    def foo(self):
        self.__class__

Bunu yapmayın. Bunun yerine, type(self) kullanın:

class Foo(object):
    def foo(self):
        type(self)

type()’ın bir diğer kullanım yeri – metaclass

type()’tan bahsediyorsak type’ın bir diğer özelliği olan metaclass’lardan da kısaca bahsetmemiz gerekir.

Metaclass’lar sınıf oluşturan şeylerdir. Bir nesne oluşturmak için sınıf tanımlamamız gerekir. Python’da her şey sınıf olduğuna göre, her şeyi oluşturacak bir “şey”‘e ihtiyaç vardır. İşte burda metaclass devreye girer.

Peki bunların type() ile ilgisi ne? type birden fazla argüman ile kullanıldığında metaclass görevi görür. Yani bir sınıf oluşturur. Yani; type, Python’da arkaplanda diğer sınıfları oluşturmak için kullanılır.

type ile şunu yaparız:

MyClass = type('MyClass', (), {})

Bu bilgiyi aklımızda tutarak tekrar konumuza dönelim. Python’da nesne türünü nasıl belirleriz?


Python’da aslında bir nesnenin türünü öğrenmek için iki fonksiyon bulunur. Birincisi olan type() ile bir nesnenin tam olarak tipini belirleriz. İkincisi olan isinstance() ile ise bu nesnenin türünü bir şeye karşı kontrol ederiz. Genellikle, bu sebeple, isinstance() kullanmak isteriz. Çünkü isinstance hem dadha hızlıdır hem de tür mirasını destekler.


Haliyle, bir nesnenin türünü elde etmek için type() fonksiyonunu kullanmalıyız. type()’a bir nesneyi tek parametre olarak verdiğimizde o nesnenin türünü alırız:

>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True

Bu fonksiyon tabiki yerleşik olmayan türler için de kullanılır:

>>> class Test1 (object):
        pass
>>> class Test2 (Test1):
        pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True

type() bu objenin türünü belirlese de, miras hakkında bir şey söylemez:

>>> type(b) is Test1
False

Bu durumun üstesinden gelmek için isinstance kullanırız. Tabiki isinstance da hem yerleşik türler için hem de yerleşik olmayan türler için çalışır:

>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True

isinstance() genellikle miras açısından tercih edilen yöntemdir. Yani sadece nesnenin tipini öğrenmek istemediğimiz zamanlarda – ne sebeple olursa olsun – type() yerine isinstance() kullanmayı tercih ederiz.

isinstance()‘a vereceğimiz ikinci parametre aynı zamanda bir demet olalbilir. Bu şekilde nesnemizi birden fazla türü için kontrol edebilirizisinstance demetteki türlerden birisi ile karşılık bulursa true döndürür:

>>> isinstance([], (tuple, list, set))
True

Sonuç

Öncelikle, __class__ kullanmayın. Bunun yerine type kullanın. Eğer nesnenin türünü karşılaştırmak için kullanacaksanız veya miras önemli ise isinstance() tercih edin.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Back to top