← Kursa Dön
📄 Text · 12 min

Tip Dönüşümleri

Programlamada farklı veri tipleri bir arada çalışır. Kullanıcıdan string olarak gelen veriyi sayıya çevirmen, bir sayıyı ekranda göstermek için string yapman veya bir float'ı int'e dönüştürmen gerekebilir. Bu derste Python'daki tip dönüşümlerini — hem otomatik hem de elle yapılanları — öğreneceksin.


Implicit Conversion (Örtük/Otomatik Dönüşüm)

Python, bazı durumlarda veri tipini otomatik olarak dönüştürür. Bu, daha dar tipten daha geniş tipe doğru olur — yani veri kaybı olmayacak şekilde.

Bunu bir su bardağı analojisi ile düşün. Küçük bardaktaki su büyük bardağa sorunsuz aktarılır ama büyük bardaktaki su küçük bardağa sığmayabilir. Python otomatik dönüşümde hep "büyük bardağa aktar" mantığını kullanır.

int + float → float

x = 10      # int
y = 3.14    # float

sonuc = x + y
print(sonuc)        # 13.14
print(type(sonuc))  # <class 'float'>

# int, otomatik olarak float'a dönüştürüldü
# 10 → 10.0, sonra 10.0 + 3.14 = 13.14

int + bool → int

bool, int'in alt sınıfı olduğu için doğrudan kullanılabilir:

x = 10
y = True    # True = 1

sonuc = x + y
print(sonuc)        # 11
print(type(sonuc))  # <class 'int'>

# True → 1 olarak işlem görür
print(10 + True)    # 11
print(10 + False)   # 10
print(10 * True)    # 10
print(10 * False)   # 0

bool + float → float

sonuc = True + 3.14
print(sonuc)        # 4.14
print(type(sonuc))  # <class 'float'>

# True → 1 → 1.0, sonra 1.0 + 3.14 = 4.14

Dönüşüm Hiyerarşisi

Python'un otomatik dönüşüm sıralaması:

bool → int → float → complex

Bir işlemde farklı tipler karşılaşırsa, Python daha "geniş" olan tipe dönüştürür:

# bool + int → int
print(type(True + 1))        # <class 'int'>

# int + float → float
print(type(1 + 1.0))         # <class 'float'>

# float + complex → complex
print(type(1.0 + 2j))        # <class 'complex'>

# bool + complex → complex
print(type(True + 2j))       # <class 'complex'>

String Otomatik Dönüşmez!

Python, string'leri otomatik olarak sayıya dönüştürmez. Bu, birçok dilden farklıdır:

# ❌ Bu hata verir!
# print("5" + 3)  # TypeError: can only concatenate str (not "int") to str

# JavaScript'te "5" + 3 = "53" olur (string birleştirme)
# Python buna izin vermez — açık ol, ne istediğini söyle

# ✅ Elle dönüştür
print(int("5") + 3)    # 8 (sayı toplama)
print("5" + str(3))    # "53" (string birleştirme)

💡 İpucu: Python'un tip dönüşümünde otomatik yapmayıp hata vermesi aslında iyi bir şey. "Explicit is better than implicit" (Açık olan örtük olandan iyidir) — Python Zen'inin temel ilkelerinden biri.


Explicit Conversion (Açık/Elle Dönüşüm)

Açık dönüşüm, sen istediğinde yapılan dönüşümdür. Python'un yerleşik fonksiyonlarını kullanırsın.

int() — Tam Sayıya Dönüştürme

# float → int (kırpar, yuvarlamaz!)
print(int(3.7))      # 3 (0.7 atılır)
print(int(3.2))      # 3
print(int(-3.7))     # -3 (sıfıra doğru kırpar)
print(int(-3.2))     # -3

# string → int
print(int("42"))     # 42
print(int("  42  ")) # 42 (başındaki/sonundaki boşluk OK)
print(int("-17"))    # -17
print(int("+5"))     # 5

# bool → int
print(int(True))     # 1
print(int(False))    # 0

# Farklı tabanlardan dönüşüm
print(int("FF", 16))     # 255 (hexadecimal)
print(int("1010", 2))    # 10 (binary)
print(int("77", 8))      # 63 (octal)
print(int("42", 10))     # 42 (decimal — varsayılan)

float() — Ondalıklı Sayıya Dönüştürme

# int → float
print(float(42))      # 42.0

# string → float
print(float("3.14"))  # 3.14
print(float("42"))    # 42.0
print(float("-2.5"))  # -2.5
print(float("1e3"))   # 1000.0 (bilimsel gösterim)
print(float("inf"))   # inf
print(float("-inf"))  # -inf
print(float("nan"))   # nan

# bool → float
print(float(True))    # 1.0
print(float(False))   # 0.0

str() — String'e Dönüştürme

# Sayı → string
print(str(42))       # '42'
print(str(3.14))     # '3.14'
print(str(True))     # 'True'
print(str(False))    # 'False'
print(str(None))     # 'None'

# Liste → string
print(str([1, 2, 3]))        # '[1, 2, 3]'
print(str({"a": 1, "b": 2})) # "{'a': 1, 'b': 2}"

# Kullanım: print içinde birleştirme
yas = 25
print("Yaş: " + str(yas))  # Yaş: 25
# Ama f-string daha iyi:
print(f"Yaş: {yas}")       # Yaş: 25

bool() — Boolean'a Dönüştürme

# Sayılar
print(bool(0))      # False
print(bool(1))      # True
print(bool(-1))     # True
print(bool(0.0))    # False
print(bool(0.1))    # True

# String'ler
print(bool(""))         # False (boş string)
print(bool("False"))    # True! (dolu string)
print(bool(" "))        # True! (boşluk bile dolu)

# Koleksiyonlar
print(bool([]))     # False (boş liste)
print(bool([0]))    # True (dolu liste — içi 0 olsa bile)
print(bool({}))     # False (boş dict)

# None
print(bool(None))   # False

⚠️ Dikkat: bool("False") sonucu True'dur! Çünkü "False" boş olmayan bir string'dir. String'in içeriğine bakmaz, dolu olup olmadığına bakar. "False" string'ini boolean'a çevirmek istiyorsan özel bir mantık yazman gerekir.

# "False" string'ini boolean'a çevirme
def str_to_bool(s):
    return s.lower() in ("true", "1", "yes", "evet")

print(str_to_bool("True"))    # True
print(str_to_bool("False"))   # False
print(str_to_bool("yes"))     # True
print(str_to_bool("evet"))    # True

input() ve Tip Dönüşümü

input() fonksiyonu kullanıcıdan veri alır ve her zaman string döner. Bu, en yaygın tip dönüşümü ihtiyacının kaynağıdır.

# input() her zaman string döner
isim = input("İsminiz: ")
print(type(isim))  # <class 'str'>

# Sayı almak istiyorsan dönüştürmen lazım
yas_str = input("Yaşınız: ")  # "25" (string)
yas = int(yas_str)              # 25 (int)

# Tek satırda:
yas = int(input("Yaşınız: "))

# Float için:
boy = float(input("Boyunuz (m): "))

# Hesaplama
dogum_yili = 2024 - yas
print(f"Doğum yılınız: {dogum_yili}")

Hatalı Giriş Kontrolü

Kullanıcı her zaman doğru veri girmez. "yirmibeş" yazıp tam sayıya çevirmeye çalışırsan hata alırsın.

# ❌ Hata verir
# sayi = int("yirmibeş")  # ValueError!

# ✅ try-except ile güvenli dönüşüm
while True:
    girdi = input("Bir tam sayı girin: ")
    try:
        sayi = int(girdi)
        print(f"Girdiğiniz sayı: {sayi}")
        break
    except ValueError:
        print(f"'{girdi}' geçerli bir tam sayı değil! Tekrar deneyin.")
# Genel amaçlı güvenli dönüşüm fonksiyonu
def guvenli_int(deger, varsayilan=0):
    """String'i int'e çevirir, başarısız olursa varsayılanı döner"""
    try:
        return int(deger)
    except (ValueError, TypeError):
        return varsayilan

def guvenli_float(deger, varsayilan=0.0):
    """String'i float'a çevirir, başarısız olursa varsayılanı döner"""
    try:
        return float(deger)
    except (ValueError, TypeError):
        return varsayilan

print(guvenli_int("42"))           # 42
print(guvenli_int("abc"))          # 0
print(guvenli_int("abc", -1))     # -1
print(guvenli_float("3.14"))      # 3.14
print(guvenli_float("xyz", 0.0))  # 0.0

Hatalı Dönüşüm: ValueError

Bir değer hedef tipe dönüştürülemezse ValueError hatası alırsın:

# int() hataları
# int("3.14")     # ValueError — float formatındaki string direkt int olmaz
# int("abc")      # ValueError
# int("")         # ValueError

# Çözüm: önce float, sonra int
print(int(float("3.14")))  # 3

# float() hataları
# float("abc")    # ValueError
# float("")       # ValueError

# Ancak bazı string'ler çalışır
print(float("inf"))     # inf
print(float("nan"))     # nan
print(float("1e10"))    # 10000000000.0
# TypeError — tip uyumsuzluğu
# int([1, 2, 3])    # TypeError — liste int'e çevrilemez
# float([1])         # TypeError
# int(None)          # TypeError — None int'e çevrilemez

# Ama str() neredeyse her şeyi çevirir
print(str([1, 2, 3]))   # '[1, 2, 3]'
print(str(None))         # 'None'
print(str({"a": 1}))    # "{'a': 1}"

chr() ve ord(): Karakter ↔ Sayı

Her karakter bir sayısal değere (Unicode code point) karşılık gelir. ord() karakteri sayıya, chr() sayıyı karaktere çevirir.

# ord() — karakter → sayı (Unicode code point)
print(ord('A'))    # 65
print(ord('a'))    # 97
print(ord('0'))    # 48
print(ord('Z'))    # 90
print(ord(' '))    # 32
print(ord('ş'))    # 351
print(ord('€'))    # 8364
print(ord('🐍'))   # 128013

# chr() — sayı → karakter
print(chr(65))     # A
print(chr(97))     # a
print(chr(48))     # 0
print(chr(351))    # ş
print(chr(128013)) # 🐍

Pratik Kullanımlar

# ASCII tablosu yazdır
for i in range(32, 127):
    print(f"{i:3d} = {chr(i)}", end="  ")
    if (i - 31) % 8 == 0:
        print()

# Harf → sıra numarası
harf = 'C'
sira = ord(harf) - ord('A') + 1
print(f"'{harf}' alfabenin {sira}. harfi")  # 'C' alfabenin 3. harfi

# Sezar şifrelemesi
def sezar_sifrele(metin, kayma):
    sonuc = ""
    for karakter in metin:
        if karakter.isalpha():
            base = ord('A') if karakter.isupper() else ord('a')
            sonuc += chr((ord(karakter) - base + kayma) % 26 + base)
        else:
            sonuc += karakter
    return sonuc

sifrelenmis = sezar_sifrele("Hello World", 3)
print(sifrelenmis)  # Khoor Zruog

cozulmus = sezar_sifrele(sifrelenmis, -3)
print(cozulmus)     # Hello World
# Karakterleri kontrol et
print(chr(65).isalpha())   # True — A
print(chr(48).isdigit())   # True — 0
print(chr(32).isspace())   # True — boşluk

# Büyük-küçük harf dönüşümü (elle)
karakter = 'a'
buyuk = chr(ord(karakter) - 32)  # a(97) - 32 = A(65)
print(buyuk)  # A

# Tabii ki .upper() kullanmak daha iyi:
print('a'.upper())  # A

bin(), oct(), hex(): Sayı Sistemleri

Bu fonksiyonlar tam sayıları farklı sayı sistemlerinde string olarak gösterir.

sayi = 255

# İkili (binary) — taban 2
print(bin(sayi))   # '0b11111111'

# Sekizli (octal) — taban 8
print(oct(sayi))   # '0o377'

# Onaltılı (hexadecimal) — taban 16
print(hex(sayi))   # '0xff'

# Ön ek olmadan
print(bin(sayi)[2:])   # '11111111'
print(oct(sayi)[2:])   # '377'
print(hex(sayi)[2:])   # 'ff'

# f-string ile (ön ek olmadan)
print(f"{sayi:b}")     # 11111111
print(f"{sayi:o}")     # 377
print(f"{sayi:x}")     # ff
print(f"{sayi:X}")     # FF (büyük harf)

# Ön ek ile
print(f"{sayi:#b}")    # 0b11111111
print(f"{sayi:#o}")    # 0o377
print(f"{sayi:#x}")    # 0xff

Geri Dönüşüm

# String → int (belirli tabandan)
print(int('11111111', 2))   # 255
print(int('377', 8))        # 255
print(int('ff', 16))        # 255
print(int('0xff', 16))      # 255 (ön ekle de çalışır)
print(int('0b11111111', 2)) # 255

# Pratik: Renk kodu dönüşümü
renk_hex = "#FF8C00"  # Koyu turuncu
r = int(renk_hex[1:3], 16)  # 255
g = int(renk_hex[3:5], 16)  # 140
b = int(renk_hex[5:7], 16)  # 0
print(f"RGB({r}, {g}, {b})")  # RGB(255, 140, 0)

Bit İşlemleri Gösterimi

a = 0b1100  # 12
b = 0b1010  # 10

print(f"a       = {a:04b} ({a})")    # 1100 (12)
print(f"b       = {b:04b} ({b})")    # 1010 (10)
print(f"a & b   = {a & b:04b} ({a & b})")    # 1000 (8)
print(f"a | b   = {a | b:04b} ({a | b})")    # 1110 (14)
print(f"a ^ b   = {a ^ b:04b} ({a ^ b})")    # 0110 (6)

eval() Tehlikesi: Neden Kullanmamalı

eval() fonksiyonu, bir string'i Python ifadesi olarak çalıştırır. Güçlü ama çok tehlikeli.

# eval() bir string'i Python kodu olarak çalıştırır
print(eval("2 + 3"))        # 5
print(eval("'hello'.upper()"))  # HELLO

x = 10
print(eval("x * 2"))        # 20

# Tip dönüşümü gibi kullanmak cazip gelebilir:
sayi = eval(input("Sayı girin: "))  # ❌ ASLA YAPMA!

Neden Tehlikeli?

Kullanıcı eval() içine herhangi bir Python kodu yazabilir:

# Kullanıcı şunu girerse:
# __import__('os').system('rm -rf /')  → Tüm sistemi siler!
# __import__('os').system('cat /etc/passwd')  → Şifreleri okur!

# ❌ TEHLİKELİ
# sonuc = eval(input("Hesaplama: "))

# ✅ GÜVENLİ alternatifler:
# 1. int() veya float() kullan
sayi = int(input("Sayı: "))

# 2. Basit hesap makinesi için ast.literal_eval
import ast
# Sadece literal değerleri değerlendirir (sayı, string, liste, dict)
print(ast.literal_eval("42"))           # 42
print(ast.literal_eval("[1, 2, 3]"))    # [1, 2, 3]
print(ast.literal_eval("{'a': 1}"))     # {'a': 1}

# ast.literal_eval tehlikeli kodu çalıştırmaz:
# ast.literal_eval("__import__('os').system('ls')")  # ValueError!

⚠️ Dikkat: eval() ve exec() fonksiyonlarını kullanıcı girdisiyle asla kullanma. Bu, güvenlik açığı oluşturur. Eğer kullanıcıdan matematiksel ifade almak istiyorsan, özel bir parser yaz veya güvenli bir kütüphane kullan.

# eval() yerine güvenli matematik hesaplayıcı
def guvenli_hesapla(ifade):
    """Sadece basit matematik işlemlerine izin ver"""
    izinli_karakterler = set("0123456789+-*/.() ")
    
    if not all(c in izinli_karakterler for c in ifade):
        raise ValueError("Geçersiz karakter!")
    
    # Hâlâ eval kullanıyor — production'da daha iyi çözüm gerekir
    return eval(ifade)

print(guvenli_hesapla("2 + 3 * 4"))  # 14
# guvenli_hesapla("__import__('os')")  # ValueError!

Type Checking: isinstance() vs type()

Tip kontrolü yapmanın iki yolu var. Hangisini ne zaman kullanacağını bilmek önemli.

type() ile Kontrol

x = 42
print(type(x) == int)     # True
print(type(x) == float)   # False

# Birden fazla tip kontrolü
if type(x) == int or type(x) == float:
    print("Sayısal değer")

isinstance() ile Kontrol (Önerilen)

x = 42
print(isinstance(x, int))          # True
print(isinstance(x, float))        # False
print(isinstance(x, (int, float))) # True — birden fazla tip

# isinstance kalıtımı dikkate alır
print(isinstance(True, int))       # True (bool, int'in alt sınıfı)
print(type(True) == int)           # False (tam tip eşleşmesi)

Fark: Kalıtım (Inheritance)

# type() sadece tam eşleşmeye bakar
# isinstance() kalıtım zincirini de kontrol eder

print(type(True) == bool)          # True
print(type(True) == int)           # False — bool != int
print(isinstance(True, int))       # True — bool, int'in alt sınıfı

# Özel sınıflarla
class Hayvan:
    pass

class Kedi(Hayvan):
    pass

kedi = Kedi()
print(type(kedi) == Hayvan)        # False
print(type(kedi) == Kedi)          # True
print(isinstance(kedi, Hayvan))    # True — Kedi, Hayvan'ın alt sınıfı
print(isinstance(kedi, Kedi))      # True

Ne Zaman Hangisi?

# ✅ isinstance() kullan — çoğu durumda doğru seçim
if isinstance(deger, (int, float)):
    print("Sayısal değer")

# ✅ type() kullan — tam tip eşleşmesi gerekiyorsa
if type(deger) is int:  # bool'u hariç tut
    print("Kesinlikle int, bool değil")

# 🐍 Duck typing — en Pythonic yaklaşım
# "Tip kontrol etme, dene ve hata yakala"
def iki_katina_cik(deger):
    try:
        return deger * 2
    except TypeError:
        return str(deger) * 2

💡 İpucu: Python'da "duck typing" prensibi hâkimdir: "Eğer ördek gibi yürüyorsa ve ördek gibi vaklıyorsa, o bir ördektir." Yani tipe bakmak yerine, nesnenin istenen işlemi yapıp yapamadığına bak. isinstance() kontrolü yerine try/except kullanmak genellikle daha Pythonic'tir.


Dönüşüm Tablosu

Hangi dönüşümler çalışır, hangisi hata verir? İşte kapsamlı bir tablo:

# int() dönüşümleri
int(42)          # 42 — zaten int
int(3.14)        # 3 — kırpar
int(True)        # 1
int(False)       # 0
int("42")        # 42
int("3.14")      # ❌ ValueError (önce float sonra int yap)
int("")          # ❌ ValueError
int(None)        # ❌ TypeError
int([1])         # ❌ TypeError

# float() dönüşümleri
float(42)        # 42.0
float(3.14)      # 3.14 — zaten float
float(True)      # 1.0
float(False)     # 0.0
float("3.14")    # 3.14
float("42")      # 42.0
float("")        # ❌ ValueError
float(None)      # ❌ TypeError

# str() dönüşümleri — neredeyse hiç hata vermez
str(42)          # '42'
str(3.14)        # '3.14'
str(True)        # 'True'
str(None)        # 'None'
str([1, 2])      # '[1, 2]'
str({"a": 1})    # "{'a': 1}"

# bool() dönüşümleri — hiç hata vermez
bool(42)         # True
bool(0)          # False
bool("abc")      # True
bool("")         # False
bool(None)       # False
bool([1])        # True
bool([])         # False

Dönüşüm Zincirleri

Bazen birden fazla dönüşüm adımı gerekir:

# String float → int (iki adım)
metin = "3.14"
# int(metin)  # ❌ ValueError
sayi = int(float(metin))  # ✅ 3

# Sayı → binary string → sayı
n = 42
binary = bin(n)        # '0b101010'
geri = int(binary, 2)  # 42

# Liste → string → tekrar liste
import ast
liste = [1, 2, 3]
metin = str(liste)                  # '[1, 2, 3]'
geri_liste = ast.literal_eval(metin) # [1, 2, 3]

Pratik Örnekler

Gelişmiş Input Fonksiyonu

def input_int(mesaj, min_val=None, max_val=None):
    """Kullanıcıdan güvenli int alır, sınır kontrolü yapar"""
    while True:
        try:
            deger = int(input(mesaj))
            if min_val is not None and deger < min_val:
                print(f"En az {min_val} olmalı!")
                continue
            if max_val is not None and deger > max_val:
                print(f"En fazla {max_val} olmalı!")
                continue
            return deger
        except ValueError:
            print("Geçerli bir tam sayı girin!")

# Kullanım
# yas = input_int("Yaşınız: ", min_val=0, max_val=150)
# not_degeri = input_int("Notunuz (0-100): ", 0, 100)

Tip Raporlayıcı

def tip_raporu(deger):
    """Değerin tip bilgilerini ayrıntılı raporlar"""
    print(f"Değer:         {deger!r}")
    print(f"Tip:           {type(deger).__name__}")
    print(f"Bool değeri:   {bool(deger)}")
    print(f"str():         {str(deger)!r}")
    
    # Sayısal dönüşümler
    for func_name, func in [("int", int), ("float", float)]:
        try:
            sonuc = func(deger)
            print(f"{func_name}():       {sonuc}")
        except (ValueError, TypeError):
            print(f"{func_name}():       ❌ Dönüştürülemez")
    
    print("-" * 35)

tip_raporu(42)
tip_raporu("3.14")
tip_raporu(True)
tip_raporu(None)
tip_raporu([1, 2])

Özet

  • Implicit conversion: Python, int + floatfloat gibi güvenli dönüşümleri otomatik yapar; string'leri otomatik dönüştürmez.

  • Explicit conversion: int(), float(), str(), bool() fonksiyonlarıyla elle dönüşüm yap.

  • `input()` her zaman string döner — sayı almak için int(input()) veya float(input()) kullan.

  • Hatalı dönüşümler `ValueError` verir — kullanıcı girdisini her zaman try/except ile kontrol et.

  • `chr()`/`ord()` karakter ↔ sayı, `bin()`/`oct()`/`hex()` sayı → farklı tabanlar.

  • `eval()` tehlikelidir — kullanıcı girdisiyle asla kullanma; int(), float() veya ast.literal_eval() tercih et.