You are on page 1of 918

Kapak: Levent Gler

Python 3 iin Trke Klavuz


Srm 3

Yazan: Frat zgl

16.05.2016
NDEKLER

1 Bu Kitap Hakknda 1
1.1 Bu Kitab Nereden ndirebilirim? . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 Bu Kitaptan Nasl Yararlanabilirim? . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3 Nereden Yardm Alabilirim? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Projeye Nasl Yardmc Olabilirim? . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5 Kullanm Koullar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

2 Python Hakknda 4
2.1 Python Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.2 Neden Programlama renmek steyeyim? . . . . . . . . . . . . . . . . . . . . 4
2.3 Neden Python? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 Python Nasl Telaffuz Edilir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5 Platform Destei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.6 Farkl Python Srmleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.7 Hangi Seriyi renmeliyim? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

3 Python Nasl Kurulur? 8


3.1 GNU/Linux Kullanclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
3.2 Windows Kullanclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3 Python Kurulum ve alma Dizini . . . . . . . . . . . . . . . . . . . . . . . . . 14

4 Python Nasl altrlr? 15


4.1 GNU/Linux Kullanclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
4.2 Windows Kullanclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.3 Hangi Komut Hangi Srm altryor? . . . . . . . . . . . . . . . . . . . . . . 22
4.4 Sistem Komut Satr ve Python Komut Satr . . . . . . . . . . . . . . . . . . . . 22

5 Etkileimli Python 23
5.1 Etkileimli Kabukta lk Admlar . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
5.2 Etkileimli Kabuun Hafzas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

6 print() Fonksiyonu 49
6.1 Nedir, Ne e Yarar? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
6.2 Nasl Kullanlr? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
6.3 Bir Fonksiyon Olarak print() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
6.4 print() Fonksiyonunun Parametreleri . . . . . . . . . . . . . . . . . . . . . . . . 55
6.5 Birka Pratik Bilgi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65

i
7 Ka Dizileri 73
7.1 Ters Taksim (\) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
7.2 Satr Ba (\n) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
7.3 Sekme (\t) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
7.4 Zil Sesi (\a) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
7.5 Ayn Satr Ba (\r) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
7.6 Dey Sekme (\v) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.7 mle Kaydrma (\b) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
7.8 Kk Unicode (\u) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
7.9 Byk Unicode (\U) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
7.10 Uzun Ad (\N) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
7.11 Onaltl Karakter (\x) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
7.12 Etkisizletirme (r) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.13 Sayfa Ba (\f) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.14 Ka Dizilerine Toplu Bak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91

8 Programlar Kaydetme ve altrma 92


8.1 GNU/Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
8.2 Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94

9 alma Ortam Tavsiyesi 96


9.1 Windows Kullanclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
9.2 GNU/Linux Kullanclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
9.3 Metin Dzenleyici Ayarlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
9.4 MS-DOS Komut Satr Ayarlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
9.5 Program rnekleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100

10 Yorum ve Aklama Cmleleri 104


10.1 Yorum areti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
10.2 Yorum aretinin Farkl Kullanmlar . . . . . . . . . . . . . . . . . . . . . . . . . 106

11 Kullancdan Bilgi Almak 109


11.1 input() Fonksiyonu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
11.2 Tip Dnmleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
11.3 eval() ve exec() Fonksiyonlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
11.4 format() Metodu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

12 Koullu Durumlar 133


12.1 Koul Deyimleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
12.2 rnek Uygulama . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145

13 leler 147
13.1 Aritmetik leler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
13.2 Karlatrma leleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
13.3 Bool leleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
13.4 Deer Atama leleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 162
13.5 Aitlik leleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
13.6 Kimlik leleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
13.7 Uygulama rnekleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169

14 Dngler (Loops) 180


14.1 while Dngs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181
14.2 for Dngs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188

ii
14.3 lgili Aralar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
14.4 rnek Uygulamalar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201

15 Hata Yakalama 213


15.1 Hata Trleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
15.2 try... except... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
15.3 try... except... as... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
15.4 try... except... else... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220
15.5 try... except... nally... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
15.6 raise . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
15.7 Btn Hatalar Yakalamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
15.8 rnek Uygulama . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 224

16 Karakter Dizileri 226


16.1 Karakter Dizilerinin elerine Erimek . . . . . . . . . . . . . . . . . . . . . . . 227
16.2 Karakter Dizilerini Dilimlemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
16.3 Karakter Dizilerini Ters evirmek . . . . . . . . . . . . . . . . . . . . . . . . . . 236
16.4 Karakter Dizilerini Alfabe Srasna Dizmek . . . . . . . . . . . . . . . . . . . . . 238
16.5 Karakter Dizileri zerinde Deiiklik Yapmak . . . . . . . . . . . . . . . . . . . . 240
16.6 nemli Fonksiyon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
16.7 Notlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250

17 Karakter Dizilerinin Metotlar 252


17.1 replace() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
17.2 split(), rsplit(), splitlines() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
17.3 lower() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
17.4 upper() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
17.5 islower(), isupper() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
17.6 endswith() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
17.7 startswith() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267

18 Karakter Dizilerinin Metotlar (Devam) 269


18.1 capitalize() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
18.2 title() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
18.3 swapcase() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
18.4 casefold() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
18.5 strip(), lstrip(), rstrip() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
18.6 join() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
18.7 count() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
18.8 index(), rindex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
18.9 nd, rnd() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
18.10 center() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
18.11 rjust(), ljust() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
18.12 zll() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 290
18.13 partition(), rpartition() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
18.14 encode() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
18.15 expandtabs() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292

19 Karakter Dizilerinin Metotlar (Devam) 293


19.1 str.maketrans(), translate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
19.2 isalpha() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304
19.3 isdigit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305

iii
19.4 isalnum() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
19.5 isdecimal() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
19.6 isidentier() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
19.7 isnumeric() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
19.8 isspace() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
19.9 isprintable() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307

20 Karakter Dizilerini Biimlendirmek 309


20.1 % areti ile Biimlendirme (Eski Yntem) . . . . . . . . . . . . . . . . . . . . . 311
20.2 format() Metodu ile Biimlendirme (Yeni Yntem) . . . . . . . . . . . . . . . . . 323

21 Listeler ve Demetler 332


21.1 Listeler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333
21.2 Demetler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367

22 Listelerin ve Demetlerin Metotlar 372


22.1 Listelerin Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
22.2 Demetlerin Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383

23 Sayma Sistemleri 385


23.1 Onlu Sayma Sistemi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385
23.2 Sekizli Sayma Sistemi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
23.3 On Altl Sayma Sistemi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
23.4 kili Sayma Sistemi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390
23.5 Sayma Sistemlerini Birbirine Dntrme . . . . . . . . . . . . . . . . . . . . . 391
23.6 Sayma Sistemlerinin Birbirlerine Kar Avantajlar . . . . . . . . . . . . . . . . . 394

24 Saylar 396
24.1 Saylarn Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
24.2 Aritmetik Fonksiyonlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400

25 Temel Dosya lemleri 404


25.1 Dosya Oluturmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
25.2 Dosyaya Yazmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
25.3 Dosya Okumak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
25.4 Dosyalar Otomatik Kapatma . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
25.5 Dosyay leri-Geri Sarmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
25.6 Dosyalarda Deiiklik Yapmak . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
25.7 Dosyaya Erime Kipleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416

26 Dosyalarn Metot ve Nitelikleri 419


26.1 closed Nitelii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
26.2 readable() Metodu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
26.3 writable() Metodu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
26.4 truncate() Metodu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
26.5 mode Nitelii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
26.6 name Nitelii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
26.7 encoding Nitelii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422

27 kili (Binary ) Dosyalar 423


27.1 kili Dosyalarla rnekler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424

28 Basit bir letiim Modeli 432

iv
28.1 8 Bitlik bir Sistem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
28.2 Hata Kontrol . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
28.3 Karakterlerin Temsili . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 436

29 Karakter Kodlama (Character Encoding ) 439


29.1 Giri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 439
29.2 ASCII . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
29.3 UNICODE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449
29.4 Konu ile ilgili Fonksiyonlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458

30 Baytlar (Bytes) ve Bayt Dizileri (Bytearrays) 463


30.1 Giri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
30.2 Eskisi ve Yenisi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465
30.3 Bayt Tanmlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
30.4 bytes() Fonksiyonu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
30.5 Baytlarn Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
30.6 Bayt Dizileri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
30.7 Bayt Dizilerinin Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470

31 Szlkler 472
31.1 Szlk Tanmlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
31.2 Szlk elerine Erimek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
31.3 Szlklerin Yaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
31.4 Szlklere e Eklemek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
31.5 Szlk eleri zerinde Deiiklik Yapmak . . . . . . . . . . . . . . . . . . . . . 484
31.6 Szlk reteleri (Dictionary Comprehensions ) . . . . . . . . . . . . . . . . . . 484

32 Szlklerin Metotlar 486


32.1 keys() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
32.2 values() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
32.3 items() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488
32.4 get() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
32.5 clear() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
32.6 copy() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491
32.7 fromkeys() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492
32.8 pop() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
32.9 popitem() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
32.10 setdefault() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
32.11 update() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494

33 Kmeler ve Dondurulmu Kmeler 496


33.1 Kmeler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
33.2 Dondurulmu Kmeler (Frozenset) . . . . . . . . . . . . . . . . . . . . . . . . . 512

34 Fonksiyonlar 513
34.1 Fonksiyon Nedir ve Ne e Yarar? . . . . . . . . . . . . . . . . . . . . . . . . . . 513
34.2 Fonksiyon Tanmlamak ve armak . . . . . . . . . . . . . . . . . . . . . . . . 517
34.3 Fonksiyonlarn Yaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
34.4 Fonksiyonlar Ne e Yarar? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
34.5 Parametreler ve Argmanlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 528
34.6 return Deyimi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
34.7 rnek bir Uygulama . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 539

v
34.8 Fonksiyonlarn Kapsam ve global Deyimi . . . . . . . . . . . . . . . . . . . . . 543

35 Gml Fonksiyonlar 548


35.1 abs() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
35.2 round() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
35.3 all() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 550
35.4 any() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
35.5 ascii() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552
35.6 repr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 553
35.7 bool() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
35.8 bin() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
35.9 bytes() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 554
35.10 bytearray() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 557
35.11 chr() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558
35.12 list() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558
35.13 set() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
35.14 tuple() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
35.15 frozenset() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559
35.16 complex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
35.17 oat() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
35.18 int() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560
35.19 str() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 561
35.20 dict() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562
35.21 callable() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
35.22 ord() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
35.23 oct() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
35.24 hex() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 563
35.25 eval(), exec(), globals(), locals(), compile() . . . . . . . . . . . . . . . . . . . . . . 564
35.26 copyright() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
35.27 credits() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
35.28 license() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
35.29 dir() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
35.30 divmod() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568
35.31 enumerate() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 569
35.32 exit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
35.33 help() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
35.34 id() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571
35.35 input() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
35.36 format() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
35.37 lter() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
35.38 hash() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575
35.39 isinstance() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575
35.40 len() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576
35.41 map() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576
35.42 max() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577
35.43 min() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
35.44 open() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
35.45 pow() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
35.46 print() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
35.47 quit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
35.48 range() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 585

vi
35.49 reversed() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
35.50 sorted() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
35.51 slice() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
35.52 sum() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
35.53 type() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
35.54 zip() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 595
35.55 vars() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596

36 leri Dzey Fonksiyonlar 598


36.1 Lambda Fonksiyonlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
36.2 zyinelemeli (Recursive ) Fonksiyonlar . . . . . . . . . . . . . . . . . . . . . . . 602

37 Modller 615
37.1 Modl Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 615
37.2 Hazr Modller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 617
37.3 Modllerin e Aktarlmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
37.4 Kendi Tanmladmz Modller . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
37.5 nc ahs Modlleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
37.6 __all__ Listesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 635
37.7 Modllerin zel Nitelikleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638

38 Nesne Tabanl Programlama (OOP) 648


38.1 Giri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648
38.2 Snar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 649
38.3 Snar Ne e Yarar? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 650
38.4 Snf Tanmlamak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 658
38.5 Snf Nitelikleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659
38.6 Snarn rneklenmesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 661
38.7 rnek Nitelikleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
38.8 __init__ Fonksiyonu ve self . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667
38.9 rnek Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673

39 Nesne Tabanl Programlama (Devam) 680


39.1 Snf Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 680
39.2 @classmethod Bezeyicisi ve cls . . . . . . . . . . . . . . . . . . . . . . . . . . . 685
39.3 Alternatif naclar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688
39.4 Statik Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
39.5 @staticmethod Bezeyicisi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697

40 Nesne Tabanl Programlama (Devam) 701


40.1 Nesneler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701
40.2 Nesne Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701
40.3 Basit Bir Oyun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703
40.4 Her ey Bir Nesnedir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713
40.5 Birinci Snf eler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714

41 Nesne Tabanl Programlama (Devam) 717


41.1 Snf yeleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
41.2 @property Bezeyicisi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727

42 Nesne Tabanl Programlama (Devam) 738


42.1 Miras Alma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 738
42.2 Taban Snar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 740

vii
42.3 Alt Snar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742
42.4 Miras Alma Trleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744
42.5 super() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 750
42.6 object Snf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 753

43 Nesne Tabanl Programlama (Devam) 756


43.1 Tkinter Hakknda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 756
43.2 Prosedrel Bir rnek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 757
43.3 Sn Bir rnek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 762
43.4 oklu Miras Alma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 764
43.5 Dahil Etme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 767

44 Nesne Tabanl Programlama (Devam) 769


44.1 na, lklendirme ve Sonlandrma . . . . . . . . . . . . . . . . . . . . . . . . . . 769

45 Paketler 771
45.1 Paket Nedir? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
45.2 Paket Trleri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772
45.3 Paketlerin e Aktarlmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774
45.4 Kendi Oluturduumuz Paketler . . . . . . . . . . . . . . . . . . . . . . . . . . . 777

46 Dzenli fadeler 786


46.1 Dzenli fadelerin Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 787
46.2 Metakarakterler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794
46.3 Eleme Nesnelerinin Metotlar . . . . . . . . . . . . . . . . . . . . . . . . . . . 810
46.4 zel Diziler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812
46.5 Dzenli fadelerin Derlenmesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814
46.6 Dzenli fadelerle Metin/Karakter Dizisi Deitirme lemleri . . . . . . . . . . 816
46.7 Sonu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 820

47 Sqlite ile Veritaban Programlama 821


47.1 Giri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821
47.2 Neden Sqlite? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 821
47.3 Sqliten Yaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 822
47.4 Yardmc Aralar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823
47.5 Yeni Bir Veritaban Oluturmak . . . . . . . . . . . . . . . . . . . . . . . . . . . 824
47.6 Varolan Bir Veritabanyla Balant Kurmak . . . . . . . . . . . . . . . . . . . . . 826
47.7 mle Oluturma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826
47.8 Tablo Oluturma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827
47.9 artl Tablo Oluturma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 828
47.10 Tabloya Veri Girme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 829
47.11 Verilerin Veritabanna lenmesi . . . . . . . . . . . . . . . . . . . . . . . . . . . 830
47.12 Veritabannn Kapatlmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 831
47.13 Parametreli Sorgular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 832
47.14 Tablodaki Verileri Semek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 833
47.15 Seilen Verileri Almak . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 834
47.16 Veri Szme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 839
47.17 Veritaban Gvenlii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 840
47.18 Blm Sorular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845

48 nemli Standart Ktphane Modlleri 847


48.1 os Modl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 847

viii
48.2 sys Modl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 865
48.3 random Modl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 877
48.4 datetime Modl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 881
48.5 time Modl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 892

49 Katkda Bulunanlar 897


49.1 Barbaros Akkurt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 898
49.2 ebnem Duyar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
49.3 Onur Eker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
49.4 Emre Erzgn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
49.5 Tayfun Yaar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
49.6 Metin Hrn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
49.7 Ahmet ztekin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 899
49.8 Mesut diz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900
49.9 Levent Civa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900
49.10 Frat Ekinci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900
49.11 Talha Kesler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900
49.12 mer Gk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900
49.13 Yunus Emre Bulut . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900
49.14 Erhan Paaolu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 900
49.15 Cemre Efe Karaka . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901
49.16 Salim Yldrm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901
49.17 aatay Genlik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901
49.18 Valeh Asadl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901
49.19 Halit Turan Arcan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901
49.20 Levent Gler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901
49.21 Yaar Celep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902
49.22 Uur Uyar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902
49.23 Serdar alar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902
49.24 Ahmet Onur Yldrm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 902
49.25 Anl lginolu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 903
49.26 Hseyin Ula Yeltrk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 903
49.27 Nuri Acar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 903
49.28 Azat Frat imen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 903
49.29 Aykut Karda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 903
49.30 Sezer Bozkr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 903
49.31 Alican Uzunhan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 903
49.32 zgr zer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904
49.33 Kerim Yldz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904
49.34 Muhammed Ylmaz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904
49.35 Ahmet Erdoan . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904
49.36 Abdurrahman Dursun . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 904
49.37 Tahir Uzelli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
49.38 Mehmet Akbay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
49.39 Mehmet elikyontar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
49.40 Sava Zengin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
49.41 Tuncay Gven . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
49.42 Cafer Ulu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
49.43 Nikita Trkmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
49.44 Axolotl Axolotl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905

ix
x
BLM 1

Bu Kitap Hakknda

Elinizdeki kitap, Python programlama dili iin kapsaml bir Trke kaynak oluturma
projesi olan istihza.comun bir rndr. Bu kitabn amac, herhangi bir sebeple Python
programlama diline ilgi duyan, bu programlama dilini renmek isteyen kiilere bu dili
olabildiince hzl, ayrntl ve kolay bir ekilde retmektir.
Bu kitabn hedef kitlesi, programlamay hi bilmeyen kiilerdir. Bu sebeple, bu kitapta ders
konularn olabildiince ayrntl ve basitletirilmi bir ekilde ele almaya altk. Ancak
eer gemiten gelen bir programlama deneyiminiz varsa, stelik programlamaya ilikin
kavramlara da ainaysanz, bu kitab skc bulabilirsiniz. yle bir durumda, bu belgelerin
yerine, Python programlama diline ait resmi klavuzun, yine istihza.com projesinin bir rn
olan Trke evirisini takip etmeyi tercih edebilirsiniz. Fakat reneceiniz ilk programlama
dili Python ise, resmi klavuzu anlamak size epey zor gelecektir.

1.1 Bu Kitab Nereden ndirebilirim?

Bu kitab nternet zerinden takip edebileceiniz gibi, depodan PDF veya EPUB biimlerinde
bilgisayarnza da indirebilirsiniz. Ancak bu kitabn henz yazlma aamasnda olduunu ve
ieriinin sk sk gncellendiini aklnzdan karmayn. Dolaysyla, bilgisayarnza indirdiiniz
PDF ve EPUB belgeleri gncelliini abucak yitirecektir. O yzden, eer mmknse, kitab
evrim ii kaynandan takip etmeniz veya bu mmkn deilse, PDF/EPUB belgelerini sk sk
yeniden indirmeniz daha mantkl olacaktr.

1.2 Bu Kitaptan Nasl Yararlanabilirim?

Elinizdeki kitap, epey uzun ve ayrntl makalelerden oluuyor. Dolaysyla bu kitab elinize
alp bir roman gibi okumaya alrsanz, sklp renme azminizi kaybedebilirsiniz. Bu kitab
sklmadan ve bkknla dmeden takip edebilmeniz iin size birka neride bulunalm.
Programlama dillerini, sanki tarih, corafya veya felsefe alyormusunuz gibi, kitaba
gmlp harl harl okuyarak renemezsiniz. Programlama dillerini renebilmek iin sizin
de etkin bir ekilde renme srecine katlmanz gerekir. Yani bu kitaptaki makalelere kafanz
gmmek yerine, bol bol rnek kod yazmaya alrsanz, rendiiniz eyler zihninizde daha
kolay yer edecektir. Birincisi bu.
kincisi, kimse sizden bu kitaptaki her ayrnty ezberlemenizi beklemiyor. Maharet, bir
konuya ilikin btn ayrntlar aklda tutabilmekte deildir. yi bir programc, bir konuya dair
nasl aratrma yapacan ve kaynaklardan nasl faydalanacan bilir. Bir yazlm gelitirici

1
Python 3 iin Trke Klavuz, Srm 3

aday olarak sizin de renmeniz gereken ey, grdnz btn konular en ince ayrntsna
kadar ezberlemeye kalkmaktan ziyade, o konuya ilikin ilk aamada kir sahibi olmaya
almaktr. Pythonda ilerledike, zaten belli alanlara ilgi duyacak, kendinizi o alanlarda
gelitirmeye alacaksnz. Elbette ok uratnz konulara ilikin ayrntlar da daha kolay
aklnzda kalacaktr. stelik bir projeye ilikin gerekliliklerin sizi ynlendirmesiyle, belli
konularda daha ayrntl aratrma yapma frsat da bulacaksnz.
ncs, bir konuyu alrken yeterince anlayamadnz hissederseniz, ltfen dudanz
bzp bir duvar kesine kvrlarak kendi kendinizi ylgnla drmeyin. Eer bir konuyu
anlamadysanz, okuyup gein. Okuyup gemek iinize sinmiyorsa, aada belirttiimiz
ekilde yardm isteyin.

1.3 Nereden Yardm Alabilirim?

Bu kitapta Python programlama diline ilikin konular olabildiince temiz ve anlalr bir dille
anlatmaya altk. Ancak yine de baz konular zihninizde tam olarak yer etmeyebilir. stelik
kimi zaman, bir konuyu daha iyi anlayabilmek ya da bir sorunun stesinden gelebilmek iin
bilen birilerinin yardmna da ihtiya duyabilirsiniz. te byle durumlarda istihza.comun
forum alanna urayarak baka Python programclarndan yardm isteyebilirsiniz.
Forum alan hem bilgi edinmek, hem de bildiklerinizi paylamak iin olduka elverili bir
ortamdr. Foruma ilk giriiniz muhtemelen yardm istemek iin olacaktr. Ama ilerleyen
zamanlarda Python bilginiz arttka bir de bakacaksnz ki yardm ararken yardm eder
duruma gelmisiniz. te forum; kendinizdeki deiimi grmek, bilgi dzeyinizdeki art takip
etmek ve hatta yeni eyler renmek iin bulunmaz bir frsattr.

1.4 Projeye Nasl Yardmc Olabilirim?

Bu kitabn amac, kitab okuyanlara Python programlama dilini doru ve ayrntl bir ekilde
retmek olduu kadar, bu programlama dilini retirken dzgn ve anlalr bir Trke de
kullanmaktr. Bu bakmdan, kitapta bulabileceiniz kod hatalaryla birlikte, kitaptaki anlatm,
yazm ve noktalama hatalarn da yazara iletirseniz, istihza.com projesine nemli bir katkda
bulunmu olursunuz.
Ayrca bkz.:
Projeye bu ekilde katkda bulunanlarn listesini Katkda Bulunanlar balkl sayfada
grebilirsiniz.
Bunun dnda, projeye destek olmann bir baka yolu, forum alannda sorulan sorular
cevaplamaya almaktr. Bu ekilde hem projeye destek olmu, hem bakalarna yardm
etmi, hem de kendi bilginizi artrm olursunuz.

1.5 Kullanm Koullar

Bu kitaptaki bilgiler, istihza.comun teki ksmlar gibi, Creative Commons lisans altndadr.
Bu lisansa gre, bu kitaptaki btn bilgilerden herkes cretsiz olarak yararlanabilir. Eer
isterseniz burada grdnz belgelerin ktsn alabilir, tandnz veya tanmadnz
herkesle gnl rahatlyla paylaabilirsiniz. Ancak bu belgeleri baka bir yerde

2 Blm 1. Bu Kitap Hakknda


Python 3 iin Trke Klavuz, Srm 3

kullanacaksanz, istihza.com adresini kaynak olarak gstermeli ve bu belgeleri kesinlikle


satmamalsnz. Arzu ederseniz belgeleri oaltp cretsiz olarak databilirsiniz.

1.5. Kullanm Koullar 3


BLM 2

Python Hakknda

Eer yaamnzn bir dneminde herhangi bir programlama dili ile az veya ok ilgilendiyseniz,
Python adn duymu olabilirsiniz. nceden bir programlama dili deneyiminiz hi olmamsa
dahi, Python adnn bir yerlerden kulanza alnm olma ihtimali bir hayli yksek. Bu
satrlar okuyor olduunuza gre, Python adn en az bir kez duymu olduunuzu ve bu eye
kar iinizde hi deilse bir merak uyandn varsayabiliriz.
Peki, en kt ihtimalle kulak dolgunluunuz olduunu varsaydmz bu ey hakknda acaba
neler biliyorsunuz?
te biz bu ilk blmde, fazla teknik ayrntya kamadan, Python hakknda ksa ksa bilgiler
vererek Pythonn ne olduunu ve bununla neler yapabileceinizi anlatmaya alacaz.

2.1 Python Nedir?

Tahmin edebileceiniz gibi Python (C, C++, Perl, Ruby ve benzerleri gibi) bir programlama
dilidir ve tpk teki programlama dilleri gibi, nnzde duran kara kutuya, yani bilgisayara
hkmetmenizi salar.
Bu programlama dili Guido Van Rossum adl Hollandal bir programc tarafndan 90l yllarn
banda gelitirilmeye balanmtr. ou insan, isminin Python olmasna aldanarak, bu
programlama dilinin, adn piton ylanndan aldn dnr. Ancak zannedildiinin aksine
bu programlama dilinin ad piton ylanndan gelmez. Guido Van Rossum bu programlama
dilini, The Monty Python adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl
gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa da, Python
programlama dilinin pek ok yerde bir ylan gr ile temsil edilmesi neredeyse bir gelenek
halini almtr.
Dediimiz gibi, Python bir programlama dilidir. stelik pek ok dile kyasla renmesi
kolay bir programlama dilidir. Bu yzden, eer daha nce hi programlama deneyiminiz
olmamsa, programlama maceranza Pythonla balamay tercih edebilirsiniz.

2.2 Neden Programlama renmek steyeyim?

Gnlk yaamnza yle bir bakn. Gerek i yerinizde olsun, gerek evde bilgisayar banda
olsun, belli ileri tekdze bir ekilde tekrar ettiinizi greceksiniz. Mesela srekli olarak yazl
belgelerle uramanz gerektiren bir ite alyor olabilirsiniz. Belki de her gn onlarca
belgeyi ap bu belgelerde birtakm bilgiler aryor, bu bilgileri dzeltiyor, yeniliyor veya

4
Python 3 iin Trke Klavuz, Srm 3

siliyorsunuzdur. Bu ilemlerin ne kadar vakit alc ve skc olduunu dnn. Eer bir
programlama dili biliyor olsaydnz, btn bu ilemleri sizin yerinize bu programlama dili
hallediyor olabilirdi.
te Python programlama dili byle bir durumda devreye girer. Her gn saatler boyunca
uratnz ilerinizi, yalnzca birka satr Python kodu yardmyla birka saniye iinde
tamamlayabilirsiniz.
Ya da yle bir durum dnn: altnz i yerinde PDF belgeleriyle bolca har neir
oluyor olabilirsiniz. Belki de yzlerce sayfalk kaeli ve imzal belgeyi PDF haline getirmeniz
gerekiyordur. stelik sizden bu belgeleri mmkn olduunca tek para halinde PDFlemeniz
isteniyor olabilir. Ama o yzlerce sayfay taraycdan geirirken iin tam ortasnda bir aksilik
oluyor, makine arzalanyor ve belki de ister istemez belgeniz blnyordur.
te Python programlama dili byle bir durumda da devreye girer. Eer Python programlama
dilini renirseniz, nternette saatlerce cretsiz PDF birletirme program aramak veya
profesyonel yazlmlara onlarca dolar para vermek yerine, belgelerinizi birletirip iinizi
grecek program kendiniz yazabilirsiniz.
Elbette Pythonla yapabilecekleriniz yukarda verdiimiz basit rneklerle snrl deildir.
Python kullanarak masast programlama, oyun programlama, tanabilir cihaz
programlama, web programlama ve a programlama gibi pek ok alanda almalar
yrtebilirsiniz.

2.3 Neden Python?

Python programlarnn en byk zelliklerinden birisi, C ve C++ gibi dillerin aksine,


derlenmeye gerek olmadan altrlabilmeleridir. Pythonda derleme ilemi ortadan
kaldrld iin, bu dille olduka hzl bir ekilde program gelitirilebilir.
Ayrca Python programlama dilinin basit ve temiz sz dizimi, onu pek ok programc
tarafndan tercih edilen bir dil haline getirmitir. Pythonn sz diziminin temiz ve basit olmas
sayesinde hem program yazmak, hem de bakas tarafndan yazlm bir program okumak,
baka dillere kyasla ok kolaydr.
Pythonn yukarda saylan zellikleri sayesinde dnya apnda n sahibi byk kurulular
(Google, YouTube ve Yahoo! gibi) bnyelerinde her zaman Python programclarna ihtiya
duyuyor. Mesela pek ok byk irketin Python bilen programclara i imkan saladn,
Pythonn ba gelitiricisi Guido Van Rossumun 2005 ile 2012 yllar arasnda Googleda
altn, 2012 ylnn sonlarna doru ise Dropbox irketine getiini sylersek, bu
programlama dilinin nemi ve geerlilii herhalde daha belirgin bir ekilde ortaya kacaktr.
Python programlama dili ve bu dili hakkyla bilenler sadece uluslararas irketlerin ilgisini
ekmekle kalmyor. Python son zamanlarda Trkiyedeki kurum ve kurulularn da dikkatini
ekmeye balad. Bu dil artk yava yava Trkiyedeki niversitelerin mfredatnda da
kendine yer buluyor.
Szn z, pek ok farkl sebepten, baka bir programlama dilini deil de, Python
programlama dilini renmek istiyor olabilirsiniz.

2.3. Neden Python? 5


Python 3 iin Trke Klavuz, Srm 3

2.4 Python Nasl Telaffuz Edilir?

Python programlama dili zerine bu kadar sz syledik. Peki yabanc bir kelime olan python
nasl telaffuz edeceimizi biliyor muyuz?
Gelitiricisi Hollandal olsa da python ngilizce bir kelimedir. Dolaysyla bu kelimenin
telaffuzunda ngilizcenin kurallar geerli. Ancak bu kelimeyi hakkyla telaffuz etmek, ana dili
Trke olanlar iin pek kolay deil. nk bu kelime iinde, Trkede yer almayan ve telaffuzu
peltek syi andran [th] sesi var. ngilizce bilenler bu sesi think (dnmek) kelimesinden
hatrlayacaklardr. Ana dili Trke olanlar think kelimesini genellikle [tink] eklinde telaffuz
eder. Dolaysyla python kelimesini de [paytn] eklinde telaffuz edebilirsiniz.
Python kelimesini tamamen Trkeletirerek [piton] eklinde telaffuz etmeyi yeleyenler de
var. Elbette siz de dilinizin dnd bir telaffuzu tercih etmekte zgrsnz.
Bu arada, eer python kelimesinin ngilizce telaffuzunu dinlemek istiyorsanz howjsay.com
adresini ziyaret edebilir, Guido Van Rossumun bu kelimeyi nasl telaffuz ettiini merak
ediyorsanz da http://goo.gl/bx9iJu adresindeki tantm videosunu izleyebilirsiniz.

2.5 Platform Destei

Python programlama dili pek ok farkl iletim sistemi ve platform zerinde alabilir.
GNU/Linux, Windows, Mac OS X, AS/400, BeOS, MorphOS, MS-DOS, OS/2, OS/390, z/OS,
RiscOS, S60, Solaris, VMS, Windows CE, HP-UX, iOS ve Android gibi, belki adn dahi
duymadnz pek ok ortamda Python uygulamalar gelitirebilirsiniz. Ayrca herhangi bir
ortamda yazdnz bir Python program, zerinde hibir deiiklik yaplmadan veya ufak
deiikliklerle baka ortamlarda da altrlabilir.
Biz bu belgelerde Python programlama dilini GNU/Linux ve Microsoft Windows iletim sistemi
zerinden anlatacaz. Ancak sk skya bel balayacamz zel bir GNU/Linux datm
veya Windows srm yok. Bu yzden, hangi GNU/Linux datmn veya hangi Windows
srmn kullanyor olursanz olun, buradaki bilgiler yardmyla Python programlama dilini
renebilir, rendiklerinizi kendi iletim sisteminize uyarlayabilirsiniz.

Not: Bu satrlarn yazarnn, Ubuntu, CentOs, Windows 7 ve Windows 10 kurulu


bilgisayarlara eriimi olduu iin, bu kitaptaki ekran grntleri genellikle bu iletim
sistemlerinden alnm olacaktr.

2.6 Farkl Python Srmleri

Eer daha nce Python programlama dili ile ilgili aratrma yaptysanz, u anda piyasada iki
farkl Python serisinin olduu dikkatinizi ekmi olmal. 20.04.2016 tarihi itibariyle piyasada
olan en yeni Python srmleri Python 2.7.11 ve Python 3.5.1dir.
Eer bir Python srm 2 says ile balyorsa (mesela 2.7.11), o srm Python 2.x serisine
aittir. Yok eer bir Python srm 3 says ile balyorsa (mesela 3.5.1), o srm Python 3.x
serisine aittir.
Peki neden piyasada iki farkl Python srm var ve bu bizim iin ne anlama geliyor?

6 Blm 2. Python Hakknda


Python 3 iin Trke Klavuz, Srm 3

Python programlama dili 1990 ylndan bu yana gelitirilen bir dil. Bu sre iinde pek ok
Python program yazld ve insanlarn kullanmna sunuldu. u anda piyasada Pythonn 2.x
serisinden bir srmle yazlm pek ok program bulunuyor. 3.x serisi ise ancak son yllarda
yaygnlk kazanmaya balad.

Not: Biz bu kitapta kolaylk olsun diye Pythonn 3.x serisini Python3; 2.x serisini ise Python2
olarak adlandracaz.

Python3, Python2ye gre hem ok daha gldr, hem de Python2nin hatalarndan


arndrlmtr. Python3teki byk deiikliklerden tr, Python2 ile yazlm bir program
Python3 altnda almayacaktr. Ayn durum bunun tersi iin de geerlidir. Yani Python3
kullanarak yazdnz bir program Python2 altnda almaz.
Dediimiz gibi, piyasada Python2 ile yazlm ok sayda program var. te bu sebeple Python
gelitiricileri uzun bir sre daha Python2yi gelitirmeye devam edecek. Elbette gelitiriciler
bir yandan da Python3 zerinde almay ve bu yeni seriyi gelitirmeyi srdrecek.
Farkl Python serilerinin var olmasndan tr, Python ile program yazarken hangi seriye
ait srmlerden birini kullandnz bilmeniz, yazacanz programn kaderi asndan byk
nem tar.

2.7 Hangi Seriyi renmeliyim?

Dediimiz gibi, u anda piyasada iki farkl Python serisi var: Python3 ve Python2. Peki acaba
hangi seriye ait bir srm renmelisiniz?
[Ksa cevap]
Python3 renmelisiniz.
[Uzun cevap]
Eer Python programlama diline yeni balyorsanz Python3 renmeniz daha doru
olacaktr. Ama eer Python programlama dilini belirli bir proje zerinde almak
zere reniyorsanz, hangi srm renmeniz gerektii, projede kullanacanz yardmc
modllerin durumuna baldr. Zira u anda piyasada bulunan btn Python
modlleri/programlar henz Python3e aktarlm deil.
Eer projenizde kullanmay planladnz yardmc modller halihazrda Python3e
aktarlmsa Python3 renebilirsiniz. Ancak eer bu modllerin henz Python3 srm
kmamsa sizin de Python2 ile devam etmeniz daha uygun olabilir. Ama her halkarda
Python3n bu dilin gelecei olduunu ve gnn birinde Python2nin tamamen tedavlden
kalkacan da aklnzn bir kesinde bulundurun.

2.7. Hangi Seriyi renmeliyim? 7


BLM 3

Python Nasl Kurulur?

Python ile program yazabilmemiz iin bu programlama dilinin bilgisayarmzda kurulu olmas
gerekiyor. Bu programlama dilini kurmanzn gerekip gerekmedii, kullandnz iletim
sistemine baldr. Biz burada hem GNU/Linux hem de Windows kullanclarnn durumunu
srasyla ve ayr ayr inceleyeceiz. Dilerseniz ncelikle GNU/Linux kullanclarnn durumuna
bakalm:

Not: Bu kitap boyunca baz konularn GNU/Linux ve Windows kullanclar iin ayr ayr
anlatldn greceksiniz. Ancak konular bu ekilde ayrlm da olsa, ben size her ikisini
de okumanz tavsiye ederim. nk bu blmlerde her iki kullanc grubunun da ilgisini
ekebilecek bilgilere rastlayacaksnz. Ayrca bu blmler farkl kullanc gruplarna hitap
ediyor olsa da, aslnda bu blmlerin birbirini tamamlayc nitelikte olduunu greceksiniz.

3.1 GNU/Linux Kullanclar

GNU/Linux datmlarna Python programlama dilini kurarken baz noktalar gz nnde


bulundurmamz gerekiyor. te bu blmde bu nemli noktalarn neler olduunu
inceleyeceiz.

3.1.1 Kurulu Python Srm

Hemen hemen btn GNU/Linux datmlarnda Python programlama dili kurulu olarak gelir.
rnein Ubuntuda Python zaten kuruludur.
Ancak burada yle bir durum var:
Daha nce de belirttiimiz gibi, u anda piyasada iki farkl Python serisi bulunuyor. Bunlardan
birinin Pythonn 2.x serisi, tekinin ise 3.x serisi olduunu biliyorsunuz.
Sisteminizde kurulu olan Python srmn denetlemek iin komut satrnda ncelikle u
komutu vermeyi deneyin (byk V ile):
python -V

Eer bu komuttan Python 2.x.y eklinde bir kt alyorsanz, yani x ve yden nceki ksm 2 ile
balyorsa sisteminizde Python2 kuruludur.
Ancak python -V komutundan Python 2.x.y eklinde bir kt almanz sisteminizde sadece
Python2nin kurulu olduunu gstermez. Sisteminizde Python2 ile birlikte Python3 de

8
Python 3 iin Trke Klavuz, Srm 3

halihazrda kurulu olabilir. rnein Ubuntu GNU/Linuxun 12.10 srmnden itibaren hem
Python2, hem de Python3 sistemde kurulu vaziyettedir.
Kullandnz GNU/Linux datmnda durumun ne olduunu denetlemek iin yukardaki
komutu bir de python3 -V eklinde altrmay deneyebilirsiniz. Eer bu komut size bir hata
mesaj yerine bir srm numaras veriyorsa sisteminizde Python3 de kuruludur.
Sisteminizdeki Python srmlerine ilikin daha kesin bir rapor iin ise u komutu
kullanabilirsiniz:
ls -g {,/usr{,/local}}/bin | grep python

Buradan aldnz kty inceleyerek de sisteminizde birden fazla Python srmnn kurulu
olup olmadn grebilirsiniz. [Bununla ilgili bir tartma iin bkz. http://goo.gl/RnRRc]
Ayrca kullandnz GNU/Linux datmnda whereis python gibi bir komut vererek de
sistemde kurulu Python srmleri hakknda bilgi edinebilirsiniz.
Eer sisteminizde Python3 kuruluysa ve siz de kurulu olan Python3 srmnden
memnunsanz herhangi bir ey yapmanza gerek yok. Farkl bir Python srm kurmaya
almadan yolunuza devam edebilirsiniz.

3.1.2 Paket Deposundan Kurulum

Sistemlerinde ntanml olarak herhangi bir Python3 srm kurulu olmayan veya
sistemlerinde kurulu ntanml Python3 srmnden memnun olmayan GNU/Linux
kullanclarnn, Python3 elde etmek iin tercih edebilecei iki yol var: Birincisi ve benim
size nereceim yol, ncelikle kullandnz datmn paket yneticisini kontrol etmenizdir.
Python3 sisteminizde kurulu olmasa bile, datmnzn depolarnda bu srm paketlenmi
halde duruyor olabilir. O yzden sisteminize uygun bir ekilde paket yneticinizi ap
orada python kelimesini kullanarak bir arama yapmanz neririm. rnein Ubuntu
GNU/Linux datmnn paket depolarnda Python3 var. Dolaysyla Ubuntu kullanclar, eer
sistemlerinde zaten kurulu deilse (ki muhtemelen kuruludur), bu paketi Ubuntu Yazlm
Merkezi araclyla veya dorudan u komutla kurabilir:
sudo apt-get install python3

Bu komut, Python3 btn bamllklar ile beraber bilgisayarnza kuracaktr.

3.1.3 Kaynaktan Kurulum

Peki ya kullandnz datmn depolarnda Python3 yoksa veya depodaki Python3 srm
eskiyse ve siz daha yeni bir Python3 srm kullanmak istiyorsanz ne yapacaksnz?
Eer datmnzn depolarnda Python3 paketini bulamazsanz veya depodaki srm sizi
tatmin etmiyorsa, Python3 kaynaktan derlemeniz gerekecektir. Python3 kaynaktan
derlerken iki seeneiniz var: Python3 root haklar ile kurmak veya Python3 yetkisiz
kullanc olarak kurmak. Normal artlar altnda eer kullandnz sistemde root haklarna
sahipseniz Python3 yetkili kullanc olarak kurmanz tavsiye ederim.

3.1. GNU/Linux Kullanclar 9


Python 3 iin Trke Klavuz, Srm 3

root Haklar le Kurulum

Python kurmadan nce sistemimizde bulunmas gereken baz programlar var. Aslnda bu
programlar olmadan da Python kurulabilir, ancak eer bu programlar kurmazsanz Pythonn
baz zelliklerinden yararlanamazsnz. Bu programlar unlardr:
1. tcl-dev
2. tk-dev
3. zlib1g-dev
4. ncurses-dev
5. libreadline-dev
6. libdb-dev
7. libgdbm-dev
8. libzip-dev
9. libssl-dev
10. libsqlite3-dev
11. libbz2-dev
12. liblzma-dev
Bu programlar, kullandnz GNU/Linux datmnn paket yneticisi araclyla
kurabilirsiniz. Yalnz paket adlarnn ve gerekli paket saysnn datmlar arasnda farkllk
gsterebileceini unutmayn. Yukardaki liste Ubuntu iin geerlidir. Mesela yukarda tcl-dev
olarak verdiimiz paket ad baka bir datmda sadece tcl olarak geiyor ya da yukardaki
paketlerin bazlar kullandnz datmda halihazrda kurulu olduu iin sizin daha az
bamllk kurmanz gerekiyor olabilir.
Ubuntuda yukardaki paketlerin hepsini u komutla kurabilirsiniz:
sudo apt-get install tcl-dev tk-dev
zlib1g-dev ncurses-dev libreadline-dev
libdb-dev libgdbm-dev libzip-dev libssl-dev
libsqlite3-dev libbz2-dev liblzma-dev

Not: Farkl GNU/Linux datmlarnda, Python3 kaynaktan derleme ileminden nce


halihazrda kurulu olmas gereken paketlerin listesi iin http://goo.gl/zfLpX adresindeki
tabloyu inceleyebilirsiniz.

Yukardaki programlar kurduktan sonra https://www.python.org/ftp/python/3.5.1 adresine


gidiyoruz. Bu adreste, zerinde Python-3.5.1.tar.xz yazan balantya tklayarak sktrlm
kurulum dosyasn bilgisayarmza indiriyoruz.
Daha sonra bu sktrlm dosyay ayoruz. Alan klasrn iine girip, orada ilk olarak u
komutu veriyoruz:
./configure

Bu komut, Python programlama dilinin sisteminize kurulabilmesi iin gereken hazrlk


aamalarn gerekletirir. Bu betiin temel olarak yapt i, sisteminizin Python
programlama dilinin kurulmasna uygun olup olmadn, derleme ilemi iin gereken

10 Blm 3. Python Nasl Kurulur?


Python 3 iin Trke Klavuz, Srm 3

yazlmlarn sisteminizde kurulu olup olmadn denetlemektir. Bu betik ayrca, bir sonraki
admda gerekletireceimiz ina ileminin nasl yryeceini tarif eden Makele adl bir
dosya da oluturur.
Bu arada bu komutun bandaki ./ iareti, o anda iinde bulunduunuz dizinde yer alan
congure adl bir betii altrmanz salyor. Eer yalnzca configure komutu verirseniz,
iletim sistemi bu betii PATH dizinleri iinde arayacak ve bulamayaca iin de hata
verecektir.
./configure komutu hatasz olarak tamamlandktan sonra ikinci olarak u komutu veriyoruz:
make

Burada aslnda ./configure komutu ile oluan Makele adl dosyay make adl bir program
araclyla altrm oluyoruz. make bir sistem komutudur. Bu komutu yukardaki gibi
parametresiz olarak altrdmzda make komutu, o anda iinde bulunduumuz dizinde
bir Makele dosyas arar ve eer byle bir dosya varsa onu altrr. Eer bir nceki
admda altrdmz ./configure komutu baarsz olduysa, dizinde bir Makele dosyas
olumayaca iin yukardaki make komutu da almayacaktr. O yzden derleme ilemi
srasnda verdiimiz komutlarn ktlarn takip edip, bir sonraki aamaya gemeden nce
komutun dzgn sonlanp sonlanmadndan emin olmamz gerekiyor.
make komutunun yapt i, Python programlama dilinin sisteminize kurulmas esnasnda
sistemin eitli yerlerine kopyalanacak olan dosyalar ina edip oluturmaktr. Bu komutun
tamamlanmas, kullandnz bilgisayarn kapasitesine bal olarak biraz uzun srebilir.
make komutu tamamlandktan sonra, komut ktsnn son satrlarna doru yle bir uyar
mesaj grebilirsiniz:
Python build finished, but the necessary bits
to build these modules were not found: [burada
eksik olan modl veya modllerin adlar sralanr]

Burada Python, sistemimizde baz paketlerin eksik olduu konusunda bizi uyaryor. Uyar
mesajnda bir veya daha fazla paketin eksik olduunu grebilirsiniz. Eer yleyse, eksik
olduu bildirilen btn paketleri kurmamz gerekiyor.
Gerekli paketi ya da paketleri kurduktan sonra make komutunu tekrar altryoruz. Endie
etmeyin, make komutunu ikinci kez verdiimizde komutun tamamlanmas birincisi kadar uzun
srmez. Eer bu komutu ikinci kez altrdnzda yukardaki uyar mesaj kaybolduysa u
komutla yolunuza devam edebilirsiniz:
sudo make altinstall

Daha nce kaynaktan program derlemi olan GNU/Linux kullanclarnn eli, make
komutundan sonra make install komutunu vermeye gitmi olabilir. Ama burada bizim make
install yerine make altinstall komutunu kullandmza dikkat edin. make altinstall
komutu, Python kurulurken klasr ve dosyalara srm numarasnn da eklenmesini salar.
Bylece yeni kurduunuz Python, sistemdeki eski Python3 srmn silip zerine yazmam
olur ve iki farkl srm yan yana varolabilir. Eer make altinstall yerine make install
komutunu verirseniz sisteminizde zaten varolan eski bir Python3 srmne ait dosya ve
dizinlerin zerine yazp silerek o srm kullanlamaz hale getirebilirsiniz. Bu da sistemde
beklenmedik problemlerin ortaya kmasna yol aabilir. Bu nemli ayrnty kesinlikle gzden
karmamalsnz.
Ayrca bkz.:

3.1. GNU/Linux Kullanclar 11


Python 3 iin Trke Klavuz, Srm 3

Python3n kaynaktan kurulumu ile ilgili bir tartma iin bkz.


http://www.istihza.com/forum/viewtopic.php?f=50&t=544
Derleme aamalarnn hibirinde herhangi bir hata mesaj almadysanz kurulum baaryla
gereklemi ve sisteminize Python programlama dilinin 3.x srm kurulmu demektir.

Yetkisiz Kullanc Olarak Kurulum

Elbette sudo make altinstall komutunu verip Python kurabilmek iin root haklarna sahip
olmanz gerekiyor. Ama eer kullandnz sistemde bu haklara sahip deilseniz Python bu
ekilde kuramazsnz. Kstl haklara sahip olduunuz bir sistemde Python ancak kendi ev
dizininize ($HOME) kurabilirsiniz.
Eer Python yetkisiz kullanc olarak kuracaksanz, ncelikle yukarda bahsettiimiz Python
bamllklarnn sisteminizde kurulu olup olmadn kontrol etmeniz lazm. Kullandnz
sistemde herhangi bir Python srm halihazrda kuruluysa, bu bamllklar da muhtemelen
zaten kuruludur. Ama deilse, bunlar kurmas iin ya sistem yneticisine ricada
bulunacaksnz, ya da bu bamllklar da tek tek kendi ev dizininize kuracaksnz. Eer sistem
yneticisini bu bamllklar kurmaya ikna edemezseniz, internet zerinden bulabileceiniz
bilgiler yardmyla bu bamllklar tek tek elle kendiniz kurabilirsiniz. Ancak bu ilemin epey
zaman alacan ve sre srasnda pek ok baka bamllkla da karlacanz syleyebilirim.
O yzden ne yapp edip sistem yneticisini bamllklar kurmaya ikna etmenizi tavsiye
ederim... Tabii sistem yneticisini bu bamllklar kurmaya ikna edebilirseniz, istediiniz
Python srmn de kurmaya ikna edebileceinizi dnebiliriz! Ama biz burada sizin
Python kendinizin kuracan varsayarak yolumuza devam edelim.
Python yetkisiz olarak kurmak, root haklaryla kurmaya ok benzer. Aralarnda yalnzca
bir-iki ufak fark vardr. Mesela Python yetkisiz kullanc olarak kurarken, ./configure
komutunu u ekilde vermeniz gerekiyor:
./configure --prefix=$HOME/python

Python root haklaryla kurduunuzda Python /usr dizini altna kurulacaktr. Ancak siz
yetkisiz kullanc olduunuz iin /usr dizinine herhangi bir ey kuramazsnz. te bu yzden,
congure betiine verdiimiz prex parametresi yardmyla Python, yazma yetkimiz olan
bir dizine kuruyoruz. Mesela yukardaki komut Pythonn /usr dizinine deil, ev dizininiz iinde
python adl bir klasre kurulmasn salayacaktr. Elbette siz python yerine farkl bir dizin
ad da belirleyebilirsiniz. Burada nemli olan nokta, prex parametresine vereceiniz dizin
adnn, sizin yazmaya yetkili olduunuz bir dizin olmasdr.
Bu komutu altrdktan sonra make komutunu normal bir ekilde veriyoruz. Bunun ardndan
da make install (veya duruma gre make altinstall) komutuyla Python ev dizinimize
kuruyoruz. Burada make install komutunu sudosuz kullandmza dikkat edin. nk,
dediimiz gibi, siz yetkili kullanc olmadnz iin sudo komutunu kullanamazsnz.
Python bu ekilde ev dizininiz altnda bir klasre kurduunuzda Python ile ilgili btn
dosyalarn bu klasr iinde yer aldn greceksiniz. Bu klasr dikkatlice inceleyip neyin
nerede olduuna ainalk kazanmaya aln. Eer mmknse root haklar ile kurulmu bir
Python srmn inceleyerek, dosyalarn iki farkl kurulum trnde nerelere kopyalandn
karlatrn.
Bylece Python programlama dilini bilgisayarmza nasl kuracamz renmi olduk.
Ama bu noktada bir uyar yapmadan gemeyelim: Python zellikle baz GNU/Linux
datmlarnda pek ok sistem aracyla sk skya balantldr. Yani Python, kullandnz

12 Blm 3. Python Nasl Kurulur?


Python 3 iin Trke Klavuz, Srm 3

datmn belkemii durumunda olabilir. Bu yzden Python kaynaktan derlemek baz


riskler tayabilir. Eer yukarda anlatld ekilde, kaynaktan Python derleyecekseniz, kar
karya olduunuz risklerin farknda olmalsnz. Ayrca GNU/Linux zerinde kaynaktan
program derlemek konusunda tecrbeli deilseniz ve eer yukardaki aklamalar size kafa
kartrc geliyorsa, mesela Ben bu komutlar nereye yazacam? diye bir soru geiyorsa
aklnzdan, kesinlikle datmnzla birlikte gelen Python srmn kullanmalsnz. Python
srmlerini baa ba takip ettii iin, ben size Ubuntu GNU/Linuxu denemenizi nerebilirim.
Ubuntunun depolarnda Pythonn en yeni srmlerini rahatlkla bulabilirsiniz. Ubuntunun
resmi sitesine ubuntu.com adresinden, yerel Trkiye sitesine ise forum.ubuntu-tr.net
adresinden ulaabilirsiniz. Eer u anda kullandnz GNU/Linux datmndan vazgemek
istemiyorsanz, sabit diskinizden kk bir blm ayrp bu blme sadece Python
almalarnz iin Ubuntu datmn da kurmay tercih edebilirsiniz.
Yalnz kk bir uyar daha yapalm. Kaynaktan kurulum ile ilgili bu sylediklerimizden,
Pythonn GNU/Linuxa kesinlikle kaynaktan derlenerek kurulmamas gerektii anlam
kmamal. Yukardaki uyarlarn amac, kullancnn Python kaynaktan derlerken sadece
biraz daha dikkatli olmas gerektiini hatrlatmaktr. rnein bu satrlarn yazar, kulland
Ubuntu sisteminde Python3 kaynaktan derleyerek kullanmay tercih ediyor ve herhangi bir
problem yaamyor.
Bu nemli uyarlar da yaptmza gre gnl rahatlyla yolumuza devam edebiliriz.
Kurduumuz yeni Python nasl altracamz biraz sonra greceiz. Ama nce Windows
kullanclarnn Python3 nasl kuracaklarna bakalm.

3.2 Windows Kullanclar

Windows srmlerinin hibirinde Python kurulu olarak gelmez. O yzden Windows


kullanclar, Python sitesinden indirip kuracak.
Bunun iin ncelikle http://www.python.org/downloads adresine gidiyoruz.
Bu adrese gittiinizde, zerinde Download Python 3.5.1 ve Download 2.7.11 yazan, yan yana
iki dme greceksiniz. Daha nce de sylediimiz gibi, eer bir Python srm numaras 2
ile balyorsa o srm 2.x serisine, yok eer 3 ile balyorsa 3.x serisine aittir. Dolaysyla ilk
dme Python3 srmn, ikinci dme ise Python2 srmn ierir.
Biz bu kitapta Pythonn 3.x serisini anlatacamz iin (yeni Python srmleri ktnda
o dmeler zerinde yazan srm numaralar deiecek de olsa), 3 ile balayan srm
numarasn ieren dmeye tklamaya zen gsteriyoruz. Bu dmeye tkladnzda
bilgisayarnza .exe uzantl kurulum dosyas inecek. Bu dosyaya ift tklayarak kurulum
programn balatabilirsiniz.

Not: Eer indireceiniz Python srmnn mimarisini ve srmn kendiniz


semek isterseniz https://www.python.org/ftp/python/3.5.1 adresinden kendinize uygun olan
srm bulup indirebilirsiniz.

Kurulum dosyasna ift tkladnzda karnza ilk gelen ekranda, pencerenin alt tarafnda u
kutucuklar greceksiniz:
1. Install launcher for all users (recommended)
2. Add Python 3.5 to PATH

3.2. Windows Kullanclar 13


Python 3 iin Trke Klavuz, Srm 3

Burada ilk kutucuk zaten seilidir. Bunu bu ekilde brakabilirsiniz. kinci kutucuk ise
Python yola eklememizi, bylece yalnzca python komutu vererek Python balatabilmemizi
salayacak. O yzden oradaki ikinci kutucuu da iaretliyoruz.
Ayn pencerenin st tarafnda ise u seenekleri greceksiniz:
1. -> Install Now
2. -> Customize Installation
Burada Install Now yazan ksma tklayarak kurulumu balatyoruz.
Eer Pythonn bilgisayarda nereye kurulacan ve baka birtakm kurulum zelliklerini
deitirmek istiyorsanz Customize Installation yazl ksma tklayabilirsiniz. Ben bu kitapta
sizin Install Now yazan ksma tklayarak kurulum yaptnz varsayacam.

Not: Pythonn resmi sitesinde dolarken kurulum dosyalar arasnda, web-based installer
(web tabanl kurulum betii) adl bir kurulum dosyas grebilirsiniz. Bu kurulum dosyas,
Pythonn almas iin gereken dosyalar kurulum esnasnda internetten indirip kuran,
1MBdan kk bir kurulum program ierir. Dolaysyla eer kurulumu bu dosyadan
yapacaksanz, kesintisiz bir internet balantsna ihtiyacnz olacak.

Uyar: Eer Windowsta Python kurmaya alrken hata alyorsanz, muhtemelen iletim
sisteminiz gncel deildir. rnein Windows 7de Python kurabilmeniz iin, SP1 (Service
Pack 1) kurulu olmaldr. Windows gncellemelerini kurduktan sonra Python kurmay
tekrar deneyin.

3.3 Python Kurulum ve alma Dizini

Python programlama dilini, kullandmz iletim sistemine nasl kurabileceimizi bilmek


kadar nemli bir konu da Python hangi dizine kurduumuzu bilmektir. Zira programclk
maceramz boyunca karlaacamz baz sorunlar, Pythonn kurulu olduu dizine gitmemizi
gerektirecek, stelik kendi yazdmz baz programlarda da Pythonn kurulu olduu dizinde
eitli ilemler yapmak ihtiyac duyacaz. Ayrca baz durumlarda, o anda alan Python
srmnn hangi konumdan altn tespit etmemiz de gerekebilir.
te bu sebeplerden, Pythonn hangi dizine kurulduunu mutlaka biliyor olmamz lazm.
Pythonn, iletim sisteminizde hangi dizine kurulduu, Python nasl kurduunuza bal
olarak farkllk gsterir.
GNU/Linux datmlarnda Python genellikle /usr/lib/python 3.5 dizininde kurulur. Ama
elbette, eer siz Python kaynaktan derlediyseniz, derleme srasnda congure betiine
verdiiniz prex parametresi yardmyla Pythonn kurulum dizinini kendiniz de belirlemi
olabilirsiniz.
Windowsta Python programlama dilini aynen bu kitapta gsterdiimiz ekilde kurduysanz,
Python %LOCALAPPDATA%\Programs\Python dizini iine kurulacaktr. Ancak eer kurulum
penceresinde Customize Installation dmesine basarak kurulumu zelletirdiyseniz
ve Install for all users seeneini iaretlediyseniz Python %PROGRAMFILES% veya
%PROGRAMFILES(x86) adl evre deikenlerinin iaret ettii dizin iine kurulacaktr.

14 Blm 3. Python Nasl Kurulur?


BLM 4

Python Nasl altrlr?

Bir nceki blmde, Python farkl platformlara nasl kuracamz btn ayrntlaryla
anlattk. Bu blmde ise kurduumuz bu Python programn hem GNU/Linuxta hem de
Windowsta nasl altracamz greceiz. ncelikle GNU/Linux kullanclarnn Python
nasl altracana bakalm.

4.1 GNU/Linux Kullanclar

Geen blmlerde grdnz gibi, Python3 GNU/Linux sistemleri zerine farkl ekillerde
kurabiliyoruz. Bu blmde, her bir kurulum tr iin Python3n nasl altrlacan ayr
ayr inceleyeceiz.

4.1.1 Kurulu Python3 Kullananlar

Eer sisteminizde zaten Python3 kurulu ise komut satrnda yalnzca u komutu vererek
Python3 balatabilirsiniz:
python

Ancak daha nce de dediimiz gibi, 20.04.2016 tarihi itibariyle pek ok GNU/Linux
datmnda ntanml olarak Python2 kuruludur. Dolaysyla python komutunu verdiinizde
alan srm muhtemelen Python2 olacaktr. Bu yzden sistemimizde ntanml olarak
hangi srmn kurulu olduuna ve python komutunun hangi srm balattna ok dikkat
etmelisiniz.
Yine daha nce de sylediimiz gibi, sisteminizde hem Python2 hem de Python3 zaten
kurulu durumda olabilir. O yzden yukardaki komutu bir de python3 eklinde vermeyi
deneyebilirsiniz.
rnein Ubuntu GNU/Linux datmnn 12.10 srmnden itibaren python komutu
Python2yi; python3 komutu ise Python3 altryor.

4.1.2 Python3 Depodan Kuranlar

Dediimiz gibi, 20.04.2016 tarihi itibariyle GNU/Linux datmlarnda ntanml Python


srm arlkl olarak Python2dir. Dolaysyla python komutu Pythonn 2.x srmlerini
altrr. Bu durumdan tr, herhangi bir akmay nlemek iin GNU/Linux datmlar
Python3 paketini farkl bir ekilde adlandrma yoluna gider. u anda piyasada bulunan

15
Python 3 iin Trke Klavuz, Srm 3

datmlarn ezici ounluu Python3 paketini python3 eklinde adlandryor. O yzden


GNU/Linux kullanclar, eer paket yneticilerini kullanarak Python kurulumu gerekletirmi
iseler, komut satrnda u komutu vererek Python3 balatabilirler:
python3

Bu komutun ardndan una benzer bir ekranla karlam olmalsnz:


istihza@ubuntu:~$ # python3 Python 3.5.1 (default, 20.04.2016, 12:24:55) [GCC 4.4.7
20120313 (Red Hat 4.4.7-3)] on linux Type help, copyright, credits or license for more
information. >>>
Eer yukardaki ekran grdyseniz Pythonla programlama yapmaya hazrsnz demektir.
Deilse, geriye dnp ilerin nerede ters gittiini bulmaya alabilirsiniz.
Bu aamada ilerin nerede ters gitmi olabileceine dair birka ipucu verelim:
1. Python3 kurulurken paket yneticinizin herhangi bir hata vermediinden, programn
sisteminize baaryla kurulduundan emin olun. Bunun iin Python3n kurulu paketler
listesinde grnp grnmediini denetleyebilirsiniz.
2. python3 komutunu doru verdiinize emin olun. Python programlama diline zellikle
yeni balayanlarn en sk yapt hatalardan biri python kelimesini yanl yazmaktr.
Python yerine yanllkla pyhton, pyton veya phyton yazm olabilirsiniz. Ayrca python3
komutunun tamamen kk harerden olutuuna dikkat edin. Python ve python
bilgisayar asndan ayn eyler deildir.
3. Kullandnz datmn Python3 paketini adlandrma politikas yukarda anlattmzdan
farkl olabilir. Yani sizin kullandnz datm, belki de Python3 paketini farkl bir ekilde
adlandrmtr. Eer durum byleyse, datmnzn yardm kaynaklarn (wiki, forum, irc,
yardm belgeleri, kullanc listeleri, vb.) kullanarak ya da istihza.com/forum adresinde
sorarak Python3n nasl altrlacan renmeyi deneyebilirsiniz.
Gelelim Python3 kaynaktan derlemi olanlarn durumuna...

4.1.3 Python3 root Olarak Derleyenler

Eer Python3 nceki blmlerde anlattmz ekilde kaynaktan root haklar ile
derlediyseniz python3 komutu almayacaktr. Bunun yerine u komutu kullanmanz
gerekecek:
python3.5

Not: Kurduunuz Python3 srmnn 3.5 olduunu varsayyorum. Eer farkl bir
Python3 srm kurduysanz, elbette balatc komut olarak o srmn adn kullanmanz
gerekecektir. Mesela: python3.0 veya python3.1. Bu arada python3.5 komutunda 35
saysnn rakamlar arasnda bir adet nokta iareti olduunu gzden karmyoruz...

Tpk paket deposundan kurulumda olduu gibi, eer yukardaki komut Python altrmanz
salamyorsa, kurulum esnasnda baz eyler ters gitmi olabilir. rnein kaynaktan
kurulumun herhangi bir aamasnda bir hata alm olabilirsiniz ve bu da Pythonn
kurulumunu engellemi olabilir.
Grdnz gibi, Python kaynaktan derleyenler Python programlama dilini altrabilmek
iin Pythonn tam srm adn belirtiyor. Dilerseniz bu ekilde almaya devam edebilirsiniz.
Bunun hibir sakncas yok. Ancak ben size kolaylk asndan, /usr/bin/ dizini altna py3

16 Blm 4. Python Nasl altrlr?


Python 3 iin Trke Klavuz, Srm 3

adnda bir sembolik ba yerletirmenizi tavsiye ederim. Bylece sadece py3 komutunu
vererek Python3 balatabilirsiniz.
Peki bunu nasl yapacaz?
Python kaynaktan derlendiinde altrlabilir dosya /usr/local/bin/ dizini iine Python 3.5
(veya kurduunuz Python3 srmne bal olarak Python3.0 ya da Python3.1 ) adyla
kopyalanr. Bu nedenle Python3 altrabilmek iin python3.5 komutunu kullanmamz
gerekir. Python3 altrabilmek iin mesela sadece py3 gibi bir komut kullanmak istiyorsak
yapacamz tek ey /usr/local/bin/ dizini iindeki python 3.5 adl dosyaya /usr/bin dizini
altndan, py3 adl bir sembolik ba oluturmak olacaktr. Bunun iin ln komutunu
kullanacaz:
ln -s /usr/local/bin/python3.5 /usr/bin/py3
Tabii bu komutu yetkili kullanc olarak vermeniz gerektiini sylememe herhalde gerek
yoktur. Bu komutu verdikten sonra artk sadece py3 komutu ile Python programlama dilini
balatabilirsiniz.

ok nemli Bir Uyar

Bir nceki admda anlattmz gibi Python3 resmi sitesinden indirip kendiniz derlediniz.
Gayet gzel. Ancak bu noktada ok nemli bir konuya dikkatinizi ekmek isterim. En batan
beri sylediimiz gibi, Python programlama dili GNU/Linux iletim sistemlerinde ok nemli
bir yere sahiptir. yle ki bu programlama dili, kullandnz datmn belkemii durumunda
olabilir.
rnein Ubuntu GNU/Linux datmnda pek ok sistem arac Python ile yazlmtr. Bu
yzden, sistemdeki ntanml Python srmnn ne olduu ve dolaysyla python komutunun
hangi Python srmn altrd ok nemlidir. nk sisteminizdeki hayati baz aralar,
python komutunun altrd Python srmne bel balam durumdadr. Dolaysyla sizin
bu python komutunun altrd Python srmne dokunmamanz gerekir.
Mesela eer kullandnz iletim sisteminde python komutu Pythonn 2.x srmlerinden
birini altryorsa sembolik balar veya baka aralar vastasyla python komutunu Pythonn
baka bir srmne balamayn. Bu ekilde btn sistemi kullanlmaz hale getirirsiniz.
Elbette eer kurulum aamasnda tarif ettiimiz gibi, Python3 make install yerine make
altinstall komutu ile kurmaya zen gsterdiyseniz, sonradan oluturduunuz ba dosyasn
silip python komutunu yine sistemdeki ntanml srme balayabilirsiniz. Bu ekilde her
ey yine eski haline dner. Ama eer Python make install komutuyla kurmanzdan tr
sistemdeki ntanml Python srmne ait dosyalar kaybettiyseniz sizin iin yaplacak fazla
bir ey yok... Sistemi tekrar eski kararl haline getirmek iin kan, ter ve gzya dkeceksiniz...
Ayn ekilde, kullandnz datmda python3 komutunun ntanml olarak belirli bir
Python srmn balatp balatmad da nemlidir. Yukarda python komutu ile ilgili
sylediklerimiz python3 ve buna benzer baka komutlar iin de aynen geerli.
rnein, Ubuntu GNU/Linux datmnda python komutu sistemde kurulu olan Python 2.x
srmn; python3 komutu ise sistemde kurulu olan Python 3.x srmn altrdndan,
biz kendi kurduumuz Python srmleri iin, sistemdeki srmlerle akmayacak isimler
setik. Mesela kendi kurduumuz Python3 srmn altrmak iin py3 gibi bir komut tercih
ettik.
yi bir test olarak, Python programlama dilini kendiniz kaynaktan derlemeden nce u
komutun ktsn iyice inceleyebilirsiniz:

4.1. GNU/Linux Kullanclar 17


Python 3 iin Trke Klavuz, Srm 3

ls -g {,/usr{,/local}}/bin | grep python

Bu komut iki farkl Python srmnn kurulu olduu sistemlerde una benzer bir kt verir
(kt krplmtr):
dh_python2
dh_python3
pdb2.7 -> ../lib/python2.7/pdb.py
pdb3.2 -> ../lib/python3.2/pdb.py
py3versions -> ../share/python3/py3versions.py
python -> python2.7
python2 -> python2.7
python2.7
python3 -> python3.2
python3.2 -> python3.2mu
python3.2mu
python3mu -> python3.2mu
pyversions -> ../share/python/pyversions.py
Yatk harerle gsterdiimiz ksmlara dikkat edin. Grdnz gibi python ve python2
komutlar bu sistemde Pythonn 2.7 srmn altryor. python3 komutu ise Pythonn 3.2
srmn... Dolaysyla yukardaki kty aldmz bir sistemde kendi kurduumuz Python
srmlerine python, python2 veya python3 gibi isimler vermekten kanmalyz.
Szn z, bir GNU/Linux kullancs olarak sistemdeki ntanml hibir Python srmn
silmemeli, ntanml srme ulaan komutlar deitirmemelisiniz. Eer mesela sisteminizde
python3 komutu halihazrda bir Python srmn altryorsa, siz yeni kurduunuz Python
srmne ulamak iin ntanml adla akmayacak baka bir komut ad kullann. Yani
rnein sisteminizde python3 komutu Pythonn 3.2 srmn altryorsa, siz yeni
kurduunuz srm altrmak iin py3 gibi bir sembolik ba oluturun. Brakn ntanml
komut (python, python3 vb.) ntanml Python srmn altrmaya devam etsin.
Asla unutmayn. Siz bir programc aday olarak, program yazacanz iletim sistemini enine
boyuna tanmakla ykmlsnz. Dolaysyla iletim sisteminizi kararsz hale getirecek
davranlar bilmeli, bu davranlardan kanmal, yanl bir ilem yaptnzda da nasl geri
dneceinizi bilmelisiniz. Hele ki bir program kaynaktan derlemeye karar vermiseniz...
Bu ciddi uyary da yaptmza gre gnl rahatlyla yolumuza devam edebiliriz.

4.1.4 Python3 Ev Dizinine Kuranlar

Eer Python3 kstl kullanc haklar ile derleyip ev dizininize kurduysanz yukardaki
komutlar Python altrmanz salamayacaktr. Python3 ev dizinine kurmu olan
kullanclar Python3 altrabilmek iin, ncelikle komut satr araclyla Python3
kurduklar dizine, oradan da o dizin altndaki bin/ klasrne ulaacak ve orada u komutu
verecek:
./python3.5
Diyelim ki Python3 $HOME/python adl dizine kurdunuz. nce u komutla
$HOME/python/bin adl dizine ulayoruz:
cd $HOME/python/bin

18 Blm 4. Python Nasl altrlr?


Python 3 iin Trke Klavuz, Srm 3

Ardndan da u komutu veriyoruz:


./python3.5

Not: Komutun bandaki ./ iaretinin ne ie yaradn artk adnz gibi biliyorsunuz...

Not: Elbette ben burada kurduunuz Python srmnn 3.5 olduunu varsaydm. Eer
farkl bir srm kurduysanz yukardaki komutu ona gre yazmanz gerekiyor.

Eer isterseniz bu ekilde almaya devam edebilirsiniz. Ancak her defasnda Pythonn
kurulu olduu dizin altna gelip orada ./python3.5 komutunu altrmak bir sre sonra
eziyete dnecektir. lerinizi kolaylatrmak iin u ilemleri takip etmelisiniz:
1. ev dizininizin altnda bulunan .prole (veya kullandnz datma gre .bash_prole ya da
.bashrc ) adl dosyay an.
2. Bu dosyann en sonuna una benzer bir satr yerletirerek Python altrmamz salayan
dosyann bulunduu dizini yola ekleyin:
export PATH=$PATH:$HOME/python/bin/

3. $HOME/python/bin/ satr Python3n altrlabilir dosyasnn hangi dizin altnda


olduunu gsteriyor. Ben burada Python3n altrlabilir dosyasnn $HOME/python/bin
dizini iinde olduunu varsaydm. O yzden de $HOME/python/bin/ gibi bir satr yazdm.
Ama eer Python3n altrlabilir dosyas sizde farkl bir dizindeyse bu satr ona gre
yazmalsnz.
4. Kendi sisteminize uygun satr dosyaya ekledikten sonra dosyay kaydedip kn. Dosyada
yaptmz deiikliin etkin hale gelebilmesi iin u komutu verin:
source .profile

Elbette eer sizin sisteminizdeki dosyann ad .bash_prole veya .bashrc ise yukardaki
komutu ona gre deitirmelisiniz.
5. Daha sonra $HOME/python/bin/python 3.5 adl dosyaya $HOME/python/bin/ dizini
altndan mesela py3 gibi bir sembolik ba verin:
ln -s $HOME/python/bin/python3.5 $HOME/python/bin/py3
6. Bilgisayarnz yeniden balatn.
7. Artk hangi konumda bulunursanz bulunun, u komutu vererek Python3 balatabilirsiniz:
py3

Burada da eer yukardaki komut Python3 altrmanz salamyorsa, baz eyleri


eksik veya yanl yapm olabilirsiniz. Yardm almak iin istihza.com/forum adresine
urayabilirsiniz.
Python3 baaryla kurup altrabildiinizi varsayarak yolumuza devam edelim.

4.1.5 GNU/Linuxta Farkl Srmleri Birlikte Kullanmak

Daha nce de dediimiz gibi, u anda piyasada iki farkl Python serisi bulunuyor: Python2 ve
Python3. ok uzun zamandan beri kullanmda olduu iin, Python2 Python3e kyasla daha

4.1. GNU/Linux Kullanclar 19


Python 3 iin Trke Klavuz, Srm 3

yaygn. Eer hem Python2 ile yazlm programlar altrmak, hem de Python3 ile gelitirme
yapmak istiyorsanz, sisteminizde hem Python2yi hem de Python3 ayn anda bulundurmay
tercih edebilirsiniz. Peki bunu nasl yapacaksnz?
En bata da sylediimiz gibi, hemen hemen btn GNU/Linux datmlarnda Python2 kurulu
olarak gelir. Dolaysyla eer sisteminize ek olarak Python3 de kurduysanz (kaynaktan
veya paket deposundan), baka herhangi bir ey yapmanza gerek yok. Yukarda anlattmz
ynergeleri takip ettiyseniz, konsolda python komutu verdiinizde Python2 alacak, python3
(veya py3) komutunu verdiinizde ise Python3 alacaktr.
Ama eer sisteminizde Python2 bile kurulu deilse, ki bu ok ok dk bir ihtimaldir,
Python2yi paket yneticiniz yardmyla sisteminize kurabilirsiniz. u anda piyasada olup da
paket deposunda Python bulundurmayan GNU/Linux datm pek azdr.
GNU/Linuxta Python nasl altracamz ve farkl Python srmlerini bir arada nasl
kullanacamz rendiimize gre, Windows kullanclarnn durumuna bakabiliriz.

4.2 Windows Kullanclar

Windows kullanclar Python3 iki ekilde balatabilir:


1. Balat > Tm Programlar > Python 3.5 > Python (Command Line) yolunu takip ederek.
2. Komut satrnda python komutunu vererek.
Eer birinci yolu tercih ederseniz, Pythonn size sunduu komut satrna dorudan ulam
olursunuz. Ancak Python komut satrna bu ekilde ulatnzda baz kstlamalarla kar
karya kalrsnz. Dorudan Pythonn komut satrna ulamak yerine nce MS-DOS komut
satrna ulap, oradan Python komut satrna ulamak zellikle ileride yapacanz almalar
asndan ok daha mantkl olacaktr. O yzden komut satrna bu ekilde ulamak yerine
ikinci seenei tercih etmenizi tavsiye ederim. Bunun iin nceki blmlerde gsterdiimiz
ekilde komut satrna ulan ve orada u komutu altrn:
python

Bu komutu verdiinizde una benzer bir ekranla karlaacaksnz:


C:\Users\istihza> python3 Python 3.5.1 (v3.5.1:c0e311e010fc, 20.04.2016, 12:24:55) [MSC
v.1600 32 bit (Intel)] on win32 Type help, copyright, credits or license for more
information. >>>
Eer bu komut yukardakine benzer bir ekran yerine bir hata mesaj verdiyse kurulum
srasnda baz admlar eksik veya yanl yapm olabilirsiniz. Yukardaki komut
almyorsa, muhtemelen kurulum srasnda Add python 3.5 to path kutucuunu
iaretlemeyi unutmusunuzdur. Eer yleyse, kurulum dosyasn tekrar altrp, ilgili adm
gerekletirmeniz veya Python kendiniz YOLa eklemeniz gerekiyor.
python komutunu baaryla altrabildiinizi varsayarak yolumuza devam edelim.

4.2.1 Windowsta Farkl Srmleri Birlikte Kullanmak

Daha nce de dediimiz gibi, u anda piyasada iki farkl Python serisi bulunuyor: Python2 ve
Python3. ok uzun zamandan beri kullanmda olduu iin, Python2 Python3e kyasla daha
yaygn. Eer hem Python2 ile yazlm programlar altrmak, hem de Python3 ile gelitirme

20 Blm 4. Python Nasl altrlr?


Python 3 iin Trke Klavuz, Srm 3

yapmak istiyorsanz, sisteminizde hem Python2yi hem de Python3 ayn anda bulundurmay
tercih edebilirsiniz. Peki bunu nasl yapacaksnz?
Windowsta bu ilemi yapmak ok kolaydr. python.org/download adresine giderek farkl
Python srmlerini bilgisayarnza indirebilir ve bunlar bilgisayarnza normal bir ekilde
kurabilirsiniz. Bu ekilde sisteminize istediiniz sayda farkl Python srm kurabilirsiniz.
Peki bu farkl srmlere nasl ulaacaksnz?
Python, bilgisayarmzdaki farkl Python srmlerini altrabilmemiz iin bize py adl zel
bir program sunar.

Not: Py program yalnzca Windowsa zgdr. GNU/Linuxta byle bir program bulunmaz.

Py programn altrmak iin, daha nce gsterdiimiz ekilde sistem komut satrna
ulayoruz ve orada u komutu veriyoruz:
py

Bu komutu verdiinizde (teorik olarak) sisteminize en son kurduunuz Python srm


almaya balayacaktr. Ancak bu her zaman byle olmayabilir. Ya da aldnz kt
beklediiniz gibi olmayabilir. O yzden bu komutu verdiinizde hangi srmn baladna
dikkat edin.
Eer sisteminizde birden fazla Python srm kurulu ise, bu betik yardmyla istediiniz
srm balatabilirsiniz. Mesela sisteminizde hem Pythonn 2.x srmlerinden biri, hem de
Pythonn 3.x srmlerinden biri kurulu ise, u komut yardmyla Python 2.xi balatabilirsiniz:
py -2

Python 3.xi balatmak iin ise u komutu veriyoruz:


py -3

Eer sisteminizde birden fazla Python2 veya birden fazla Python3 srm kurulu ise, ana ve
alt srm numaralarn belirterek istediiniz srme ulaabilirsiniz:
py -2.6

py -2.7

py -3.4

py -3.5

Bu arada dikkat ettiyseniz, Python programlarn balatabilmek iin hem python hem de py
komutunu kullanma imkanna sahibiz. Eer sisteminizde tek bir Python srm kurulu ise,
Python balatmak iin python komutunu kullanmak isteyebilir, farkl srmlerin bir arada
bulunduu durumlarda ise py ile bu farkl srmlere tek tek erimek isteyebilirsiniz.
Bylece Pythonla ilgili en temel bilgileri edinmi olduk. Bu blmde rendiklerimiz
sayesinde Python programlama dilini bilgisayarmza kurabiliyor ve bu programlama dilini
baaryla altrabiliyoruz.

4.2. Windows Kullanclar 21


Python 3 iin Trke Klavuz, Srm 3

4.3 Hangi Komut Hangi Srm altryor?

Artk Python programlama dilinin bilgisayarmza nasl kurulacan ve bu programlama


dilinin nasl altrlacan biliyoruz. Ancak konunun neminden tr, tekrar vurgulayp,
cevabn bilip bilmediinizden emin olmak istediimiz bir soru var: Kullandnz iletim
sisteminde acaba hangi komut, hangi Python srmn altryor?
Bu kitapta anlattmz farkl yntemleri takip ederek, Python programlama dilini
bilgisayarnza farkl ekillerde kurmu olabilirsiniz. rnein Python programlama dilini,
kullandnz GNU/Linux datmnn paket yneticisi araclyla kurduysanz, Python
balatmak iin python3 komutunu kullanmanz gerekebilir. Ayn ekilde, eer Python
Windowsa kurduysanz, bu programlama dilini altrmak iin python komutunu kullanyor
olabilirsiniz. Btn bunlardan farkl olarak, eer Pythonn kaynak kodlarn sitesinden indirip
derlediyseniz, Python altrmak iin kendi belirlediiniz bambaka bir ad da kullanyor
olabilirsiniz. rnein belki de Python altrmak iin py3 gibi bir komut kullanyorsunuzdur...
Python programlama dilini altrmak iin hangi komutu kullanyor olursanz olun, ltfen bir
sonraki konuya gemeden nce kendi kendinize u sorular sorun:
1. Kullandm iletim sisteminde Python program halihazrda kurulu mu?
2. Kullandm iletim sisteminde toplam ka farkl Python srm var?
3. python komutu bu Python srmlerinden hangisini altryor?
4. python3 komutu alyor mu?
5. Eer alyorsa, bu komut Python srmlerinden hangisini altryor?
6. Kaynaktan derlediim Python srmn altrmak iin hangi komutu kullanyorum?
Biz bu kitapta unlar varsayacaz:
1. Kullandnz iletim sisteminde Pythonn 2.x srmlerini python komutuyla
altryorsunuz.
2. Kullandnz iletim sisteminde Pythonn 3.x srmlerini python3 komutuyla
altryorsunuz.
Bu kitaptan yararlanrken, bu varsaymlar gz nnde bulundurmal, eer bunlardan farkl
komutlar kullanyorsanz, kodlarnz ona gre ayarlamalsnz.

4.4 Sistem Komut Satr ve Python Komut Satr

Buraya kadar Python programlama dilini nasl altracamz konusundaki btn bilgileri
edindik. Ancak programlamaya yeni balayanlarn ok sk yapt bir hata var: Sistem komut
satr ile Python komut satrn birbirine kartrmak.
Asla unutmayn, kullandnz iletim sisteminin komut satr ile Pythonn komut satr
birbirinden farkl iki ortamdr. Yani Windowsta cmd, Ubuntuda ise Ctrl+Alt+T ile ulatnz
ortam sistem komut satr iken, bu ortam ap python3 (veya python ya da py3) komutu
vererek ulatnz ortam Pythonn komut satrdr. Sistem komut satrnda sistem komutlar
(mesela cd, ls, dir, pwd) verilirken, Python komut satrnda, biraz sonra renmeye
balayacamz Python komutlar verilir. Dolaysyla python3 (veya python ya da py3)
komutunu verdikten sonra ulatnz ortamda cd Desktop ve ls gibi sistem komutlarn
kullanmaya almanz sizi hsrana uratacaktr.

22 Blm 4. Python Nasl altrlr?


BLM 5

Etkileimli Python

u ana kadar rendiklerimiz sayesinde Python programlama dilinin farkl sistemlere


nasl kurulacan ve nasl altrlacan biliyoruz. Dolaysyla Python bir nceki
blmde anlattmz ekilde altrdmz zaman una benzer bir ekranla karlaacamzn
farkndayz:
istihza@ubuntu:~$ # python3 Python 3.5.1 (default, 20.04.2016, 12:24:55) [GCC 4.4.7
20120313 (Red Hat 4.4.7-3)] on linux Type help, copyright, credits or license for more
information. >>>
Biz imdiye kadar bu ekrana Python komut satr demeyi tercih ettik. Dilerseniz bundan
sonra da bu ad kullanmaya devam edebilirsiniz. Ancak teknik olarak bu ekrana etkileimli
kabuk (interactive shell ) ad verildiini bilmemizde fayda var. Etkileimli kabuk, bizim Python
programlama dili ile iliki kurabileceimiz, yani onunla etkileebileceimiz bir st katmandr.
Etkileimli kabuk, asl programmz iinde kullanacamz kodlar deneme imkan sunar bize.
Buras bir nevi test alan gibidir. rnein bir Python kodunun alp almadn denemek
veya nasl altn, ne sonu verdiini grmek istediimizde bu ekran son derece faydal bir
ara olarak karmza kar. Bu ortam, zellikle Pythona yeni balayanlarn bu programlama
diline ainalk kazanmasn salamas asndan da bulunmaz bir aratr. Biz de bu blmde
etkileimli kabuk zerinde baz almalar yaparak, Pythona alma turlar atacaz.
Bu arada, geen blmde sylediimiz gibi, bu ortamn sistem komut satr adn verdiimiz
ortamdan farkl olduunu aklmzdan karmyoruz. O zaman da dediimiz gibi, sistem komut
satrnda sistem komutlar, Python komut satrnda (yani etkileimli kabukta) ise Python
komutlar verilir. Mesela echo %PATH%, cd Desktop, dir ve ls birer sistem komutudur. Eer
bu komutlar etkileimli kabukta vermeye kalkrsanz, bunlar birer Python komutu olmad
iin, Python size bir hata mesaj gsterecektir. Mesela Pythonn etkileimli kabuunda cd
Desktop komutunu verirseniz yle bir hata alrsnz:
>>> cd Desktop

File "<stdin>", line 1


cd Desktop
^
SyntaxError: invalid syntax

nk cd Desktop bir Python komutu deildir. O yzden bu komutu Pythonn etkileimli


kabuunda veremeyiz. Bu komutu ancak ve ancak kullandmz iletim sisteminin komut
satrnda verebiliriz.
Ne diyorduk? Etkileimli kabuk bir veya birka satrlk kodlar denemek/test etmek iin gayet
uygun bir aratr. sterseniz konuyu daha fazla lafa bomayalm. Zira etkileimli kabuu

23
Python 3 iin Trke Klavuz, Srm 3

kullandka bunun ne byk bir nimet olduunu siz de anlayacaksnz. zellikle derlenerek
altrlan programlama dilleri ile uram olan arkadalarm, etkileimli kabuun gcn
grdklerinde gz yalarna hakim olamayacaklar.
Farkl iletim sistemlerinde py3, py -3, python3 veya python komutunu vererek Pythonn
komut satrna nasl eriebileceimizi nceki derslerde ayrntl olarak anlatmtk. Etkileimli
kabua ulamakta sknt yayorsanz eski konular tekrar gzden geirmenizi tavsiye ederim.
Etkileimli kabuk zerinde almaya balamadan nce dilerseniz nemli bir konuyu akla
kavuturalm: Etkileimli kabuu baaryla altrdk. Peki bu kabuktan kmak istersek
ne yapacaz? Elbette dorudan pencere zerindeki arp tuuna basarak bu ortam terk
edebilirsiniz. Ancak bu ilemi kaba kuvvete bavurmadan yapmann bir yolu olmal, deil mi?
Etkileimli kabuktan kmann birka farkl yolu vardr:
1. Pencere zerindeki arp dmesine basmak (kaba kuvvet)
2. nce Ctrl+Z tularna, ardndan da Enter tuuna basmak (Windows)
3. Ctrl+Z tularna basmak (GNU/Linux)
4. nce F6 tuuna, ardndan da Enter tuuna basmak (Windows)
5. quit() yazp Enter tuuna basmak (Btn iletim sistemleri)
6. import sys; sys.exit() komutunu vermek (Btn iletim sistemleri)
Siz bu farkl yntemler arasndan, kolaynza hangisi geliyorsa onu seebilirsiniz. Bu satrlarn
yazar, Windowsta 2 numaral; GNU/Linuxta ise 3 numaral seenei tercih ediyor.

5.1 Etkileimli Kabukta lk Admlar

Pythonda etkileimli kabuu nasl altracamz ve bu ortam nasl terk edeceimizi


rendiimize gre artk etkileimli kabuk araclyla Python programlama dilinde ilk
admlarmz atmaya balayabiliriz.
imdi kendi sistemimize uygun bir ekilde etkileimli kabuu tekrar altralm. Etkileimli
kabuu altrdmzda ekranda grnen >>> iareti Pythonn bizden komut almaya hazr
olduunu gsteriyor. Python kodlarmz bu >>> iaretinden hemen sonra, hi boluk
brakmadan yazacaz.
Buradaki hi boluk brakmadan ksm nemli. Pythona yeni balayanlarn en sk yapt
hatalardan biri >>> iareti ile komut arasnda boluk brakmalardr. Eer bu ekilde boluk
brakrsanz yazdnz kod hata verecektir.
sterseniz basit bir deneme yapalm. >>> iaretinden hemen sonra, hi boluk brakmadan
u komutu yazalm:
>>> "Merhaba Zalim Dnya!"

Bu arada yukardaki kodlar iinde grnen >>> iaretini siz yazmayacaksnz. Bu iareti
etkileimli kabuun grnmn temsil etmek iin yerletirdik oraya. Siz Merhaba Zalim
Dnya! satrn yazdktan sonra doruca Enter dmesine basacaksnz.
Bu komutu yazp Enter tuuna bastmzda yle bir kt alm olmalyz:
'Merhaba Zalim Dnya!'

24 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

Bylece yarm yamalak da olsa ilk Python programmz yazm olduk...


Muhtemelen bu kod, iinizde en ufak bir heyecan dahi uyandrmamtr. Hatta byle bir kod
yazmak size anlamsz bile gelmi olabilir. Ama aslnda u kck kod paras bile bize Python
programlama dili hakknda ok nemli ipular veriyor. Gelin isterseniz bu tek satrlk kodu
biraz inceleyelim...

5.1.1 Karakter Dizilerine Giri

Dediimiz gibi, yukarda yazdmz kck kod paras sizi heyecanlandrmam olabilir,
ama aslnda bu kod Python programlama dili ve bu dilin yaps hakknda ok nemli bilgileri
iinde barndryor.
Teknik olarak sylemek gerekirse, yukarda yazdmz Merhaba Zalim Dnya! ifadesi bir
karakter dizisidir. ngilizcede buna string ad verilir ve programlama asndan son derece
nemli bir kavramdr bu. Kavramn adndan da rahatlkla anlayabileceiniz gibi, bir veya daha
fazla karakterden oluan elere karakter dizisi (string ) diyoruz.
Karakter dizileri btn programclk maceramz boyunca karmza kacak. O yzden bu
kavram ne kadar erken renirsek o kadar iyi.
Peki bir verinin karakter dizisi olup olmamasnn bize ne faydas var? Yani yukardaki cmle
karakter dizisi olmu olmam bize ne?
Pythonda, o anda elinizde bulunan bir verinin hangi tipte olduunu bilmek son derece
nemlidir. nk bir verinin ait olduu tip, o veriyle neler yapp neler yapamayacanz
belirler. Pythonda her veri tipinin belli bal zellikleri vardr. Dolaysyla, elimizdeki
bir verinin tipini bilmezsek o veriyi programlarmzda etkin bir ekilde kullanamayz. te
yukarda rneini verdiimiz Merhaba Zalim Dnya! adl karakter dizisi de bir veri tipidir.
Pythonda karakter dizileri dnda baka veri tipleri de bulunur. Biraz sonra baka veri
tiplerini de inceleyeceiz.
Dikkat ederseniz Merhaba Zalim Dnya! adl karakter dizisini trnak iinde gsterdik. Bu da
ok nemli bir bilgidir. Eer bu cmleyi trnak iine almazsak programmz hata verecektir:
>>> Merhaba Zalim Dnya!

File "<stdin>", line 1


Merhaba Zalim Dnya!
^
SyntaxError: invalid syntax

Zaten trnak iaretleri, karakter dizilerinin ayrt edici zelliidir. yle ki, Pythonda trnak
iinde gsterdiiniz her ey bir karakter dizisidir. rnein u bir karakter dizisidir:
>>> "a"

Grdnz gibi, trnak iinde gsterilen tek karakterlik bir e de Pythonda karakter dizisi
snfna giriyor.
Mesela u, ii bo bir karakter dizisidir:
>>> ""

u da iinde bir adet boluk karakteri barndran bir karakter dizisi...

5.1. Etkileimli Kabukta lk Admlar 25


Python 3 iin Trke Klavuz, Srm 3

>>> " "

Bu ikisi arasndaki farka dikkat ediyoruz: Pythonda bo karakter dizisi ve bir adet boluktan
oluan karakter dizisi birbirlerinden farkl iki kavramdr. Adndan da anlalaca gibi, bo
karakter dizileri ilerinde hibir karakter (baka bir deyile e) barndrmayan karakter
dizileridir. Bir (veya daha fazla) boluktan oluan karakter dizileri ise ilerinde boluk karakteri
barndran karakter dizileridir. Yani bu karakter dizilerinden biri bo, teki ise doludur. Ama
neticede her ikisi de karakter dizisidir. u anda olduka anlamsz bir konu zerinde vakit
kaybediyormuuz hissine kaplm olabilirsiniz, ama emin olun, Python programlama diline
yeni balayanlarn nemli tkezleme noktalarndan biridir bu sylediimiz ey...
Dilerseniz biz karakter dizilerine elimizin almas iin birka rnek verelim:
>>> "Elma"

'Elma'

>>> "Guido Van Rossum"

'Guido Van Rossum'

>>> "Python programlama dili"

'Python programlama dili'

>>> "mnhbgfgh"

'mnhbgfgh'

>>> "$5&"

'$5&'

>>> ""

''

>>> " "

' '

>>> " "

' '

Yukardaki rneklerin hepsi birer karakter dizisidir. Dikkat ettiyseniz yukardaki karakter
dizilerinin hepsinin ortak zellii trnak iinde gsteriliyor olmasdr. Dediimiz gibi, trnak
iaretleri karakter dizilerinin ayrt edici zelliidir.
Peki bir verinin karakter dizisi olup olmadndan nasl emin olabilirsiniz?
Eer herhangi bir verinin karakter dizisi olup olmad konusunda tereddtnz varsa, type()
adl bir fonksiyondan yararlanarak o verinin tipini sorgulayabilirsiniz. Bu fonksiyonu yle
kullanyoruz:
>>> type("Elma")

<class 'str'>

26 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

Not: Bu fonksiyon kelimesinin kafanz kartrmasna izin vermeyin. lerde fonksiyonlar


olduka ayrntl bir ekilde inceleyeceimiz iin, type() ifadesinin bir fonksiyon olduunu
bilmeniz imdilik yeterli olacaktr. stelik fonksiyon konusunu ayrntl bir ekilde anlatma
vakti geldiinde siz fonksiyonlara dair pek ok eyi zaten renmi olacaksnz.

Burada amacmz Elma adl enin tipini denetlemek. Denetlenecek eyi type()
fonksiyonunun parantezleri arasnda belirttiimize dikkat edin. (Fonksiyonlarn parantezleri
iinde belirtilen deerlere teknik dilde parametre ad verilir.)
Yukardaki ktda bizi ilgilendiren ksm, sondaki str ifadesi. Tahmin edebileceiniz gibi,
bu ifade string kelimesinin ksaltmasdr. Bu kelimenin Trkede karakter dizisi anlamna
geldiini sylemitik. O halde yukardaki ktya bakarak, Elma esinin bir karakter dizisi
olduunu syleyebiliyoruz.
type() fonksiyonu yardmyla kendi kendinize baz denemeler yaparak konuyu iyice
sindirmenizi tavsiye ederim. Mesela {656$#gfd ifadesinin hangi snfa girdiini kontrol
etmekle balayabilirsiniz.
Peki karakter dizileri ile neler yapabiliriz? u anda Python bilgimiz kstl olduu iin karakter
dizileri ile ok fazla ey yapamayz, ama ilerde bilgimiz arttka, karakter dizileriyle sk fk
olacaz.
Esasnda, henz bilgimiz kstl da olsa karakter dizileriyle yine de ufak tefek baz eyler
yapamayacak durumda deiliz. Mesela u anki bilgilerimizi ve grr grmez size tandk
gelecek baz basit paralar kullanarak, karakter dizilerini birbirleriyle birletirebiliriz:
>>> "istihza" + ".com"

'istihza.com'

Burada + iaretini kullanarak karakter dizilerini nasl birletirebildiimize dikkat edin. ki


karakter dizisini + iareti ile birletirdiimizde karakter dizilerinin arasnda boluk olmadna
zellikle dikkatinizi ekmek isterim. Bu durumu u rnekte daha net grebiliriz:

>>> "Frat" + "zgl"

'Fratzgl'

Grdnz gibi, bu iki karakter dizisi, arada boluk olmadan birbiriyle bititirildi. Araya
boluk eklemek iin birka farkl yntemden yararlanabilirsiniz:

>>> "Frat" + " " + "zgl"

'Frat zgl'

Burada iki karakter dizisi arasna bir adet boluk karakteri yerletirdik. Ayn etkiyi u ekilde
de elde edebilirsiniz:

>>> "Frat" + " zgl"

Burada da zgl karakter dizisinin bana bir adet boluk yerletirerek istediimiz kty elde
ettik.
Bu arada, karakter dizilerini birletirmek iin mutlaka + iareti kullanmak zorunda deilsiniz.
Siz + iaretini kullanmasanz da Python sizin karakter dizilerini birletirmek istediinizi
anlayacak kadar zekidir:

5.1. Etkileimli Kabukta lk Admlar 27


Python 3 iin Trke Klavuz, Srm 3

>>> "www" "." "google" "." "com"

'www.google.com'

Ancak grdnz gibi, + iaretini kullandnzda kodlarnz daha okunakl oluyor.


+ iareti dnda karakter dizileri ile birlikte * (arp) iaretini de kullanabiliriz. O zaman yle
bir etki elde ederiz:
>>> "w" * 3

'www'

>>> "yava " * 2

'yava yava '

>>> "-" * 10

'----------'

>>> "uzak" + " " * 5 + "ok uzak..."

'uzak ok uzak...'

Grdnz gibi, ok basit paralar bir araya getirerek karmak ktlar elde edebiliyoruz.
Mesela son rnekte uzak adl karakter dizisine nce 5 adet boluk karakteri (" " * 5),
ardndan da ok uzak... adl karakter dizisini ekleyerek istediimiz kty aldk.
Burada + ve * adl iki yeni ara gryoruz. Bunlar aslnda saylarla birlikte kullanlan birer
aritmetik iletir. Normalde + ileci toplama ilemleri iin, * ileci ise arpma ilemleri iin
kullanlr. Ama yukardaki rneklerde, + iaretinin birletirme; * iaretinin ise tekrarlama
anlamndan tr bu iki ileci baz durumlarda karakter dizileri ile birlikte de kullanabiliyoruz.
Bunlarn dnda bir de - (eksi) ve / (bl) ileleri bulunur. Ancak bu iaretleri karakter dizileri
ile birlikte kullanamyoruz.
Karakter dizilerini sonraki bir blmde btn ayrntlaryla inceleyeceiz. O yzden imdilik
bu konuya bir ara verelim.

5.1.2 Saylara Giri

Dedik ki, Pythonda birtakm veri tipleri bulunur ve karakter dizileri de bu veri tiplerinden
yalnzca biridir. Veri tipi olarak karakter dizilerinin dnda, biraz nce aritmetik ileler
vesilesiyle szn ettiimiz, bir de say (number ) adl bir veri tipi vardr.
Herhalde saylarn ne anlama geldiini tarif etmeye gerek yok. Bunlar bildiimiz saylardr.
Mesela:
>>> 23

23

>>> 4567

4567

28 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

>>> 2.3

2.3

>>> (10+2j)

(10+2j)

Pythonda saylarn farkl alt trleri bulunur. Mesela tamsaylar, kayan noktal saylar,
karmak saylar...
Yukardaki rnekler arasnda geen 23 ve 4567 birer tamsaydr. ngilizcede bu tr saylara
integer ad verilir.
2.3 ise bir kayan noktal saydr (oating point number veya ksaca oat ). Bu arada kayan
noktal saylarda basamak ayrac olarak virgl deil, nokta iareti kullandmza dikkat edin.
En sonda grdmz 10+2j says ise bir karmak saydr (complex ). Ancak eer
matematikle youn bir ekilde uramyorsanz karmak saylar pek karnza kmaz.
Saylar temel olarak rendiimize gre etkileimli kabuu basit bir hesap makinesi niyetine
kullanabiliriz:
>>> 5 + 2

>>> 25 * 25

625

>>> 5 / 2

2.5

>>> 10 - 3

Yukardaki rneklerde kullandmz aritmetik ilelerden biraz nce bahsetmitik. O yzden


bunlara yabanclk ektiinizi zannetmiyorum. Ama biz yine de bu ileleri ve grevlerini
ylece sralayalm:
le Grevi
+ toplama
- karma
* arpma
/ blme
Yukardaki rneklerde bir ey dikkatinizi ekmi olmal: Karakter dizilerini tanmlarken trnak
iaretlerini kullandk. Ancak saylarda trnak iareti yok. Daha nce de dediimiz gibi, trnak
iaretleri karakter dizilerinin ayrt edici zelliidir. Pythonda trnak iinde gsterdiiniz her
ey bir karakter dizisidir. Mesela u rneklere bakalm:
>>> 34657

34657

5.1. Etkileimli Kabukta lk Admlar 29


Python 3 iin Trke Klavuz, Srm 3

Bu bir saydr. Peki ya u?


>>> "34657"

'34657'

Bu ise bir karakter dizisidir. Dilerseniz biraz nce rendiimiz type() fonksiyonu yardmyla
bu verilerin tipini sorgulayalm:
>>> type(34657)

<class 'int'>

Buradaki int ifadesi ngilizce integer , yani tamsay kelimesinin ksaltmasdr. Demek ki
34657 says bir tamsay imi. Bir de una bakalm:
>>> type("34657")

<class 'str'>

Grdnz gibi, 34657 saysn trnak iine aldmzda bu say artk say olma zelliini
yitiriyor ve bir karakter dizisi oluyor. u anda bu ok nemsiz bir ayrntym gibi gelebilir
size, ama aslnda son derece nemli bir konudur bu. Bu durumun etkilerini u rneklerde
grebilirsiniz:
>>> 23 + 65

88

Burada normal bir ekilde iki sayy birbiriyle topladk.


Bir de una bakn:
>>> "23" + "65"

'2365'

Burada ise Python iki karakter dizisini yan yana yazmakla yetindi; yani bunlar birletirdi.
Python asndan 23 ve 23 birbirinden farkldr. 23 bir karakter dizisi iken, 23 bir saydr.
Ayn ey 65 ve 65 iin de geerlidir. Yani Python asndan 65 ile Merhaba Zalim Dnya!
arasnda hi bir fark yoktur. Bunlarn ikisi de karakter dizisi snfna girer. Ancak 65 ile 65
birbirinden farkldr. 65 bir say iken, 65 bir karakter dizisidir.
Bu bilgi, zellikle aritmetik ilemlerde byk nem tar. Bunu dilerseniz u rnekler zerinde
gsterelim:
>>> 45 + "45"

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Grdnz gibi, yukardaki kodlar hata veriyor. Bunun sebebi bir say (45 ) ile bir karakter
dizisini (45 ) birbiriyle toplamaya almamzdr. Asla unutmayn, aritmetik ilemler ancak
saylar arasnda yaplr. Karakter dizileri ile herhangi bir aritmetik ilem yaplamaz.
Bir de una bakalm:

30 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

>>> 45 + 45

90

Bu kodlar ise dzgn alr. nk burada iki sayy aritmetik ileme soktuk ve baarl olduk.
Son olarak u rnei verelim:
>>> "45" + "45"

'4545'

Burada + ilecinin toplama anlamna gelmediine dikkat edin. Bu ile burada iki karakter
dizisini birletirme grevi stleniyor. Yani yukardaki rnein u rnekten hibir fark yoktur:
>>> "istihza." + "com"

'istihza.com'

Bu iki rnekte de yaptmz ey karakter dizilerini birbiriyle birletirmektir.


Grdnz gibi, + ilecinin sandaki ve solundaki deerler birer karakter dizisi ise bu ile
bu iki deeri birbiriyle birletiriyor. Ama eer bu deerler birer say ise + ileci bu deerleri
birbiriyle aritmetik olarak topluyor.
* ileci de + ilecine benzer bir i yapar. Yani eer * ileci bir say ve bir karakter dizisi ile
karlarsa, o karakter dizisini, verilen say kadar tekrarlar. rnein:
>>> "w" * 3

'www'

Burada * ileci bir karakter dizisi (w ) ve bir say (3 ) arasnda ilem yapt iin, karakter
dizisini, ilgili say kadar tekrarlyor. Yani w karakter dizisini 3 kez tekrarlyor.
Bir de una bakalm:
>>> 25 * 3

75

Burada ise * ileci iki adet say arasnda ilem yapt iin bu deerleri birbiriyle aritmetik
olarak arpyor ve 75 deerini elde etmemizi salyor.
Grdnz gibi, o anda elimizde bulunan verilerin tipini bilmek gerekten de byk nem
tayor. nk eer elimizdeki verilerin tipini bilmezsek nasl sonular elde edeceimizi de
kestiremeyiz.
Bylece karakter dizileri ile saylar arasndaki fark renmi olduk. Bu bilgiler size
nemsizmi gibi gelebilir, ama aslnda karakter dizileri ile saylar arasndaki fark anlamak,
Python programlama dilinin nemli bir blmn renmi olmak demektir. leride
yazacanz en karmak programlarda bile, bazen programnzn almamasnn (veya daha
kts yanl almasnn) nedeninin karakter dizileri ile saylar birbirine kartrmanz
olduunu greceksiniz. O yzden burada rendiiniz hibir bilgi krntsn batan
savmamanz (ve sabrszlk ya da acelecilik etmemenizi) tavsiye ederim.

5.1. Etkileimli Kabukta lk Admlar 31


Python 3 iin Trke Klavuz, Srm 3

5.1.3 Deikenler

imdi yle bir durum dnn: Diyelim ki sisteme kayt iin kullanc ad ve parola
belirlenmesini isteyen bir program yazyorsunuz. Yazacanz bu programda, belirlenebilecek
kullanc ad ve parolann toplam uzunluu 40 karakteri gemeyecek.
Bu program yazarken ilk aamada yapmanz gereken ey, kullancnn belirledii kullanc ad
ve parolann uzunluunu tek tek denetlemek olmal.
Mesela kullanc yle bir kullanc ad belirlemi olsun:
firat_ozgul_1980

Kullancnn belirledii parola ise u olsun:


rT%65#$hGfUY56123

te bizim ncelikle kullancdan gelen bu verilerin teker teker uzunluunu biliyor olmamz
lazm, ki bu verilerin toplam 40 karakter snrn ap amadn denetleyebilelim.
Peki bu verilerin uzunluunu nasl leceiz? Elbette bunun iin verilerdeki hareri elle
tek tek saymayacaz. Bunun yerine, Python programlama dilinin bize sunduu bir arac
kullanacaz. Peki nedir bu ara?
Hatrlarsanz birka sayfa nce type() adl bir fonksiyondan sz etmitik. Bu fonksiyonun
grevi bir verinin hangi tipte olduunu bize bildirmekti. te tpk type() gibi, Pythonda
len() adl baka bir fonksiyon daha bulunur. Bu fonksiyonun grevi ise karakter dizilerinin
(ve ileride greceimiz gibi, baka veri tiplerinin) uzunluunu lmektir. Yani bu fonksiyonu
kullanarak bir karakter dizisinin toplam ka karakterden olutuunu renebiliriz.
Biz henz kullancdan nasl veri alacamz bilmiyoruz. Ama imdilik unu syleyebiliriz:
Pythonda kullancdan herhangi bir veri aldmzda, bu veri bize bir karakter dizisi olarak
gelecektir. Yani kullancdan yukardaki kullanc ad ve parolay aldmz varsayarsak, bu
veriler bize u ekilde gelir:
"firat_ozgul_1980"

ve:
"rT%65#$hGfUY56123"

Grdnz gibi, elde ettiimiz veriler trnak iinde yer alyor. Yani bunlar birer karakter
dizisi. imdi gelin yukarda bahsettiimiz len() fonksiyonunu kullanarak bu karakter
dizilerinin uzunluunu lelim.
Dediimiz gibi, len() de tpk type() gibi bir fonksiyondur. Dolaysyla len() fonksiyonunun
kullanm type() fonksiyonunun kullanmna ok benzer. Nasl type() fonksiyonu bize,
kendisine verdiimiz parametrelerin tipini sylyorsa, len() fonksiyonu da kendisine
verdiimiz parametrelerin uzunluunu syler.
Dikkatlice bakn:
>>> len("firat_ozgul_1980")

16

>>> len("rT%65#$hGfUY56123")

32 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

17

Demek ki rat_ozgul_1980 adl karakter dizisinde 16 ; rT%65#$hGfUY56123 adl karakter


dizisinde ise 17 karakter varm. Bizim istediimiz ey bu iki deerin toplam uzunluunun 40
karakteri amamas. Bunu denetlemek iin yapmamz gereken ey bu iki deerin uzunluunu
birbiriyle toplamak olmal. Yani:
>>> len("firat_ozgul_1980") + len("rT%65#$hGfUY56123")

Buradan alacamz sonu 33 olacaktr. Demek ki kullanc 40 karakter limitini amam. O


halde programmz bu kullanc ad ve parolay kabul edebilir...
Bu arada, belki farkettiniz, belki de farketmediniz, ama burada da ok nemli bir durumla
kar karyayz. Grdnz gibi len() fonksiyonu bize say deerli bir veri gnderiyor. Gelin
isterseniz bunu teyit edelim:
>>> type(len("firat_ozgul_1980"))

<class 'int'>

len() fonksiyonunun bize say deerli bir veri gndermesi sayesinde bu fonksiyondan elde
ettiimiz deerleri birbiriyle toplayabiliyoruz:
>>> len("firat_ozgul_1980") + len("rT%65#$hGfUY56123")

33

Eer len() fonksiyonu bize say deil de mesela karakter dizisi verseydi, bu fonksiyondan elde
ettiimiz deerleri yukardaki gibi dorudan birbiriyle aritmetik olarak toplayamazdk. yle
bir durumda, bu iki veriyi birbiriyle toplamaya altmzda, + ileci 16 ve 17 deerlerini
birbiriyle toplamak yerine bu deerleri birbiriyle birletirerek bize 1617 gibi bir sonu
verecekti.
Her zaman sylediimiz gibi, Pythonda veri tipi kavramn ok iyi anlamak ve o anda elimizde
bulunan bir verinin hangi tipte olduunu bilmek ok nemlidir. Aksi halde programlarmzda
hata yapmamz kanlmazdr.
Eer yukarda anlattmz eyleri kafa kartrc bulduysanz hi endie etmeyin. Birka
blm sonra input() adl bir fonksiyondan bahsettiimizde imdi sylediimiz eyleri ok
daha net anlayacaksnz.
Biraz sonra len() fonksiyonundan bahsetmeye devam edeceiz, ama isterseniz ondan nce
ok nemli bir konuya deinelim.
Biraz nce yle bir rnek vermitik:
>>> len("firat_ozgul_1980")

16

>>> len("rT%65#$hGfUY56123")

17

>>> len("firat_ozgul_1980") + len("rT%65#$hGfUY56123")

5.1. Etkileimli Kabukta lk Admlar 33


Python 3 iin Trke Klavuz, Srm 3

Bu kodlar, istediimiz eyi gayet gzel yerine getiriyor. Ama sizce de yukardaki kodlarda ok
rahatsz edici bir durum yok mu?
Dikkat ederseniz, yukardaki rneklerde kullandmz verileri, program iinde her
ihtiya duyduumuzda tekrar tekrar yazdk. Bylece ayn program iinde iki kez
rat_ozgul_1980 ; iki kez de rT%65#$hGfUY56123 yazmak zorunda kaldk. Halbuki bu
verileri programlarmzn iinde her ihtiya duyduumuzda tekrar tekrar yazmak yerine bir
deikene atasak ve gerektiinde o deikeni kullansak ok daha iyi olmaz m? Herhalde
olur...
Peki nedir bu deiken dediimiz ey?
Pythonda bir program iinde deerlere verilen isimlere deiken denir. Hemen bir rnek
verelim:
>>> n = 5

Burada 5 saysn bir deikene atadk. Deikenimiz ise n. Ayrca 5 saysn bir deikene
atamak iin = iaretinden yararlandmza da ok dikkat edin. Buradan, = iaretinin Python
programlama dilinde deer atama ilemleri iin kullanld sonucunu karyoruz.
n = 5 gibi bir komut yardmyla 5 deerini n adl deikene atamamz sayesinde artk ne
zaman 5 saysna ihtiya duysak bu n deikenini armamz yeterli olacaktr:
>>> n

>>> n * 10

50

>>> n / 2

2.5

Grdnz gibi, 5 deerini bir deikene atadktan sonra, bu 5 deerini kullanmamz


gereken yerlerde sadece deikenin adn kullandmzda deikenin deerini Python
otomatik olarak yerine koyabiliyor. Yani n = 5 komutuyla n adl bir deiken tanmladktan
sonra, artk ne zaman 5 saysna ihtiya duysak n deikenini armamz yeterli olacaktr.
Python o 5 deerini otomatik olarak yerine koyar.
imdi de pi adl baka bir deiken tanmlayalm:
>>> pi = 3.14

Bu pi deikeninin deeri ile n deikeninin deerini toplayalm:


>>> pi + n

8.14

Grdnz gibi, deerleri her defasnda tekrar yazmak yerine bunlar bir deikene atayp,
gereken yerde bu deikeni kullanmak ok daha pratik bir yntem.
Ayn eyi programmz iin de yapabiliriz:
>>> kullanc_ad = "firat_ozgul_1980"
>>> parola = "rT%65#$hGfUY56123"

34 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

= iaretini kullanarak ilgili deerlere artk birer ad verdiimiz, yani bu deerleri birer
deikene atadmz iin, bu deerleri kullanmamz gereken yerlerde deerlerin kendisini
uzun uzun yazmak yerine, belirlediimiz deiken adlarn kullanabiliriz. Mesela:
>>> len(kullanc_ad)

16

>>> len(parola)

17

>>> len(kullanc_ad) + len(parola)

33

>>> k_ad_uzunluu = len(kullanc_ad)


>>> type(k_ad_uzunluu)

<class 'int'>

Grdnz gibi, deiken kullanm ilerimizi bir hayli kolaylatryor.

Deiken Ad Belirleme Kurallar

Python programlama dilinde, deiken ad olarak belirleyebileceimiz kelime says


neredeyse snrszdr. Yani hemen hemen her kelimeyi deiken ad olarak kullanabiliriz.
Ama yine de deiken ad belirlerken dikkat etmemiz gereken baz kurallar var. Bu kurallarn
bazlar zorunluluk, bazlar ise yalnzca tavsiye niteliindedir.
imdi bu kurallar tek tek inceleyelim:
1. Deiken adlar bir say ile balayamaz. Yani u kullanm yanltr:
>>> 3_kilo_elma = "5 TL"

2. Deiken adlar aritmetik ilelerle balayamaz. Yani u kullanm yanltr:


>>> +deer = 4568

3. Deiken adlar ya bir alfabe haryle ya da _ iaretiyle balamaldr:


>>> _deer = 4568
>>> deer = 4568

4. Deiken adlar iinde Trke karakterler kullanabilirsiniz. Ancak ileride beklenmedik uyum
sorunlar kmas ihtimaline kar deiken adlarnda Trke karakter kullanmaktan kanmak
isteyebilirsiniz.
5. Aadaki kelimeleri deiken ad olarak kullanamazsnz:
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class',
'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for',
'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not',
'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

Bunlar Pythonda zel anlam ifade eden kelimelerdir. Etkileimli kabuk zaten bu kelimeleri
deiken ad olarak kullanmanza izin vermez. rnein:

5.1. Etkileimli Kabukta lk Admlar 35


Python 3 iin Trke Klavuz, Srm 3

>>> elif = "ho kz"

File "<stdin>", line 1


elif = "ho kz"
^
SyntaxError: invalid syntax

>>> as = "kare"

File "<stdin>", line 1


as = "kare"
^
SyntaxError: invalid syntax

>>> False = 45

File "<stdin>", line 1


SyntaxError: assignment to keyword

Ama ilerde greceimiz gibi, programlarnz bir dosyaya yazarken bu kelimeleri deiken ad
olarak kullanmaya alrsanz programnz tespit etmesi ok g hatalar retecektir.
Bu arada elbette yukardaki listeyi bir rpda ezberlemeniz beklenmiyor sizden. Python
programlama dilini rendike zel kelimeleri bir bakta tanyabilecek duruma geleceksiniz.
Ayrca eer isterseniz u komutlar vererek, istediiniz her an yukardaki listeye ulaabilirsiniz:
>>> import keyword
>>> keyword.kwlist

['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class',


'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for',
'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not',
'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

Size bir soru: Acaba bu listede ka tane kelime var?


Bu soru karsnda listedeki kelimeleri tek tek elle saymaya kalkan arkadalarma
teesserimi iletiyorum... Bu tr iler iin hangi arac kullanabileceimizi artk ok iyi biliyor
olmalsnz:
>>> len(keyword.kwlist)

33

Bu kodlar yle yazabileceimizi de biliyorsunuz:


>>> yasakl_kelimeler = keyword.kwlist
>>> len(yasakl_kelimeler)

33

Bu arada, yukardaki kodlarn bir ksmn henz anlayamam olabilirsiniz. Hi endie


etmeyin. Yukardaki kodlar vermemizin sebebi deiken ad olarak kullanlamayacak
kelimelere ksa yoldan nasl ulaabileceinizi gsterebilmek iindir. Bir-iki blm sonra
burada yazdmz kodlar rahatlkla anlayabilecek dzeye geleceksiniz.
Yukarda verdiimiz kodlarn ktsndan anladmza gre, toplam 33 tane kelime varm
deiken ad belirlerken kullanmaktan kanmamz gereken...

36 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

6. Yukardaki kelimeler dnda, Python programlama diline ait fonksiyon ve benzeri


aralarn adlarn da deiken ad olarak kullanmamalsnz. rnein yazdnz programlarda
deikenlerinize type veya len ad vermeyin. nk type ve len Pythona ait iki nemli
fonksiyonun addr. Eer mesela bir deikene type adn verirseniz, o programda artk
type() fonksiyonunu kullanamazsnz:
>>> type = 3456

Bu rnekte type adnda bir deiken tanmladk. imdi mesela elma kelimesinin tipini
denetlemek iin type() fonksiyonunu kullanmaya alalm:
>>> type("elma")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

Grdnz gibi, artk type() fonksiyonu almyor. nk siz type kelimesini bir deiken
ad olarak kullanarak, type() fonksiyonunu kullanlamaz hale getirdiniz.
Bu durumdan kurtulmak iin etkileimli kabuu kapatp tekrar aabilirsiniz. Ya da eer
etkileimli kabuu kapatmak istemiyorsanz u komut yardmyla type deikenini ortadan
kaldrmay da tercih edebilirsiniz:
>>> del type

Bylece, (tahmin edebileceiniz gibi delete (silmek) kelimesinin ksaltmas olan) del
komutuyla type deikenini silmi oldunuz. Artk type kelimesi yine type() fonksiyonunu
aracak:
>>> type("elma")

<class 'str'>

7. Deiken adlarn belirlerken, deikeni oluturan kelimeler arasnda boluk braklamaz.


Yani u kullanm yanltr:
>>> kullanc ad = "istihza"

Yukardaki deikeni u ekilde tanmlayabiliriz:


>>> kullanc_ad = "istihza"

Ya da yle:
>>> kullancAd = "istihza"

8. Deiken adlar belirlerken, deiken adnn, deikenin deerini olabildiince


betimlemesine dikkat etmemiz kodlarmzn okunaklln artracaktr. rnein:
>>> personel_says = 45

Yukardaki, tanmlad deere uygun bir deiken addr. u ise kurallara uygun bir deiken
ad olsa da yeterince betimleyici deildir:
>>> say = 45

9. Deiken adlar ne ok ksa, ne de ok uzun olmaldr. Mesela u deiken ad, kodlar


okuyan kiiye, deiken deerinin anlam konusunda pek kir vermez:

5.1. Etkileimli Kabukta lk Admlar 37


Python 3 iin Trke Klavuz, Srm 3

>>> a = 345542353

u deiken ad ise gereksiz yere uzundur:


>>> trkiye_byk_millet_meclisi_milletvekili_says = 550

Deiken adlarnn uzunluunu makul seviyede tutmak esastr:


>>> tbmm_mv_says = 550

Yukarda verdiimiz btn bu rnekler bize, Pythonda deikenlerin, deerlere atanm


adlardan ibaret olduunu gsteriyor. Deikenler, yazdmz programlarda bize ok byk
kolaylk salar. Mesela 123432456322 gibi bir sayy ya da Trkiye Cumhuriyeti alma ve
Sosyal Gvenlik Bakanl gibi bir karakter dizisini gerektii her yerde tek tek elle yazmak
yerine, bunlar birer deikene atayarak, gerektiinde sadece bu deiken adn kullanmak
ok daha mantkl bir itir.
Ayrca zaten ileride kullancdan veri almaya baladnzda, aldnz bu verileri, yazdnz
programda kullanabilmek iin mutlaka bir deikene atamanz gerekecek. O yzden
Pythondaki deiken kavramn imdiden iyi tanyp anlamakta byk fayda var.

Uygulama rnekleri

Gelin isterseniz yukarda verdiimiz bilgileri pekitirmek iin birka ufak altrma yapalm,
altrma yaparken de sizi yine Python programlama diline ilikin ok nemli baz yeni
bilgilerle tantralm.
Diyelim ki aylk yol masrafmz hesaplayan bir program yazmak istiyoruz. Elimizdeki verilerin
unlar olduunu varsayalm:
1. Cumartesi-Pazar gnleri almyoruz.
2. Dolaysyla ayda 22 gn alyoruz.
3. Evden ie gitmek iin kullandmz vastann creti 1.5 TL
4. ten eve dnmek iin kullandmz vastann creti 1.4 TL
Aylk yol masrafmz hesaplayabilmek iin gidi ve dn cretlerini toplayp, bunlar
altmz gn saysyla arpmamz yeterli olacaktr. Elimizdeki bu bilgilere gre aylk yol
masrafmz hesaplamak iin yle bir forml retebiliriz:
masraf = gn says x (gidi creti + dn creti)

Dilerseniz hemen bunu bir Python program haline getirelim:


>>> 22 * (1.5 + 1.4)

63.8

Demek ki bir ayda 63.8 TLlik bir yol masrafmz varm.


Bu arada, yukardaki rnekte bir ey dikkatinizi ekmi olmal. Aritmetik ilemi yaparken baz
saylar parantez iine aldk. Pythonda aritmetik ilemler yaplrken altmz matematik
kurallar geerlidir. Yani mesela ayn anda blme, karma, toplama ve arpma ilemleri
yaplacaksa ilem ncelik sras nce blme ve arpma, sonra toplama ve karma eklinde
olacaktr. Elbette siz parantezler yardmyla bu ilem srasn deitirebilirsiniz.

38 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

Bu anlattklarmza gre, eer yukarda yol masrafn hesaplayan programda parantezleri


kullanmazsak, ilem ncelik kurallar gereince Python nce 22 ile 1.5 i arpp, kan sonucu
1.4 ile toplayaca iin elde ettiimiz sonu yanl kacaktr. Bizim burada doru sonu
alabilmemiz iin nce 1.5 ile 1.4 toplamamz, kan sonucu da 22 ile arpmamz gerekiyor.
Bu sralamay da parantezler yardmyla elde ediyoruz.
Yine dikkat ederseniz, yukardaki rnek programda aslnda ok verimsiz bir yol izledik.
Grdnz gibi, bu programda btn deerleri tek tek elle kendimiz giriyoruz. rnein
allan gn saysna karlk gelen 22 deerini baka bir yerde daha kullanmak istesek ayn
sayy tekrar elle dorudan kendimiz girmek zorundayz. Mesela ylda ka gn altmz
hesaplayalm:
>>> 22 * 12

264

Grdnz gibi, burada da 22 saysna ihtiya duyduk. Aslnda deerleri bu ekilde her
defasnda tekrar tekrar elle girmek hem hata yapma riskini artrd, hem de bize fazladan
i kard iin tercih edilmeyen bir yntemdir. Bunun yerine, 22 saysna bir isim verip,
gereken yerlerde bu ismi kullanmak daha mantkl olacaktr. Yani tpk kullanc ve parola
rneinde olduu gibi, burada da verileri ncelikle bir deikene atamak ok daha akllca bir
itir:
>>> gn = 22
>>> gidi_creti = 1.5
>>> dn_creti = 1.4
>>> gn * (gidi_creti + dn_creti)

63.8

Btn deerleri birer deikene atadmz iin, artk bu deikenleri istediimiz yerde
kullanabiliriz. Mesela ylda toplam ka gn altmz bulmak istersek, ilgili deeri elle
yazmak yerine, yukarda tanmladmz gn deikenini kullanabiliriz:
>>> gn * 12

264

lerleyen zamanda aylk allan gn says deiirse sadece gn deikeninin deerini


deitirmemiz yeterli olacaktr:
>>> gn = 23
>>> gn * (gidi_creti + dn_creti)

66.7

>>> gn * 12

276

Eer bu ekilde deiken atamak yerine, deerleri gerektii her yerde elle yazsaydk, bu
deerlerde herhangi bir deiiklik yapmamz gerektiinde program iinde geen ilgili btn
deerleri bulup tek tek deitirmemiz gerekecekti:
>>> 23 * (1.6 + 1.5)

71.3

5.1. Etkileimli Kabukta lk Admlar 39


Python 3 iin Trke Klavuz, Srm 3

>>> 23 * 12

276

Deiken kavram u anda gznze pek anlaml grnmemi olabilir. Ama programlarmz
ilerde dosyaya kaydettiimiz zaman bu deikenler ok daha kullanl aralar olarak
karmza kacaktr.
Dilerseniz bir rnek daha yaparak yukardaki bilgilerin kafamza iyice yerlemesiniz
salayalm. Mesela bir dairenin alann (yaklak olarak) hesaplayan bir program yazalm.
ncelikle ap adl bir deiken tanmlayarak dairenin apn belirleyelim:
>>> ap = 16

Bu deeri kullanarak dairemizin yarapn hesaplayabiliriz. Bunun iin ap deikeninin


deerinin yarsn almamz yeterli olacaktr:
>>> yarap = ap / 2

pi saysn 3.14159 olarak alalm.


>>> pi = 3.14159

Bir dairenin alan forml (pi)r2 dir:


>>> alan = pi * (yarap * yarap)

Son olarak alan deikeninin deerini ekrana yazdrabiliriz:


>>> alan

201.06176

Bylece bir dairenin alann yaklak olarak hesaplam olduk. Dilerseniz programmz bir de
derli toplu olarak grelim:
>>> ap = 16
>>> yarap = ap / 2
>>> pi = 3.14159
>>> alan = pi * (yarap * yarap)
>>> alan

201.06176

Gryorsunuz ya, deikenler iimizi nasl da kolaylatryor. Eer yukardaki programda


deiken kullanmasaydk kodlarmz yle grnecekti:
>>> 3.14159 * ((16/2) * (16/2))

201.06176

Bu kodlar tek kullanmlktr. Eer yukardaki rnekte mesela dairenin apn deitirmeniz
gerekirse, iki yerde elle deiiklik yapmanz gerekir. Ama deikenleri kullandmzda sadece
ap deikeninin deerini deitirmeniz yeterli olacaktr. Ayrca deiken kullanmadnzda,
ilgili deeri program boyunca aklnzda tutmanz gerekir. rnein ap deikenini kullanmak
yerine, gereken her yerde 16 deerini kullanacaksanz, bu 16 deerini srekli aklnzda

40 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

tutmanz lazm. Ama bu deeri en bata bir deikene atarsanz, 16 deerini kullanmanz
gereken yerlerde, aklda tutmas daha kolay bir ifade olan ap ismini kullanabilirsiniz.
Bu arada yeri gelmiken sizi yeni bir ilele daha tantralm. imdiye kadar Pythonda
toplama (+ ), karma (-), arpma (* ), blme (/ ) ve deer atama (= ) ilelerini grdk. Ama
yukarda verdiimiz son rnek, baka bir ile daha renmemizi gerektiriyor...
Yukardaki u rnee tekrar bakalm:
alan = pi * (yarap * yarap)

Burada yarap deikeninin karesini alabilmek iin bu deeri kendisiyle arptk. Aslnda
gayet mantkl ve makul bir yntem. Kare bulmak iin deeri kendisiyle arpyoruz. Eer
bir saynn kpn bulmak isteseydik o sayy kez kendisiyle arpacaktk:
>>> 3 * 3 * 3

27

Peki ya bir saynn mesela beinci kuvvetini hesaplamak istersek ne yapacaz? O sayy be
kez kendisiyle mi arpacaz? Bu ne kadar vasat bir yntem, deil mi?
Elbette bir saynn herhangi bir kuvvetini hesaplamak iin o sayy kendisiyle kuvvetince
arpmayacaz. Pythonda bu tr kuvvet hesaplamalar iin ayr bir ile (ve fonksiyon)
bulunur.
ncelikle kuvvet hesaplarn yapmamz salayan ileten sz edelim.
Pythonda ** adl bir ile bulunur. Bu ilecin grevi bir saynn kuvvetini hesaplamamz
salamaktr. rnein bir saynn 2. kuvvetini, ya da baka bir deyile karesini hesaplamak
istersek yle bir kod yazabiliriz:
>>> 12 ** 2

144

Burada 12 saysnn 2. kuvvetini, yani karesini hesapladk. Bu bilgiyi yukardaki formle


uygulayalm:
>>> alan = pi * (yarap ** 2)

Bu ileci herhangi bir saynn herhangi bir kuvvetini hesaplamak iin kullanabiliriz elbette.
Mesela 23 saysnn kpn (yani 3. kuvvetini) hesaplayalm:
>>> 23 ** 3

12167

Ayn ileten, bir saynn karekkn hesaplamak iin de yararlanabilirsiniz. Neticede bir
saynn 0.5 inci kuvveti, o saynn karekkdr:
>>> 144 ** 0.5

12.0

Grdnz gibi, kuvvet hesaplama ilemleri iin bu ile son derece kullanl bir ara
vazifesi gryor. Ama eer istersek ayn i iin zel bir fonksiyondan da yararlanabiliriz. Bu
fonksiyonun ad pow().
Peki bu fonksiyonu nasl kullanacaz?

5.1. Etkileimli Kabukta lk Admlar 41


Python 3 iin Trke Klavuz, Srm 3

Daha nce rendiimiz type() ve len() fonksiyonlarn nasl kullanyorsak pow() fonksiyonu
da ayn ekilde kullanacaz.
type() ve len() fonksiyonlarn birtakm parametreler ile birlikte kullanyorduk hatrlarsanz.
Ayn ekilde pow() fonksiyonu da birtakm parametreler alr.
Daha nce rendiimiz fonksiyonlar tek bir parametre ile birlikte kullanmtk. pow()
fonksiyonu ise toplam farkl parametre alr. Ama genellikle bu fonksiyon yalnzca iki
parametre ile kullanlr.
Bu fonksiyonu yle kullanyoruz:
>>> pow(12, 2)

144

>>> pow(23, 3)

12167

>>> pow(144, 0.5)

12.0

Grdnz gibi, pow() fonksiyonunun ilk parametresi asl sayy, ikinci parametresi ise bu
saynn hangi kuvvetini hesaplamak istediimizi gsteriyor.
Bu arada, fonksiyonun parantezleri iinde belirttiimiz parametreleri birbirinden virgl ile
ayrdmz gzden karmayn.
Dediimiz gibi, pow() fonksiyonu, pek kullanlmayan nc bir parametre daha alr. Bu
fonksiyonun nc parametresi yle kullanlr. Dikkatlice bakn:
>>> pow(16, 2, 2)

Bu komut u anlama gelir:


16 saysnn 2 nci kuvvetini hesapla ve kan sayy 2 ye blp, blme ileminden
kalan sayy gster!
16 saysnn 2. kuvveti 256 saysdr. 256 saysn 2 ye bldmzde, blme ileminin kalan
0 dr. Yani 256 says 2 ye tam blnr...
Bir rnek daha verelim:
>>> pow(11, 3, 4)

Demek ki, 11 saysnn 3. kuvveti olan 1331 says 4 e blndnde, blme ileminden kalan
say 3 imi...
Dediimiz gibi, pow() fonksiyonu genellikle sadece iki parametre ile kullanlr. nc
parametrenin kullanm alan olduka dardr.

42 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

Deikenlere Dair Baz pular

Deikenin ne demek olduunu rendiimize gre, deikenlere dair baz ufak ipular
verebiliriz.

Ayn Deere Sahip Deikenler Tanmlama

imdi size yle bir soru sormama izin verin: Acaba ayn deere sahip iki deikeni nasl
tanmlayabiliriz? Yani mesela deeri 4 says olan iki farkl deikeni nasl belirleyeceiz?
Aklnza yle bir zm gelmi olabilir:
>>> a = 4
>>> b = 4

Bylece ikisi de 4 deerine sahip a ve b adl iki farkl deiken tanmlam olduk. Bu tamamen
geerli bir yntemdir. Ancak Pythonda bu ilemi yapmann daha kolay bir yolu var. Bakalm:
>>> a = b = 4

Bu kodlar bir ncekiyle tamamen ayn ilevi grr. Yani her iki kod da 4 deerine sahip a ve
b deikenleri tanmlamamz salar:
>>> a

>>> b

Bu bilgiyi kullanarak mesela bir yl iindeki her bir ayn ektii gn saysn ay adlarna
atayabilirsiniz:
>>> ocak = mart = mays = temmuz = austos = ekim = aralk = 31
>>> nisan = haziran = eyll = kasm = 30
>>> ubat = 28

Bylece bir rpda deeri 31 olan yedi adet deiken, deeri 30 olan drt adet deiken,
deeri 28 olan bir adet deiken tanmlam olduk. Bu deikenlerin deerine nasl
ulaacanz biliyorsunuz:
>>> ocak

31
>>> haziran

30

>>> ubat

28

>>> mays

31

5.1. Etkileimli Kabukta lk Admlar 43


Python 3 iin Trke Klavuz, Srm 3

>>> ekim

31

>>> eyll

30

Eer Pythonn ayn anda birden fazla deikene tek bir deer atama zellii olmasayd
yukardaki kodlar yle yazmamz gerekirdi:
>>> ocak = 31
>>> ubat = 28
>>> mart = 31
>>> nisan = 30
>>> mays = 31
>>> haziran = 30
>>> temmuz = 31
>>> austos = 31
>>> eyll = 30
>>> ekim = 31
>>> kasm = 30
>>> aralk = 31

Bu deikenleri nasl bir program iinde kullanacanz tamamen sizin hayal gcnze kalm.
Mesela bu deikenleri kullanarak aylara gre doalgaz faturasn hesaplayan bir program
yazabiliriz.
Hemen son gelen doalgaz faturasn (rn. Mart ay) elimize alp inceliyoruz ve bu faturadan
u verileri elde ediyoruz:
Mart ay doalgaz faturasna gre sayatan llen hacim 346 m3 . Demek ki bir ayda toplam
346 m3 doalgaz harcamz.
Fatura tutar 273.87 TL imi. Yani 346 m3 doalgaz tketmenin bedeli 273.87 TL. Buna gre
deikenlerimizi tanmlayalm:
>>> aylk_sarfiyat = 346
>>> fatura_tutar = 273.87

Bu bilgiyi kullanarak doalgazn birim yatn hesaplayabiliriz. Formlmz yle olmal:


>>> birim_fiyat = fatura_tutar / aylk_sarfiyat

>>> birim_fiyat

0.7915317919075144

Demek ki doalgazn m3 yat (vergilerle birlikte yaklak) 0.79 TLye karlk geliyormu.
Bu noktada gnlk ortalama doalgaz saryatmz da hesaplamamz gerekiyor:
>>> gnlk_sarfiyat = aylk_sarfiyat / mart
>>> gnlk_sarfiyat

11.161290322580646

Demek ki Mart aynda gnlk ortalama 11 m3 doalgaz tketmiiz.


Btn bu bilgileri kullanarak Nisan aynda gelecek faturay tahmin edebiliriz:

44 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

>>> nisan_faturas = birim_fiyat * gnlk_sarfiyat * nisan


>>> nisan_faturas

265.03548387096777

ubat ay faturas ise yle olabilir:


>>> ubat_faturas = birim_fiyat * gnlk_sarfiyat * ubat
>>> ubat_faturas

247.36645161290326

Burada farkl deikenlerin deerini deitirerek daha baka ilemler de yapabilirsiniz.


rnein pratik olmas asndan gnlk_saryat deikeninin deerini 15 yaparak
hesaplamalarnz buna gre gncelleyebilirsiniz.
Grdnz gibi, ayn anda birden fazla deiken tanmlayabilmek ilerimizi epey
kolaylatryor.
Deikenlerle ilgili bir ipucu daha verelim...

Deikenlerin Deerini Takas Etme

Diyelim ki, iyerinizdeki personelin unvanlarn tuttuunuz bir veritaban var elinizde. Bu
veritabannda una benzer ilikiler tanml:
>>> osman = "Aratrma Gelitirme Mdr"
>>> mehmet = "Proje Sorumlusu"

lerleyen zamanda ivereniniz sizden Osman ve Mehmetin unvanlarn deitirmenizi talep


edebilir. Yani Osman Proje Sorumlusu, Mehmeti de Aratrma Gelitirme Mdr yapmanz
isteyebilir sizden.
Patronunuzun bu isteini Pythonda ok rahat bir biimde yerine getirebilirsiniz. Dikkatlice
bakn:
>>> osman, mehmet = mehmet, osman

Bylece tek hamlede bu iki kiinin unvanlarn takas etmi oldunuz. Gelin isterseniz
deikenlerin son durumuna bakalm:
>>> osman

'Proje Sorumlusu

>>> mehmet

'Aratrma Gelitirme Mdr'

Grdnz gibi, osman deikeninin deerini mehmet e; mehmet deikeninin deerini ise
osman a baaryla verebilmiiz.
Yukardaki yntem Pythonn teki diller zerinde nemli bir stnldr. Baka
programlama dillerinde bu ilemi yapmak iin geici bir deiken tanmlamanz gerekir. Yani
mesela:

5.1. Etkileimli Kabukta lk Admlar 45


Python 3 iin Trke Klavuz, Srm 3

>>> osman = "Aratrma Gelitirme Mdr"


>>> mehmet = "Proje Sorumlusu"

Elimizdeki deerler bunlar. Biz imdi Osmann deerini Mehmete; Mehmetin deerini ise
Osmana aktaracaz. Bunun iin ncelikle bir geici deiken tanmlamalyz:
>>> geici = "Proje Sorumlusu"

Bu sayede Proje Sorumlusu deerini yedeklemi olduk. Bu ilem sayesinde, takas srasnda
bu deeri kaybetmeyeceiz.
imdi Osmann deerini Mehmete aktaralm:
>>> mehmet = osman

imdi elimizde iki tane Aratrma Gelitirme Mdr olmu oldu:


>>> mehmet

'Aratrma Gelitirme Mdr'

>>> osman

'Aratrma Gelitirme Mdr'

Grdnz gibi, mehmet = osman kodunu kullanarak mehmet deikeninin deerini osman
deikeninin deeriyle deitirdiimiz iin Proje Sorumlusu deeri ortadan kayboldu. Ama
biz nceden bu deeri geici adl deikene atadmz iin bu deeri kaybetmemi olduk.
imdi Osmana geici deikeni iinde tuttuumuz Proje Sorumlusu deerini verebiliriz:
>>> osman = geici

Bylece istediimiz takas ilemini gerekletirmi olduk. Son durumu kontrol edelim:
>>> osman

'Proje Sorumlusu

>>> mehmet

'Aratrma Gelitirme Mdr'

Basit bir ilem iin ne kadar byk bir zaman kayb, deil mi? Ama dediimiz gibi, Pythonda
bu ekilde geici bir deiken atamakla uramamza hi gerek yok. Sadece u forml
kullanarak deikenlerin deerini takas edebiliriz:
a, b = b, a

Bu ekilde a deikeninin deerini b deikenine; b deikeninin deerini ise a deerine


vermi oluyoruz. Eer bu ilemi geri alp her eyi eski haline dndrmek istersek, tahmin
edebileceiniz gibi yine ayn yntemden yararlanabiliriz:
b, a = a, b

Bylece deikenler konusunu da olduka ayrntl bir ekilde incelemi olduk. Ayrca bu
esnada len() ve pow() adl iki yeni fonksiyon ile ** adl bir ile de rendik.
Hazr laf gemiken, len() fonksiyonunun baz kstlamalarndan sz edelim. Dediimiz

46 Blm 5. Etkileimli Python


Python 3 iin Trke Klavuz, Srm 3

gibi, bu fonksiyonu kullanarak karakter dizileri iinde toplam ka adet karakter bulunduunu
hesaplayabiliyoruz. rnein:
>>> kelime = "muvaffakiyet"
>>> len(kelime)

12

Yalnz bu len() fonksiyonunu saylarn uzunluunu lmek iin kullanamyoruz:


>>> len(123456)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()

Grdnz gibi, len() fonksiyonu, u ana kadar rendiimiz veri tipleri arasnda yalnzca
karakter dizileri ile birlikte kullanlabiliyor. Bu fonksiyonu saylarla birlikte kullanamyoruz.
Bu blmn banda, o anda elimizde bulunan bir verinin tipini bilmemizin ok nemli
olduunu ve Pythonda bir verinin tipinin, o veri ile neler yapp neler yapamayacanz
belirlediini sylediimizi hatrlyorsunuz, deil mi? te len() fonksiyonu bu duruma ok
gzel bir rnektir.
len() fonksiyonu saylarla birlikte kullanlamaz. Dolaysyla eer elinizdeki verinin bir say
olduunu bilmezseniz, bu sayy len() fonksiyonu ile birlikte kullanmaya alabilir ve bu
ekilde programnzn hata vererek kmesine yol aabilirsiniz.
Ayrca daha nce de sylediimiz gibi, len() fonksiyonunu doru kullanabilmek iin, bu
fonksiyonun bize say deerli bir kt verdiini de bilmemiz gerekir.
len() fonksiyonu ile ilgili bu durumu da bir kenara not ettikten sonra yolumuza kaldmz
yerden devam edelim.

5.2 Etkileimli Kabuun Hafzas

Bir nceki blmde Pythonn etkileimli kabuunun nasl kullanlacana dair epey rnek
verdik ve etkileimli kabuk zerinden Pythonn baz temel aralarna ksa bir giri yaptk.
imdi isterseniz yeri gelmiken Pythonn etkileimli kabuunun bir baka yeteneinden daha
sz edelim.
Etkileimli kabukta _ adl iaret (alt izgi iareti), yaplan son ilemin veya girilen son enin
deerini tutma ilevi grr. Yani:
>>> 2345 + 54355

56700

Eer bu ilemin ardndan _ komutunu verirsek yle bir kt alrz:


>>> _

56700

Grdnz gibi, _ komutu son girilen eyi hafzasnda tutuyor. Bu zellikten eitli
ekillerde yararlanabilirsiniz:

5.2. Etkileimli Kabuun Hafzas 47


Python 3 iin Trke Klavuz, Srm 3

>>> _ + 15

56715

Burada _ komutunun deeri bir nceki ilemin sonucu olan 56715 deeri olduu iin,
_ komutuna 15 eklediimizde 56715 deerini elde ediyoruz. _ komutunun deerini tekrar
kontrol edelim:
>>> _

56715

Grdnz gibi, _ komutunun deeri artk 56715 saysdr...


_ komutu yalnzca saylar deil, karakter dizilerini de hafzasnda tutabilir:
>>> "www"

'www'

>>> _

'www'

>>> _ + ".istihza.com"

'www.istihza.com'

Bu iaret yle ok sk kullanlan bir ara deildir, ama zaman zaman iinizi epey kolaylatrr.
Yalnz, unutmamamz gereken ey, bu zelliin sadece etkileimli kabuk ortamnda geerli
olmasdr. _ komutunun etkileimli kabuk ortam dnda herhangi bir geerlilii yoktur.
Aslnda burada sylenecek daha ok ey var. Ama biz imdilik bunlar sonraki konulara
brakacaz. Zira bu blmdeki amacmz size konularn her ayrntsn vermekten ziyade,
Pythona snmanz salamaktr.

48 Blm 5. Etkileimli Python


BLM 6

print() Fonksiyonu

Geen blmde bir yandan Pythonn etkileimli kabuunu yakndan tanyp bu vesileyle baz
nemli fonksiyon ve aralar renirken, br yandan bu rendiklerimizi kullanarak rnek
programlar yazdk. Grdnz gibi, azck bir bilgiyle dahi az ok ie yarar programlar
yazmak mmkn olabiliyor. Daha yararl programlar yazabilmek iin henz renmemiz
gereken pek ok ey var. te bu blmde, daha yararl programlar yazmamz salayacak
ok nemli bir aratan sz edeceiz. neminden dolay ayrntl bir ekilde anlatacamz bu
aracn ad print() fonksiyonu.
Elbette bu blmde sadece print() fonksiyonundan bahsetmeyeceiz. Bu blmde print()
fonksiyonunun yansra Pythondaki baz nemli temel konular da ele alacaz. Mesela bu
blmde Pythondaki karakter dizilerine ve saylara ilikin ok nemli bilgiler vereceiz. Ayrca
print() fonksiyonu vesilesiyle Pythondaki fonksiyon konusuna da salam bir giri yapm,
bu kavram ile ilgili ilk bilgilerimizi alm olacaz. Szn z, bu blm bizim iin, deyim
yerindeyse, tam anlamyla bir dnm noktas olacak.
O halde isterseniz laf daha fazla uzatmadan ie print() fonksiyonunun ne olduu ve ne ie
yaradn anlatarak balayalm.

6.1 Nedir, Ne e Yarar?

imdiye kadar etkileimli kabukta gerek karakter dizilerini gerekse saylar dorudan ekrana
yazdk. Yani yle bir ey yaptk:
>>> "Python programlama dili"

'Python programlama dili'

>>> 6567

6567

Etkileimli kabuk da, ekrana yazdmz bu karakter dizisi ve sayy dorudan bize kt
olarak verdi. Ancak ilerde Python kodlarmz bir dosyaya kaydedip altrdmzda da
greceiniz gibi, Pythonn ekrana kt verebilmesi iin yukardaki kullanm yeterli deildir.
Yani yukardaki kullanm yalnzca etkileimli kabukta alr. Bu kodlar bir dosyaya kaydedip
altrmak istediimizde hibir kt alamayz. Pythonda yazdmz eylerin ekrana kt
olarak verilebilmesi iin print() adl zel bir fonksiyondan yararlanmamz gerekir.
O halde gelin bu print() fonksiyonunun ne ie yaradn ve nasl kullanldn anlamaya
alalm:

49
Python 3 iin Trke Klavuz, Srm 3

print() de tpk daha nce grdmz type(), len() ve pow() gibi bir fonksiyondur.
Fonksiyonlar ilerde daha ayrntl bir ekilde inceleyeceimizi sylemitik hatrlarsanz. O
yzden fonksiyon kelimesine taklarak, burada anlattmz eylerin kafanz kartrmasna,
moralinizi bozmasna izin vermeyin.
print() fonksiyonunun grevi ekrana kt vermemizi salamaktr. Hemen bununla ilgili bir
rnek verelim:
>>> print("Python programlama dili")

Python programlama dili

Bildiiniz gibi burada grdmz Python programlama dili bir karakter dizisidir. te
print() fonksiyonunun grevi bu karakter dizisini ekrana kt olarak vermektir. Peki
bu karakter dizisini print() fonksiyonu olmadan yazdmzda da ekrana kt vermi
olmuyor muyuz? Aslnda olmuyoruz. Dediimiz gibi, ilerde programlarmz dosyalara
kaydedip altrdmzda, banda print() olmayan ifadelerin ktda grnmediine ahit
olacaksnz.
Daha nce de dediimiz gibi, etkileimli kabuk bir test ortam olmas asndan rahat bir
ortamdr. Bu sebeple bu ortamda ekrana kt verebilmek iin print() fonksiyonunu
kullanmak zorunda deilsiniz. Yani banda print() olsa da olmasa da etkileimli kabuk
ekrana yazdrmak istediiniz eyi yazdrr. Ama iyi bir alkanlk olmas asndan, ekrana
herhangi bir ey yazdracanzda ben size print() fonksiyonunu kullanmanz tavsiye
ederim.
print() son derece gl bir fonksiyondur. Gelin isterseniz bu gl ve faydal fonksiyonu
derin derin incelemeye koyulalm.

6.2 Nasl Kullanlr?

Yukarda verdiimiz rnekte ilk gzmze arpan ey, karakter dizisini print()
fonksiyonunun parantezleri iine yazm olmamzdr. Biz bir fonksiyonun parantezleri iinde
belirtilen elere parametre dendiini geen blmde renmitik. Tpk rendiimiz teki
fonksiyonlar gibi, print() fonksiyonu da birtakm parametreler alr.
Bu arada print() fonksiyonunun parantezini ap parametreyi yazdktan sonra, parantezi
kapatmay unutmuyoruz. Python programlama diline yeni balayanlarn, hatta bazen
deneyimli programclarn bile en sk yapt hatalardan biri atklar parantezi kapatmay
unutmalardr.
Elbette, eer istersek burada dorudan Python programlama dili adl karakter dizisini
kullanmak yerine, nce bu karakter dizisini bir deikene atayp, sonra da print()
fonksiyonunun parantezleri iinde bu deikeni kullanabiliriz. Yani:
>>> dil = "Python programlama dili"
>>> print(dil)

Python programlama dili

Bu arada, hem imdi verdiimiz, hem de daha nce yazdmz rneklerde bir ey dikkatinizi
ekmi olmal. imdiye kadar verdiimiz rneklerde karakter dizilerini hep ift trnakla
gsterdik. Ama aslnda tek seeneimiz ift trnak deildir. Python bize farkl trnak
seenei sunar:

50 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

1. Tek trnak ( )
2. ift trnak ( )
3. trnak ( )
Dolaysyla yukardaki rnei farkl ekilde yazabiliriz:
>>> print('Python programlama dili')

Python programlama dili

>>> print("Python programlama dili")

Python programlama dili

>>> print("""Python programlama dili""")

Python programlama dili

Grdnz gibi ktlar arasnda hibir fark yok.


Peki ktlarda hibir fark yoksa neden farkl trnak eidi var?
sterseniz bu soruyu bir rnek zerinden aklamaya alalm. Diyelim ki ekrana yle bir
kt vermek istiyoruz:
Python programlama dilinin ad "piton" ylanndan gelmez

Eer bu cmleyi ift trnaklar iinde gsterirsek programmz hata verecektir:


>>> print("Python programlama dilinin ad "piton" ylanndan gelmez")

File "<stdin>", line 1


print("Python programlama dilinin ad "piton" ylanndan gelmez")
^
SyntaxError: invalid syntax

Bunun sebebi, cmle iinde geen piton kelimesinin de ift trnaklar iinde gsterilmi
olmasdr. Cmlenin, yani karakter dizisinin kendisi de ift trnak iinde gsterildii iin
Python, karakter dizisini balatan ve bitiren trnaklarn hangisi olduunu ayrt edemiyor.
Yukardaki cmleyi en kolay u ekilde ekrana yazdrabiliriz:
>>> print('Python programlama dilinin ad "piton" ylanndan gelmez')

Python programlama dilinin ad "piton" ylanndan gelmez

Burada karakter dizisini tek trnak iine aldk. Karakter dizisi iinde geen piton kelimesi
ift trnak iinde olduu iin, karakter dizisini balatp bitiren trnaklarla piton kelimesindeki
trnaklarn birbirine karmas gibi bir durum sz konusu deildir.
Bir de yle bir rnek verelim: Diyelim ki aadaki gibi bir kt elde etmek istiyoruz:
stanbul'un 5 gnlk hava durumu tahmini

Eer bu karakter dizisini tek trnak iaretleri iinde belirtirseniz Python size bir hata mesaj
gsterecektir:

6.2. Nasl Kullanlr? 51


Python 3 iin Trke Klavuz, Srm 3

>>> print('stanbul'un 5 gnlk hava durumu tahmini')

File "<stdin>", line 1


print('stanbul'un 5 gnlk hava durumu tahmini')
^
SyntaxError: invalid syntax

Bu hatann sebebi stanbulun kelimesi iinde geen kesme iaretidir. Tpk bir nceki
rnekte olduu gibi, Python karakter dizisini balatan ve bitiren trnaklarn hangisi olduunu
kestiremiyor. Python, karakter dizisinin en bandaki tek trnak iaretinin ardndan
stanbulun kelimesi iindeki kesme iaretini grnce karakter dizisinin burada sona erdiini
zannediyor. Ancak karakter dizisini soldan saa doru okumaya devam edince bir yerlerde
bir terslik olduunu dnyor ve bize bir hata mesaj gstermekten baka aresi kalmyor.
Yukardaki karakter dizisini en kolay yle tanmlayabiliriz:
>>> print("stanbul'un 5 gnlk hava durumu tahmini")

stanbul'un 5 gnlk hava durumu tahmini

Burada da, karakter dizisi iinde geen kesme iaretine taklmamak iin karakter dizimizi ift
trnak iaretleri iine alyoruz.
Yukardaki karakter dizilerini dzgn bir ekilde kt verebilmek iin trnak iaretlerinden
de yararlanabiliriz:
>>> print("""Python programlama dilinin ad "piton" ylanndan gelmez""")

Python programlama dilinin ad "piton" ylanndan gelmez

>>> print("""stanbul'un 5 gnlk hava durumu tahmini""")

stanbul'un 5 gnlk hava durumu tahmini

Btn bu rneklerden sonra kafanzda yle bir dnce uyanm olabilir:


Grne gre trnak iaretiyle her trl karakter dizisini hatasz bir ekilde
ekrana kt olarak verebiliyoruz. O zaman ben en iyisi btn karakter dizileri iin
trnak iaretini kullanaym!
Elbette, eer isterseniz pek ok karakter dizisi iin trnak iaretini kullanabilirsiniz.
Ancak Pythonda karakter dizileri tanmlanrken genellikle tek trnak veya ift trnak iaretleri
kullanlr. trnak iaretlerinin asl kullanm yeri ise farkldr. Peki nedir bu trnak
iaretlerinin asl kullanm yeri?
trnak iaretlerini her trl karakter dizisiyle birlikte kullanabiliyor olsak da, bu trnak
tipi ounlukla sadece birden fazla satra yaylm karakter dizilerini tanmlamada kullanlr.
rnein yle bir ekran kts vermek istediinizi dnn:
[H]=========HARMAN========[-][o][x]
| |
| Programa Hogeldiniz! |
| Srm 0.8 |
| Devam etmek iin herhangi |
| bir dmeye basn. |
| |
|=================================|

52 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

Byle bir kt verebilmek iin eer tek veya ift trnak kullanmaya kalkrsanz epey eziyet
ekersiniz. Bu tr bir kt vermenin en kolay yolu trnaklar kullanmaktr:
>>> print("""
... [H]=========HARMAN========[-][o][x]
... | |
... | Programa Hogeldiniz! |
... | Srm 0.8 |
... | Devam etmek iin herhangi |
... | bir dmeye basn. |
... | |
... |=================================|
... """)

Burada baz eyler dikkatinizi ekmi olmal. Grdnz gibi, trnakl yap teki trnak
tiplerine gre biraz farkl davranyor. imdi u rnee bakn:
>>> print("""Game Over!
...

Buraya ok dikkatli bakn. Karakter dizisine trnakla baladktan sonra, kapan trnan
koymadan Enter tuuna bastmzda >>> iareti ... iaretine dnt. Python bu ekilde
bize, yazmaya devam et! demi oluyor. Biz de buna uyarak yazmaya devam edelim:
>>> print("""Game Over!
... Insert Coin!""")

Game Over!
Insert Coin!

Kapan trna koyulmadan Enter tuuna basldnda >>> iaretinin ... iaretine dnmesi
trnaa zg bir durumdur. Eer ayn eyi tek veya ift trnaklarla yapmaya alrsanz
programnz hata verir:
>>> print("Game Over!

File "<stdin>", line 1


print("Game Over!
^
SyntaxError: EOL while scanning string literal

...veya:
>>> print('Game Over!

File "<stdin>", line 1


print("Game Over!
^
SyntaxError: EOL while scanning string literal

trnak iaretlerinin trnak kapanmadan Enter tuuna basldnda hata vermeme zellii
sayesinde, bu trnak tipi zellikle birden fazla satra yaylm karakter dizilerinin gsterilmesi
iin birebirdir.
Gelin isterseniz trnak kullanmna ilikin bir rnek daha verelim:
>>> print("""Python programlama dili Guido Van Rossum
... adl Hollandal bir programc tarafndan 90l

6.2. Nasl Kullanlr? 53


Python 3 iin Trke Klavuz, Srm 3

... yllarn banda gelitirilmeye balanmtr. ou


... insan, isminin "Python" olmasna bakarak, bu programlama
... dilinin, adn piton ylanndan aldn dnr.
... Ancak zannedildiinin aksine bu programlama dilinin
... ad piton ylanndan gelmez.""")

Python programlama dili Guido Van Rossum


adl Hollandal bir programc tarafndan 90'l
yllarn banda gelitirilmeye balanmtr. ou
insan, isminin "Python" olmasna bakarak, bu programlama
dilinin, adn piton ylanndan aldn dnr.
Ancak zannedildiinin aksine bu programlama dilinin
d piton ylanndan gelmez.

Elbette eer istersek bu metni nce bir deikene atamay da tercih edebiliriz:
>>> python_hakkinda = """Python programlama dili Guido Van Rossum
... adl Hollandal bir programc tarafndan 90l
... yllarn banda gelitirilmeye balanmtr. ou
... insan, isminin "Python" olmasna bakarak, bu programlama
... dilinin, adn piton ylanndan aldn dnr.
... Ancak zannedildiinin aksine bu programlama dilinin
... ad piton ylanndan gelmez."""
>>> print(python_hakkinda)

Python programlama dili Guido Van Rossum


adl Hollandal bir programc tarafndan 90'l
yllarn banda gelitirilmeye balanmtr. ou
insan, isminin "Python" olmasna bakarak, bu programlama
dilinin, adn piton ylanndan aldn dnr.
Ancak zannedildiinin aksine bu programlama dilinin
d piton ylanndan gelmez.

Siz yukardaki kty tek veya ift trnak kullanarak nasl ekrana yazdrabileceinizi
dnedurun, biz nemli bir konuya gei yapalm!

6.3 Bir Fonksiyon Olarak print()

print() ifadesinin bir fonksiyon olduunu sylemitik hatrlarsanz. Dediimiz gibi,


fonksiyonlarla ilgili ayrntl aklamalar ilerleyen derslerde vereceiz. Ancak imdi dilerseniz
bundan sonra anlatacaklarmz daha iyi kavrayabilmemiz iin, fonksiyonlar hakknda
bilmemiz gereken baz temel eyleri renmeye alalm.
Grdnz gibi, print() fonksiyonunu yle kullanyoruz:
>>> print("Aramak istediiniz kelimeyi yazn: ")

Burada print() bir fonksiyon, Aramak istediiniz kelimeyi yazn: adl karakter dizisi ise bu
fonksiyonun parametresidir. Daha nce len() adl baka bir fonksiyon daha renmitik
hatrlarsanz. Onu da yle kullanyorduk:
>>> len("elma")

Burada da len() bir fonksiyon, elma adl karakter dizisi ise bu fonksiyonun parametresidir.
Aslnda biim olarak print() ve len() fonksiyonlarnn birbirinden hibir fark olmadn

54 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

gryorsunuz.
Daha nce sylediimiz ve bu rneklerden de anladmz gibi, bir fonksiyonun parantezleri
iinde belirtilen elere parametre ad veriliyor. Mesela aadaki rnekte print()
fonksiyonunu tek bir parametre ile kullanyoruz:
>>> print('En az 8 haneli bir parola belirleyin.')

print() fonksiyonu, tpk pow() fonksiyonu gibi, birden fazla parametre alabilir:

>>> print('Frat', 'zgl')

Frat zgl

Bu rnekte bizim iin karlacak ok dersler var. Bir defa burada print() fonksiyonunu iki
farkl parametre ile birlikte kullandk. Bunlardan ilki Frat adl bir karakter dizisi, ikincisi ise
zgl adl baka bir karakter dizisi. Pythonn bu iki karakter dizisini nasl birletirdiine dikkat
edin. print() fonksiyonu bu iki karakter dizisini kt olarak verirken aralarna da birer boluk
yerletirdi. Ayrca, geen derste de vurguladmz gibi, parametrelerin birbirinden virgl ile
ayrldn da gzden karmyoruz.
Gelin bununla ilgili bir iki rnek daha verelim elimizin almas iin:
>>> print("Python", "Programlama", "Dili")

Python Programlama Dili

>>> print('Frat', 'zgl', 'Adana', 1980)

Frat zgl Adana 1980

Bu arada dikkatinizi nemli bir noktaya ekmek istiyorum. Yukardaki rneklerde bazen tek
trnak, bazen de ift trnak kullandk. Daha nce de sylediimiz gibi, hangi trnak tipini
kullandmz nemli deildir. Python hangi trnak tipini kullandmzdan ziyade, trnak
kullanmnda tutarl olup olmadmzla ilgilenir. Yani Python iin nemli olan, karakter
dizisini hangi trnakla balatmsak, o trnakla bitirmemizdir. Yani u tip kullanmlar geerli
deildir:
>>> print("karakter dizisi')

>>> print('karakter dizisi")

Karakter dizisini tanmlamaya balarken kullandmz trnak tipi ile karakter dizisini
tanmlamay bitirirken kullandmz trnak tipi birbirinden farkl olduu iin bu iki kullanm
da hata verecektir.

6.4 print() Fonksiyonunun Parametreleri

imdiye kadar verdiimiz rneklerde belki ok da belli olmuyordur, ama aslnda print()
fonksiyonu son derece gl bir aratr. te imdi biz bu fonksiyonun gcn gzler
nne seren zelliklerini incelemeye balayacaz. Bu blm dikkatle takip etmeniz, ilerde
yapacamz almalar daha rahat anlayabilmeniz asndan byk nem tar.

6.4. print() Fonksiyonunun Parametreleri 55


Python 3 iin Trke Klavuz, Srm 3

6.4.1 sep

print() fonksiyonu ile ilgili olarak yukarda verdiimiz rnekleri incelediimizde, bu


fonksiyonun kendine zg bir davran ekli olduunu gryoruz. Mesela bir nceki blmde
verdiimiz u rnee bakalm:

>>> print('Frat', 'zgl')

Frat zgl

Burada print() fonksiyonunu iki farkl parametre ile birlikte kullandk. Bu fonksiyon,
kendisine verdiimiz bu parametreleri belli bir dzene gre birbiriyle birletirdi. Bu dzen
gereince print(), kendisine verilen parametreleri birletirirken, parametreler arasna bir
boluk yerletiriyor. Bunu daha net grmek iin yle bir rnek daha verelim:
>>> print("Python", "PHP", "C++", "C", "Erlang")

Python PHP C++ C Erlang

Grdnz gibi, print() fonksiyonu gerekten de, kendisine verilen parametreleri


birletirirken, parametrelerin her biri arasna bir boluk yerletiriyor. Halbuki bu boluu
biz talep etmedik! Python bize bu boluu eantiyon olarak verdi. ou durumda istediimiz
ey bu olacaktr, ama baz durumlarda bu boluu istemeyebiliriz. rnein:
>>> print("http://", "www.", "istihza.", "com")

http:// www. istihza. com

Ya da boluk karakteri yerine daha farkl bir karakter kullanmak istiyor da olabiliriz. Peki byle
bir durumda ne yapmamz gerekir?
te bu noktada baz zel aralardan yararlanarak print() fonksiyonunun ntanml davran
kalplar zerinde deiiklikler yapabiliriz.
Peki nedir print() fonksiyonunu zelletirmemizi salayacak bu aralar?
Hatrlarsanz, Pythonda fonksiyonlarn parantezleri iindeki deerlere parametre ad
verildiini sylemitik. Mesela print() fonksiyonunu bir ya da daha fazla parametre ile
birlikte kullanabileceimizi biliyoruz:

>>> print("Mehmet", "z", "stanbul", "amlca", 156, "/", 45)

Mehmet z stanbul amlca 156 / 45

print() fonksiyonu iinde istediimiz sayda karakter dizisi ve/veya say deerli parametre
kullanabiliriz.
Fonksiyonlarn bir de daha zel grnml parametreleri vardr. Mesela print()
fonksiyonunun sep adl zel bir parametresi bulunur. Bu parametre print() fonksiyonunda
grnmese bile her zaman oradadr. Yani diyelim ki yle bir kod yazdk:
>>> print("http://", "www.", "google.", "com")

Burada herhangi bir sep parametresi grmyoruz. Ancak Python yukardaki kodu aslnda
yle alglar:

56 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

>>> print("http://", "www.", "google.", "com", sep=" ")

sep ifadesi, ngilizcede separator (ayrc, ayra) kelimesinin ksaltmasdr. Dolaysyla


print() fonksiyonundaki bu sep parametresi, ekrana baslacak eler arasna hangi
karakterin yerletirileceini gsterir. Bu parametrenin ntanml deeri bir adet boluk
karakteridir ( ). Yani siz bu zel parametrenin deerini baka bir eyle deitirmezseniz,
Python bu parametrenin deerini bir adet boluk karakteri olarak alacak ve ekrana baslacak
eleri birbirinden birer bolukla ayracaktr. Ancak eer biz istersek bu sep parametresinin
deerini deitirebiliriz. Bylece Python, karakter dizilerini birletirirken araya boluk deil,
bizim istediimiz baka bir karakteri yerletirebilir. Gelin imdi bu parametrenin deerini
nasl deitireceimizi grelim:
>>> print("http://", "www.", "istihza.", "com", sep="")

http://www.istihza.com

Grdnz gibi, karakter dizilerini baaryla birletirip, geerli bir internet adresi elde ettik.
Burada yaptmz ey aslnda ok basit. Sadece sep parametresinin bir adet boluk karakteri
olan ntanml deerini silip, yerine bo bir karakter dizisi deerini yazdk. Bu iki kavramn
birbirinden farkl olduunu sylediimizi hatrlyorsunuz, deil mi?
Gelin bir rnek daha yapalm:
>>> print("T", "C", sep=".")

T.C

Burada Pythona yle bir emir vermi olduk:


T ve C karakter dizilerini birbiriyle birletir! Bunu yaparken de bu karakter
dizilerinin arasna nokta iareti yerletir!
sep parametresinin teki parametrelerden fark her zaman ismiyle birlikte kullanlmasdr.
Zaten teknik olarak da bu tr parametrelere isimli parametreler ad verilir. rnein:
>>> print("Adana", "Mersin", sep="-")

Adana-Mersin

Eer burada sep parametresinin ismini belirtmeden, dorudan parametrenin deerini


yazarsak, bu deerin teki parametrelerden hibir fark kalmayacaktr:
>>> print("Adana", "Mersin", "-")

Adana Mersin -

Gelin isterseniz bu parametreyle ilgili bir rnek daha yapalm:


Bir mumdur iki mumdur... diye balayan trky biliyorsunuzdur. imdi bu trky
Pythonla nasl yazabileceimizi grelim!
>>> print("bir", "iki", "", "drt", "on drt", sep="mumdur")

birmumdurikimumdurmumdurdrtmumduron drt

Burada bir terslik olduu ak! Karakter dizileri birbirlerine skk dzende birletirildi.
Bunlarn arasnda birer boluk olsa tabii daha iyi olurdu. Ancak biliyorsunuz sep

6.4. print() Fonksiyonunun Parametreleri 57


Python 3 iin Trke Klavuz, Srm 3

parametresinin ntanml deerini silip, yerine mumdur deerini yerletirdiimiz iin,


Pythonn otomatik olarak yerletirdii boluk karakteri kayboldu. Ama eer istersek o boluk
karakterlerini kendimiz de ayarlayabiliriz:
>>> print("bir", "iki", "", "drt", "on drt", sep=" mumdur ")

bir mumdur iki mumdur mumdur drt mumdur on drt

Grdnz gibi, sep parametresine verdiimiz mumdur deerinin sanda ve solunda


birer boluk brakarak sorunumuzu zebildik. Bu sorunu zmenin baka bir yolu daha
var. Hatrlarsanz etkileimli kabukta ilk rneklerimizi verirken karakter dizilerini birletirmek
iin + iaretinden de yararlanabileceimizi sylemitik. Dolaysyla sep parametresini yle
de yazabiliriz:
>>> print("bir", "iki", "", "drt", "on drt", sep=" " + "mumdur" + " ")

Burada da, mumdur adl karakter dizisinin banda ve sonunda birer boluk brakmak
yerine, gerekli boluklar + iareti yardmyla bu karakter dizisine birletirdik. Hatta istersek +
ilecini kullanmak zorunda olmadmz dahi biliyorsunuz:
>>> print("bir", "iki", "", "drt", "on drt", sep=" " "mumdur" " ")

Ama grdnz gibi bir problemimiz daha var. Trknn szleri u ekilde olmalyd:
bir mumdur iki mumdur mumdur drt mumdur on drt mumdur
Ama sondaki mumdur kelimesi yukardaki ktda yok. Normal olan da bu aslnda. sep
parametresi, karakter dizilerinin arasna bir deer yerletirir. Karakter dizilerinin son tarafyla
ilgilenmez. Bu i iin print() fonksiyonu baka bir parametreye sahiptir.
Bu arada, yukardaki rneklerde hep karakter dizilerini kullanm olmamz sizi yanltmasn.
sep parametresi yalnzca karakter dizilerinin deil saylarn arasna da istediiniz bir deerin
yerletirilmesini salayabilir. Mesela:
>>> print(1, 2, 3, 4, 5, sep="-")

1-2-3-4-5

Ancak sep parametresine deer olarak yalnzca karakter dizilerini ve None adl zel bir
szc verebiliriz. (None szcnden ileride sz edeceiz):
>>> print(1, 2, 3, 4, 5, sep=0)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: sep must be None or a string, not int

Grdnz gibi, sep parametresine bir say olan 0 deerini veremiyoruz.


Peki bu parametreye None deeri verirsek ne olur? Bu parametreye None deeri
verildiinde, print() fonksiyonu bu parametre iin ntanml deeri (yani bir adet boluk)
kullanr:
>>> print('a', 'b', sep=None)

a b

58 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

Eer amacnz parametreleri birbirine bititirmekse, yani sep parametresinin ntanml deeri
olan boluk karakterini ortadan kaldrmaksa, sep parametresine bo bir karakter dizisi
vermeniz gerektiini biliyorsunuz:
>>> print('a', 'b', sep='')

ab

print() fonksiyonunun sep parametresini btn ayrntlaryla incelediimize gre, bu


fonksiyonun bir baka zel parametresinden sz edebiliriz.

6.4.2 end

Bir nceki blmde yle bir laf etmitik:


print() fonksiyonun sep adl zel bir parametresi bulunur. Bu parametre
print() fonksiyonunda grnmese bile her zaman oradadr.
Ayn bu ekilde, print() fonksiyonunun end adl zel bir parametresi daha bulunur. Tpk
sep parametresi gibi, end parametresi de print() fonksiyonunda grnmese bile her zaman
oradadr.
Bildiiniz gibi, sep parametresi print() fonksiyonuna verilen parametreler birletirilirken
araya hangi karakterin gireceini belirliyordu. end parametresi ise bu parametrelerin sonuna
neyin geleceini belirler.
print() fonksiyonu ntanml olarak, parametrelerin sonuna satr ba karakteri ekler. Peki
bu satr ba karakteri (veya yeni satr karakteri) denen ey de ne oluyor?
Dilerseniz bunu bir rnek zerinde grelim.
yle bir kodumuz olsun:
>>> print("Pardus ve Ubuntu birer GNU/Linux datmdr.")

Bu kodu yazp Enter tuuna bastmz anda print() fonksiyonu iki farkl ilem gerekletirir:
1. ncelikle karakter dizisini ekrana yazdrr.
2. Ardndan bir alt satra geip bize >>> iaretini gsterir.
te bu ikinci ilem, karakter dizisinin sonunda bir adet satr ba karakteri olmasndan,
daha dorusu print() fonksiyonunun, satr ba karakterini karakter dizisinin sonuna
eklemesinden kaynaklanr. Bu aklama biraz kafa kartrc gelmi olabilir. O halde biraz
daha aklayalm. u rnee bakn:
>>> print("Pardus\nUbuntu")

Pardus
Ubuntu

Burada Pardus ve Ubuntu karakter dizilerinin tam ortasnda ok zel bir karakter dizisi
daha gryorsunuz. Bu karakter dizisi udur: \n. te bu zel karakter dizisine satr ba
karakteri (newline ) ad verilir. Bu karakterin grevi, karakter dizisini, bulunduu noktadan
blp, karakter dizisinin geri kalann bir alt satra geirmektir. Zaten ktda da bu ilevi
yerine getirdiini gryorsunuz. Karakter dizisi Pardus ksmndan sonra ikiye blnyor ve
bu karakter dizisinin geri kalan ksm olan Ubuntu karakter dizisi bir alt satra yazdrlyor.
Bunu daha iyi anlamak iin bir rnek daha verelim:

6.4. print() Fonksiyonunun Parametreleri 59


Python 3 iin Trke Klavuz, Srm 3

>>> print("birinci satr\nikinci satr\nnc satr")

birinci satr
ikinci satr
nc satr

Peki size bir soru soraym: Acaba yukardaki kodlar daha verimli bir ekilde nasl yazabiliriz?
Evet, doru tahmin ettiniz... Tabii ki sep parametresini kullanarak:
>>> print("birinci satr", "ikinci satr", "nc satr", sep="\n")

birinci satr
ikinci satr
nc satr

Burada yaptmz ey ok basit. sep parametresinin deerini \n, yani yeni satr karakteri
(veya satr ba karakteri) olarak deitirdik. Bylece karakter dizileri arasna birer \n karakteri
yerletirerek her bir karakter dizisinin farkl satra yazdrlmasn saladk.
te end parametresinin ntanml deeri de bu \n karakteridir ve bu parametre print()
fonksiyonunda grnmese bile her zaman oradadr.
Yani diyelim ki yle bir kod yazdk:
>>> print("Bugn gnlerden Sal")

Burada herhangi bir end parametresi grmyoruz. Ancak Python yukardaki kodu aslnda
yle alglar:
>>> print("Bugn gnlerden Sal", end="\n")

Biraz nce de dediimiz gibi, bu kodu yazp Enter tuuna bastmz anda print() fonksiyonu
iki farkl ilem gerekletirir:
1. ncelikle karakter dizisini ekrana yazdrr.
2. Ardndan bir alt satra geip bize >>> iaretini gsterir.
Bunun ne demek olduunu anlamak iin end parametresinin deerini deitirmemiz yeterli
olacaktr:
>>> print("Bugn gnlerden Sal", end=".")

Bugn gnlerden Sal.>>>

Grdnz gibi, end parametresinin ntanml deeri olan \n karakterini silip yerine .
(nokta) iareti koyduumuz iin, komutu yazp Enter tuuna bastmzda print() fonksiyonu
satr bana gemedi. Yeni satra geebilmek iin Enter tuuna kendimiz basmalyz. Elbette,
eer yukardaki kodlar yle yazarsanz, print() fonksiyonu hem karakter dizisinin sonuna
nokta ekleyecek, hem de satr bana geecektir:
>>> print("Bugn gnlerden Sal", end=".\n")

Bugn gnlerden Sal.

imdi bu rendiklerimizi trkmze uygulayalm:

60 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

>>> print("bir", "iki", "", "drt", "on drt",


... sep=" mumdur ", end=" mumdur\n")

Not: Burada kodlarmzn saa doru irkin bir ekilde uzamasn engellemek iin on drt
karakter dizisini yazp virgl koyduktan sonra Enter tuuna basarak bir alt satra getik.
Bir alt satra getiimizde >>> iaretinin ... iaretine dntne dikkat edin. Pythonda
doru kod yazmak kadar, yazdmz kodlarn dzgn grnmesi de nemlidir. O yzden
yazdmz her bir kod satrnn mmkn olduunca 79 karakteri gememesini salamalyz.
Eer yazdnz bir satr 79 karakteri ayorsa, aan ksm yukarda gsterdiimiz ekilde alt
satra alabilirsiniz.

end parametresi de, tpk sep parametresi gibi, her zaman ismiyle birlikte kullanlmas
gereken bir parametredir. Yani eer end parametresinin ismini belirtmeden sadece deerini
kullanmaya alrsak Python ne yapmaya altmz anlayamaz.
Yine tpk sep parametresi gibi, end parametresinin deeri de sadece bir karakter dizisi veya
None olabilir:
>>> print(1, 2, 3, 4, 5, end=0)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: end must be None or a string, not int

Grdnz gibi, end parametresine bir say olan 0 deerini veremiyoruz.


Eer bu parametreye None deeri verirsek, tpk sep parametresinde olduu gibi, print()
fonksiyonu bu parametre iin ntanml deeri (yani satr ba karakteri) kullanr:
>>> print('a', 'b', end=None)

a b

Eer amacnz yeni satra geilmesini engellemekse, yani end parametresinin ntanml
deeri olan \n ka dizisini ortadan kaldrmaksa, end parametresine bo bir karakter dizisi
vermelisiniz:
>>> print('a', 'b', end='')

a b>>>

6.4.3 le

Not: Burada henz renmediimiz baz eyler greceksiniz. Hi endie etmeyin. Bunlar
ilerde btn ayrntlaryla reneceiz. imdilik konu hakknda biraz olsun kir sahibi
olmanz salayabilirsek kendimizi baarl sayacaz.

print() fonksiyonunun sep ve end dnda nc bir zel parametresi daha bulunur. Bu
parametrenin ad le dr. Grevi ise, print() fonksiyonuna verilen karakter dizisi ve/veya
saylarn, yani parametrelerin nereye yazlacan belirtmektir.
Bu parametrenin ntanml deeri sys.stdout tur. Peki bu ne anlama geliyor? sys.stdout,
standart kt konumu anlamna gelir. Peki standart kt konumu ne demek?

6.4. print() Fonksiyonunun Parametreleri 61


Python 3 iin Trke Klavuz, Srm 3

Standart kt konumu; bir programn, rettii ktlar verdii yerdir. Aslnda bu kavramn ne
demek olduu adndan da anlalyor:
standart kt konumu = ktlarn standart olarak verildii konum.
Mesela Python ntanml olarak, rettii ktlar ekrana verir. Eer o anda etkileimli kabukta
alyorsanz, Python rettii ktlar etkileimli kabuk zerinde gsterir. Eer yazdnz
bir program komut satrnda altryorsanz, retilen ktlar komut satrnda grnr.
Dolaysyla Pythonn standart kt konumu etkileimli kabuk veya komut satrdr. Yani
print() fonksiyonu yardmyla bastnz ktlar etkileimli kabukta ya da komut satrnda
grnecektir.
imdi bu konuyu daha iyi anlayabilmek iin birka rnek yapalm.
Normal artlar altnda print() fonksiyonunun ktsn etkileimli kabukta grrz:
>>> print("Ben Python, Monty Python!")

Ben Python, Monty Python!

Ama eer istersek print() fonksiyonunun, ktlarn ekrana deil, bir dosyaya yazdrmasn
da salayabiliriz. Mesela biz imdi print() fonksiyonunun deneme.txt adl bir dosyaya kt
vermesini salayalm.
Bunun iin srasyla u kodlar yazalm:
>>> dosya = open("deneme.txt", "w")
>>> print("Ben Python, Monty Python!", file=dosya)
>>> dosya.close()

Herhangi bir kt almadnz, deil mi? Evet. nk yazdmz bu kodlar sayesinde print()
fonksiyonu, ktlarn deneme.txt adl bir dosyaya yazdrd.
Gelin isterseniz yukardaki kodlar satr satr inceleyelim:
1. ncelikle deneme.txt adl bir dosya oluturduk ve bu dosyay dosya adl bir deikene
atadk. Burada kullandmz open() fonksiyonuna ok taklmayn. Bunu birka blm sonra
inceleyeceiz. Biz imdilik bu ekilde dosya oluturulduunu bilelim yeter. Bu arada open
fonksiyonunun da biim olarak type(), len(), pow() ve print() fonksiyonlarna ne kadar
benzediine dikkat edin. Grdnz gibi open() fonksiyonu da tpk type(), len(), pow()
ve print() fonksiyonlar gibi birtakm parametreler alyor. Bu fonksiyonun ilk parametresi
deneme.txt adl bir karakter dizisi. te bu karakter dizisi bizim oluturmak istediimiz
dosyann adn gsteriyor. kinci parametre ise w adl baka bir karakter dizisi. Bu da
deneme.txt dosyasnn yazma kipinde (modunda) alacan gsteriyor. Ama dediim gibi,
siz imdilik bu ayrntlara fazla taklmayn. lerleyen derslerde, bu konular adnz bilir gibi
bileceinizden emin olabilirsiniz.
2. Oluturduumuz bu deneme.txt adl dosya, o anda bulunduunuz dizin iinde oluacaktr.
Bu dizinin hangisi olduunu renmek iin u komutlar verebilirsiniz:
>>> import os
>>> os.getcwd()

Bu komutun ktsnda hangi dizinin ad grnyorsa, deneme.txt dosyas da o dizinin


iindedir. Mesela bendeki kt /home/istihza /Desktop. Demek ki oluturduum deneme.txt
adl dosya masastndeymi. Ben bu komutlar Ubuntu zerinde verdim. Eer Windows
zerinde verseydim una benzer bir kt alacaktm: C:\Users\istihza \Desktop

62 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

3. Ardndan da normal bir ekilde print() fonksiyonumuzu altrdk. Ama grdnz gibi
print() fonksiyonu bize herhangi bir kt vermedi. nk, daha nce de sylediimiz gibi,
print() fonksiyonunu biz ekrana deil, dosyaya kt verecek ekilde ayarladk. Bu ilemi, le
adl bir parametreye, biraz nce tanmladmz dosya deikenini yazarak yaptk.
4. Son komut yardmyla da, yaptmz deiikliklerin dosyada grnebilmesi iin ilk bata
atmz dosyay kapatyoruz.
imdi deneme.txt adl dosyay an. Biraz nce print() fonksiyonuyla yazdrdmz Ben
Python, Monty Python! karakter dizisinin dosyaya ilenmi olduunu greceksiniz.
Bylece print() fonksiyonunun standart kt konumunu deitirmi olduk. Yani print()
fonksiyonunun le adl parametresine farkl bir deer vererek, print() fonksiyonunun
etkileimli kabua deil dosyaya yazmasn saladk.
Tpk sep ve end parametreleri gibi, le parametresi de, siz grmeseniz bile her zaman
print() fonksiyonunun iinde vardr. Yani diyelim ki yle bir komut verdik:
>>> print("Tahir olmak da ayp deil", "Zhre olmak da")

Python bu komutu yle alglar:


>>> print("Tahir olmak da ayp deil", "Zhre olmak da",
... sep=" ", end="\n", file=sys.stdout)

Yani kendisine parametre olarak verilen deerleri ekrana yazdrrken srasyla u ilemleri
gerekletirir:
1. Parametrelerin arasna birer boluk koyar (sep=" "),
2. Ekrana yazdrma ilemi bittikten sonra parametrelerin sonuna satr ba karakteri ekler
(end="\n")
3. Bu kty standart kt konumuna gnderir (file=sys.stdout).
te biz burada le parametresinin deeri olan standart kt konumuna baka bir deer
vererek bu konumu deitiriyoruz.
Gelin isterseniz bununla ilgili bir rnek daha yapalm. Mesela kiisel bilgilerimizi bir dosyaya
kaydedelim. ncelikle bilgileri kaydedeceimiz dosyay oluturalm:
>>> f = open("kiisel_bilgiler.txt", "w")

Bu kodlarla, kiisel_bilgiler.txt adn tayan bir dosyay yazma kipinde (w ) am ve bu dosyay


f adl bir deikene atam olduk. imdi bilgileri yazmaya balayabiliriz:

>>> print("Frat zgl", file=f)


>>> print("Adana", file=f)
>>> print("Ubuntu", file=f)

imiz bittiinde dosyay kapatmay unutmuyoruz. Bylece btn bilgiler dosyaya yazlm
oluyor:
>>> f.close()

Oluturduumuz kiisel_bilgiler.txt adl dosyay atmzda, print() fonksiyonuna verdiimiz


parametrelerin dosyaya yazdrldn gryoruz.

6.4. print() Fonksiyonunun Parametreleri 63


Python 3 iin Trke Klavuz, Srm 3

En bata da sylediim gibi, bu blmde henz renmediimiz baz eylerle karlatk. Eer
yukarda verilen rnekleri anlamakta zorlandysanz hi endie etmenize gerek yok. Birka
blm sonra burada anlattmz eyler size ocuk oyunca gibi gelecek...

6.4.4 ush

imdiye kadar print() fonksiyonunun sep, end ve le adl zel birtakm parametreleri
olduunu rendik. print() fonksiyonunun bunlarn dnda baka bir zel parametresi daha
bulunur. Bu parametrenin ad ush. te imdi biz print() fonksiyonunun bu ush adl
parametresinden sz edeceiz.
Bildiiniz gibi, print() gibi bir komut verdiimizde Python, yazdrmak istediimiz bilgiyi
standart kt konumuna gnderir. Ancak Pythonda baz ilemler standart kt konumuna
gnderilmeden nce bir sre tamponda bekletilir ve daha sonra bekleyen bu ilemler topluca
standart kt konumuna gnderilir. Peki ilk bata ok karmakm gibi grnen bu ifade ne
anlama geliyor?
Aslnda siz bu olguya hi yabanc deilsiniz. le parametresini anlatrken verdiimiz u rnei
tekrar ele alalm:
>>> f = open("kiisel_bilgiler.txt", "w")

Bu komutla kiisel_bilgiler.txt adl bir dosyay yazma kipinde atk. imdi bu dosyaya baz
bilgiler ekleyelim:

>>> print("Frat zgl", file=f)

Bu komutla kiisel_bilgiler.txt adl dosyaya Frat zgl diye bir satr eklemi olduk.
imdi bilgisayarnzda oluan bu kiisel_bilgiler.txt dosyasn an. Grdnz gibi dosyada
hibir bilgi yok. Dosya u anda bo grnyor. Halbuki biz biraz nce bu dosyaya Frat zgl
diye bir satr eklemitik, deil mi?
Python bizim bu dosyaya eklemek istediimiz satr tampona kaydetti. Dosyaya yazma
ilemleri sona erdiinde ise Python, tamponda bekleyen btn bilgileri standart kt
konumuna (yani bizim durumumuzda f adl deikenin tuttuu kiisel_bilgiler.txt adl
dosyaya) boaltacak.
Dosyaya baka bilgiler de yazalm:
>>> print("Adana", file=f)
>>> print("Ubuntu", file=f)

Dosyaya yazacamz eyler bu kadar. Artk yazma ileminin sona erdiini Pythona bildirmek
iin u komutu veriyoruz:
>>> f.close()

Bylece dosyamz kapatm olduk. imdi kiisel_bilgiler.txt adl dosyaya ift tklayarak
dosyay tekrar an. Orada Frat zgl, Adana ve Ubuntu satrlarn greceksiniz.
Grdnz gibi, gerekten de Python dosyaya yazdrmak istediimiz btn verileri nce
tamponda bekletti, daha sonra dosya kapatlnca tamponda bekleyen btn verileri dosyaya
boaltt. te ush parametresi ile, bahsettiimiz bu boaltma ilemini kontrol edebilirsiniz.
imdi dikkatlice inceleyin:

64 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

>>> f = open("kiisel_bilgiler.txt", "w")

Dosyamz oluturduk. imdi bu dosyaya baz bilgiler ekleyelim:


>>> print("Merhaba Dnya!", file=f, flush=True)

Grdnz gibi, burada ush adl yeni bir parametre kullandk. Bu parametreye verdiimiz
deer True. imdi dosyaya ift tklayarak dosyay an. Grdnz gibi, henz dosyay
kapatmadmz halde bilgiler dosyaya yazld. Bu durum, tahmin edebileceiniz gibi, ush
parametresine True deeri vermemiz sayesindedir. Bu parametre iki deer alabilir: True ve
False. Bu parametrenin ntanml deeri False tur. Yani eer biz bu parametreye herhangi
bir deer belirtmezsek Python bu parametrenin deerini False olarak kabul edecek ve
bilgilerin dosyaya yazlmas iin dosyann kapatlmasn bekleyecektir. Ancak bu parametreye
True deerini verdiimizde ise veriler tamponda bekletilmeksizin standart kt konumuna
gnderilecektir.
Yazdnz bir programda, yapmak istediiniz iin niteliine gre, bir dosyaya yazmak
istediiniz bilgilerin bir sre tamponda bekletilmesini veya hi bekletilmeden dorudan
dosyaya yazlmasn isteyebilirsiniz. htiyacnza bal olarak da ush parametresinin deerini
True veya False olarak belirleyebilirsiniz.

6.5 Birka Pratik Bilgi

Buraya gelene kadar print() fonksiyonu ve bu fonksiyonun parametreleri hakknda epey


sz syledik. Dilerseniz imdi de, programclk maceranzda iinize yarayacak, ilerinizi
kolaylatracak baz ipular verelim.

6.5.1 Yldzl Parametreler

imdi size yle bir soru sormama izin verin: Acaba aadaki gibi bir kty nasl elde ederiz?
L.i.n.u.x

Aklnza hemen yle bir cevap gelmi olabilir:


>>> print("L", "i", "n", "u", "x", sep=".")

L.i.n.u.x

Yukardaki, gerekten de doru bir zmdr. Ancak bu soruyu zmenin ok daha basit bir
yolu var. imdi dikkatle bakn:
>>> print(*"Linux", sep=".")

L.i.n.u.x

Konuyu aklamaya gemeden nce bir rnek daha verelim:


>>> print(*"Galatasaray")

G a l a t a s a r a y

Burada neler dndn az ok tahmin ettiinizi zannediyorum. Son rnekte de grdnz


gibi, Galatasaray karakter dizisinin bana eklediimiz yldz iareti; Galatasaray karakter

6.5. Birka Pratik Bilgi 65


Python 3 iin Trke Klavuz, Srm 3

dizisinin her bir esini paralarna ayrarak, bunlar tek tek print() fonksiyonuna yolluyor.
Yani sanki print() fonksiyonunu yle yazmz gibi oluyor:
>>> print("G", "a", "l", "a", "t", "a", "s", "a", "r", "a", "y")

G a l a t a s a r a y

Dediimiz gibi, bir fonksiyona parametre olarak verdiimiz bir karakter dizisinin bana
eklediimiz yldz iareti, bu karakter dizisini tek tek elerine ayrp, bu eleri yine tek tek ve
sanki her bir e ayr bir parametreymi gibi o fonksiyona gnderdii iin doal olarak yldz
iaretini ancak, birden fazla parametre alabilen fonksiyonlara uygulayabiliriz.
rnein len() fonksiyonu sadece tek bir parametre alabilir:
>>> len("Galatasaray")

11

Bu fonksiyonu birden fazla parametre ile kullanamayz:


>>> len("Galatasaray", "Fenerbahe", "Beikta")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: len() takes exactly one argument (3 given)

Hata mesajnda da sylendii gibi, len() fonksiyonu yalnzca tek bir parametre alabilirken,
biz 3 parametre vermeye almz...
Dolaysyla yldzl parametreleri len() fonksiyonuna uygulayamayz:
>>> len(*"Galatasaray")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: len() takes exactly one argument (11 given)

Bir parametrenin bana yldz eklediimizde, o parametreyi oluturan btn eler tek tek
fonksiyona gnderildii iin, sanki len() fonksiyonuna 1 deil de, 11 ayr parametre vermiiz
gibi bir sonu ortaya kyor.
Yldzl parametreleri bir fonksiyona uygulayabilmemiz iin o fonksiyonun birden fazla
parametre alabilmesinin yansra, yapsnn da yldzl parametre almaya uygun olmas
gerekir. Mesela open(), type() ve biraz nce bahsettiimiz len() fonksiyonlarnn yaps
yldzl parametre almaya uygun deildir. Dolaysyla yldzl parametreleri her fonksiyonla
birlikte kullanamayz, ama print() fonksiyonu yldzl parametreler iin son derece uygun bir
fonksiyondur:
>>> print(*"Galatasaray")

G a l a t a s a r a y

>>> print(*"TBMM", sep=".")

T.B.M.M

>>> print(*"abcdefgh", sep="/")

66 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

a/b/c//d/e/f/g//h

Bu rneklerden de grdnz gibi, print() fonksiyonuna verdiimiz bir parametrenin


bana yldz eklediimizde, o parametre tek tek paralarna ayrlp print() fonksiyonuna
gnderildii iin, sonu olarak sep parametresinin karakter dizisi elerine tek tek
uygulanmasn salam oluyoruz.
Hatrlarsanz sep parametresinin ntanml deerinin bir adet boluk karakteri olduunu
sylemitik. Yani aslnda Python yukardaki ilk komutu yle gryor:
>>> print(*"Galatasaray", sep=" ")

Dolaysyla, yldz iareti sayesinde Galatasaray adl karakter dizisinin her bir esinin
arasna bir adet boluk karakteri yerletiriliyor. Bir sonraki TBMM karakter dizisinde ise, sep
parametresinin deerini nokta iareti olarak deitirdiimiz iin TBMM karakter dizisinin
her bir esinin arasna bir adet nokta iareti yerletiriliyor. Ayn ekilde abcdefgh
karakter dizisinin her bir esini tek tek print() fonksiyonuna yollayarak, sep parametresine
verdiimiz / iareti yardmyla her enin arasna bu / iaretini yerletirebiliyoruz.
Yldzl parametrelerle ilgili tek kstlama, bunlarn saylarla birlikte kullanlamayacak
olmasdr:
>>> print(*2345)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: print() argument after * must be a sequence, not int

nk yldzl parametreler ancak ve ancak dizi zellii tayan veri tipleriyle birlikte
kullanlabilir. Mesela karakter dizileri bu trden bir veri tipidir. lerde dizi zellii tayan ve
bu sayede yldzl parametrelerle birlikte kullanlabilecek baka veri tiplerini de reneceiz.
Yukarda verdiimiz rnekler bize yldzl parametrelerin son derece kullanl aralar
olduunu gsteriyor. leride de bu parametrelerden bol bol yararlanacaz. Biz imdi bu
konuyu burada kapatp baka bir eyden sz edelim.

6.5.2 sys.stdoutu Kalc Olarak Deitirmek

nceki balklar altnda verdiimiz rneklerden de grdnz gibi, print() fonksiyonunun


le parametresi yardmyla Pythonn standart kt konumunu geici olarak deitirebiliyoruz.
Ama baz durumlarda, yazdnz programlarda, o programn ileyii boyunca standart d
bir kt konumu belirlemek isteyebilirsiniz. Yani standart kt konumunu geici olarak
deil, kalc olarak deitirmeniz gerekebilir. Mesela yazdnz programda btn ktlar bir
dosyaya yazdrmay tercih edebilirsiniz. Elbette bu ilemi her defasnda le parametresini,
ktlar yazdrmak istediiniz dosyann ad olarak belirleyerek yapabilirsiniz. Tpk u rnekte
olduu gibi:
>>> f = open("dosya.txt", "w")
>>> print("Frat zgl", file=f)
>>> print("Adana", file=f)
>>> print("Ubuntu", file=f)
>>> f.close()

6.5. Birka Pratik Bilgi 67


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, her defasnda le parametresine f deerini vererek iimizi hallettik. Ama
bunu yapmann daha pratik bir yntemi var. Dilerseniz yazdnz programn tm ileyii
boyunca ktlar baka bir konuma ynlendirebilirsiniz. Bunun iin hem imdiye kadar
rendiimiz, hem de henz renmediimiz baz bilgileri kullanacaz.
lk nce yle bir kod yazalm:
>>> import sys

Bu kod yardmyla sys adl zel bir modl programmza dahil etmi, yani ie aktarm olduk.
Peki modl nedir, ie aktarmak ne demek?
Aslnda biz bu modl ve ie aktarma kavramlarna hi de yabanc deiliz. nceki derslerde,
pek zerinde durmam da olsak, biz Pythondaki birka modlle zaten tanmtk. Mesela
os adl bir modl iindeki getcwd() adl bir fonksiyonu kullanarak, o anda hangi dizinde
bulunduumuzu renebilmitik:
>>> import os
>>> os.getcwd()

Ayn ekilde keyword adl baka bir modl iindeki kwlist adl deikeni kullanarak, hangi
kelimelerin Pythonda deiken ad olarak kullanlamayacan da listeleyebilmitik:
>>> import keyword
>>> keyword.kwlist

te imdi de, os ve keyword modllerine ek olarak sys adl bir modlden sz ediyoruz.
Gelin isterseniz teki modlleri imdilik bir kenara brakp, bu sys denen modle dikkatimizi
verelim.
Dediimiz gibi, sys modl iinde pek ok nemli deiken ve fonksiyon bulunur. Ancak bir
modl iindeki deiken ve fonksiyonlar kullanabilmek iin o modl ncelikle programmza
dahil etmemiz, yani ie aktarmamz gerekiyor. Bunu import komutuyla yapyoruz:
>>> import sys

Artk sys modl iindeki btn fonksiyon ve deikenlere ulaabileceiz.


sys modl iinde bulunan pek ok deiken ve fonksiyondan biri de stdout adl deikendir.
Bu deikenin deerine yle ulaabilirsiniz:
>>> sys.stdout

Bu komut una benzer bir kt verir:


<_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1254'>

Bu ktdaki name=<stdout> ksmna dikkat edin. Bu ifadeye birazdan geri dneceiz. Biz
imdi baka bir eyden sz edelim.
Hatrlarsanz etkileimli kabuu nasl kapatabileceimizi anlatrken, etkileimli kabuktan
kmann bir yolunun da u komutlar vermek olduunu sylemitik:
>>> import sys; sys.exit()

Bu komutu tek satrda yazmtk, ama istersek yle de yazabiliriz elbette:

68 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

>>> import sys


>>> sys.exit()

Dedik ya, sys modl iinde pek ok deiken ve fonksiyon bulunur. Nasl stdout sys modl
iindeki deikenlerden biri ise, exit() de sys modl iinde bulunan fonksiyonlardan biridir.
Biz modller konusunu ilerleyen derslerde ayrntl bir ekilde inceleyeceiz. imdilik
modllere ilikin olarak yalnzca unlar bilelim yeter:
1. Pythonda modller import komutu ile ie aktarlr. rnein sys adl modl ie aktarmak
iin import sys komutunu veriyoruz.
2. Modller iinde pek ok faydal deiken ve fonksiyon bulunur. te bir modl ie
aktardmzda, o modl iindeki bu deiken ve fonksiyonlar kullanma imkan elde ederiz.
3. sys modl iindeki deikenlere bir rnek stdout ; fonksiyonlara rnek
ise exit() fonksiyonudur. Bir modl iindeki bu deiken ve fonksiyonlara
modl_ad.deiken_ya_da_fonksiyon formln kullanarak eriebiliriz. rnein:
>>> sys.stdout
>>> sys.exit()

4. Hatrlarsanz bundan nce de, open() fonksiyonu ile dosya oluturmay anlatrken,
oluturulan dosyann hangi dizinde olduunu bulabilmek amacyla, o anda iinde
bulunduumuz dizini tespit edebilmek iin u kodlar kullanmtk:
>>> import os
>>> os.getcwd()

Burada da os adl baka bir modl gryoruz. te os da tpk sys gibi bir modldr ve tpk
sys modlnde olduu gibi, os modlnn de iinde pek ok yararl deiken ve fonksiyon
bulunur. getcwd() adl fonksiyon da os modl iinde yer alan ve o anda hangi dizin altnda
bulunduumuzu gsteren bir fonksiyondur. Elbette, yine tpk sys modlnde olduu gibi,
os modl iindeki bu yararl deiken ve fonksiyonlar kullanabilmek iin de ncelikle bu os
modln ie aktarmamz, yani programmza dahil etmemiz gerekiyor. os modln import
komutu araclyla uygun bir ekilde ie aktardktan sonra, modl iinde yer alan getcwd()
adl fonksiyona yine modl_ad.fonksiyon formln kullanarak eriebiliyoruz.
Modllere ilikin imdilik bu kadar bilgi yeter. Modlleri bir kenara brakp yolumuza devam
edelim...
Eer sys.exit() komutunu verip etkileimli kabuktan ktysanz, etkileimli kabua tekrar
girin ve sys modln yeniden ie aktarn:
>>> import sys

Not: Bir modl ayn etkileimli kabuk oturumu iinde bir kez ie aktarmak yeterlidir. Bir
modl bir kez ie aktardktan sonra, o oturum sresince bu modl iindeki deiken ve
fonksiyonlar kullanmaya devam edebilirsiniz. Ama tabii ki etkileimli kabuu kapatp tekrar
atktan sonra, bir modl kullanabilmek iin o modl tekrar ie aktarmanz gerekir.

imdi u kodu yazn:


>>> f = open("dosya.txt", "w")

6.5. Birka Pratik Bilgi 69


Python 3 iin Trke Klavuz, Srm 3

Bu kodun anlamn biliyorsunuz. Burada dosya.txt adl bir dosyay yazma kipinde am
olduk. Tahmin edebileceiniz gibi, ktlarmz ekran yerine bu dosyaya ynlendireceiz.
imdi de yle bir kod yazalm:
>>> sys.stdout = f

Bildiiniz gibi, sys.stdout deeri Pythonn ktlar hangi konuma vereceini belirliyor. te
biz burada sys.stdout un deerini biraz nce oluturduumuz f adl dosya ile deitiriyoruz.
Bylece Python btn ktlar f deikeni iinde belirttiimiz dosya.txt adl dosyaya
gnderiyor.
Bu andan sonra yazacanz her ey dosya.txt adl dosyaya gidecektir:
>>> print("deneme metni", flush=True)

Grdnz gibi, burada le parametresini kullanmadmz halde ktlarmz ekrana deil,


dosya.txt adl bir dosyaya yazdrld. Peki ama bu nasl oldu? Aslnda bunun cevab ok basit:
Biraz nce sys.stdout = f komutuyla sys.stdout un deerini f deikeninin tuttuu dosya
ile deitirdik. Bu ilemi yapmadan nce sys.stdoutun deeri uydu hatrlarsanz:
<_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1254'>

Ama sys.stdout = f komutundan sonra her ey deiti. Kontrol edelim:


>>> print(sys.stdout, flush=True)

Elbette bu komuttan herhangi bir kt almadnz. ktnn ne olduunu grmek iin dosya.txt
adl dosyay an. Orada u satr greceksiniz:
<_io.TextIOWrapper name='dosya.txt' mode='w' encoding='cp1254'>

Grdnz gibi, zgn stdout ktsndaki name=<stdout> deeri name=dosya.txt olmu.


Dolaysyla artk btn ktlar dosya.txt adl dosyaya gidiyor...
Bu arada, yukardaki ktda grnen name, mode ve encoding deerlerine u ekilde
ulaabilirsiniz:
>>> sys.stdout.name
>>> sys.stdout.mode
>>> sys.stdout.encoding

Burada sys.stdout.name komutu standart kt konumunun o anki adn verecektir.


sys.stdout.mode komutu ise standart kt konumunun hangi kipe sahip olduunu gsterir.
Standart kt konumu genellikle yazma kipinde (w ) bulunur. sys.stdout.encoding kodu
ise standart kt konumunun sahip olduu kodlama biimini gsterir. Kodlama biimi,
standart kt konumuna yazdracanz karakterlerin hangi kodlama biimi ile kodlanacan
belirler. Kodlama biimi Windowsta genellikle cp1254, GNU/Linuxta ise utf-8dir. Eer
bu kodlama biimi yanl olursa, mesela dosyaya yazdracanz karakterler iindeki Trke
harer dzgn grntlenemez. Eer burada sylediklerimiz size u anda anlalmaz
geliyorsa, sylediklerimizi dikkate almadan yolunuza devam edebilirsiniz. Birka blm sonra
bu sylediklerimiz size daha fazla ey ifade etmeye balayacak nasl olsa.
Peki standart kt konumunu eski haline dndrmek isterseniz ne yapacaksnz? Bunun iin
etkileimli kabuktan kp tekrar girebilirsiniz. Etkileimli kabuu tekrar atnzda her eyin
eski haline dndn greceksiniz. Ayn ekilde, eer bu kodlar bir program dosyasna
yazm olsaydnz, programnz kapandnda her ey eski haline dnecekti.

70 Blm 6. print() Fonksiyonu


Python 3 iin Trke Klavuz, Srm 3

Peki standart kt konumunu, etkileimli kabuktan kmadan veya program kapatmadan eski
haline dndrmenin bir yolu var m? Elbette var. Dikkatlice bakn:
>>> import sys
>>> f = open("dosya.txt", "w")
>>> sys.stdout, f = f, sys.stdout
>>> print("deneme", flush=True)
>>> f, sys.stdout = sys.stdout, f
>>> print("deneme")

deneme

Uyar: Eer yukardaki kodlar altramyorsanz, ayn etkileimli kabuk oturumunda


nceden verdiiniz kodlar bu kodlarn doru kt vermesini engelliyor olabilir. Bu sorunu
amak iin, etkileimli kabuu kapatp tekrar an ve yukardaki komutlar tekrar verin.

Aslnda burada anlayamayacanz hibir ey yok. Burada yaptmz eyi geen blmlerde
deikenlerin deerini nasl takas edeceimizi anlatrken de yapmtk. Hatrlayalm:
>>> osman = "Aratrma Gelitirme Mdr"
>>> mehmet = "Proje Sorumlusu"
>>> osman, mehmet = mehmet, osman

Bu kodlarla Osman ve Mehmetin unvanlarn birbiriyle takas etmitik. te yukarda


yaptmz ey de bununla ayndr. sys.stdout, f = f, sys.stdout dediimizde f deerini
sys.stdout a, sys.stdout un deerini ise f ye vermi oluyoruz. f, sys.stdout = sys.stdout,
f dediimizde ise, bu ilemin tam tersini yaparak her eyi eski haline getirmi oluyoruz.
Pythonn bize sunduu bu kolaylktan faydalanarak deikenlerin deerini birbiriyle kolayca
takas edebiliyoruz. Eer byle bir kolaylk olmasayd yukardaki kodlar yle yazabilirdik:
>>> import sys
>>> f = open("dosya.txt", "w")
>>> zgn_stdout = sys.stdout
>>> sys.stdout = f
>>> print("deneme", flush=True)
>>> sys.stdout = zgn_stdout
>>> print("deneme")

deneme

Grdnz gibi, sys.stdout un deerini kaybetmemek iin, sys.stdout deerini f adl


dosyaya gndermeden nce u kod yardmyla yedekliyoruz:
>>> zgn_stdout = sys.stdout

sys.stdout un zgn deerini zgn_stdout deikenine atadmz iin, bu deere sonradan


tekrar ulaabileceiz. Zaten yukardaki kodlardan da grdnz gibi, sys.stdout un zgn
deerine dnmek istediimizde u kodu yazarak isteimizi gerekletirebiliyoruz:
>>> sys.stdout = zgn_stdout

Bylece stdout deeri eski haline dnm oluyor ve bundan sonra yazdrdmz her ey
yeniden ekrana baslmaya balyor.
...ve bylece uzun bir blm daha geride braktk. Bu blmde hem print() fonksiyonunu
btn ayrntlaryla incelemi olduk, hem de Python programlama diline dair baka ok

6.5. Birka Pratik Bilgi 71


Python 3 iin Trke Klavuz, Srm 3

nemli kavramlardan sz ettik. Bu bakmdan bu blm bize epey ey retti. Artk


rendiimiz bu bilgileri de kfemize koyarak bamz dik bir ekilde yola devam edebiliriz.

72 Blm 6. print() Fonksiyonu


BLM 7

Ka Dizileri

Pythonda karakter dizilerini tanmlayabilmek iin tek, ift veya trnak iaretlerinden
faydalandmz geen blmde renmitik. Python bir verinin karakter dizisi olup
olmadna bu trnak iaretlerine bakarak karar verdii iin, tek, ift ve trnak iaretleri
Python asndan zel bir nem tayor. Zira Pythonn gznde bir balang trna ile biti
trna arasnda yer alan her ey bir karakter dizisidir.
rnein ilk olarak bir iareti koyup ardndan elma eklinde devam ettiinizde, Python ilk
trna grdkten sonra karakter dizisini tanmlayabilmek iin ikinci bir trnak iareti aramaya
balar. Siz elma eklinde kodunuzu tamamladnzda ise Python bellekte elma adl bir
karakter dizisi oluturur.
Bu noktada size yle bir soru sormama izin verin: Acaba trnak iaretleri herhangi bir metin
iinde ka farkl amala kullanlabilir?
sterseniz bu sorunun cevabn rnekler zerinde vermeye alalm:
Ahmet, Bugn sinemaya gidiyorum, dedi.
Burada trnak iaretlerini, bir bakasnn szlerini aktarmak iin kullandk.
book kelimesi Trkede kitap anlamna gelir.
Burada ise trnak iaretlerini baz kelimeleri vurgulamak iin kullandk.
Bir de una bakalm:
Yarn Adanaya gidiyorum.
Burada da trnak iaretini, ekim eki olan -(y)a ile zel isim olan Adana kelimesini birbirinden
ayrmak iin kesme iareti grevinde kullandk.
imdi yukarda verdiimiz ilk cmleyi bir karakter dizisi olarak tanmlamaya alalm:
>>> 'Ahmet, "Bugn sinemaya gidiyorum," dedi.'

Burada karakter dizisini tanmlamaya tek trnak iareti ile baladk. Bylece Python bu
karakter dizisini tanmlama ilemini bitirebilmek iin ikinci bir tek trnak iareti daha aramaya
koyuldu ve arad tek trnak iaretini cmlenin sonunda bularak, karakter dizisini dzgn bir
ekilde oluturabildi.
Dediimiz gibi, Pythonn gznde trnak iaretleri bir karakter dizisini baka veri tiplerinden
ayrt etmeye yarayan bir lttr. Ama biz insanlar, yukarda verdiimiz rnek cmlelerden
de greceiniz gibi, programlama dillerinden farkl olarak, trnak iaretlerini bir metin iinde
daha farkl amalar iin de kullanabiliyoruz.

73
Python 3 iin Trke Klavuz, Srm 3

imdi yukardaki karakter dizisini yle tanmlamaya altmz dnn:


>>> "Ahmet, "Bugn sinemaya gidiyorum," dedi."

te burada Pythonn karlar ile bizim karlarmz birbiriyle att. Python karakter
dizisini balatan ilk ift trnak iaretini grdkten sonra, karakter dizisini tanmlama ilemini
bitirebilmek iin ikinci bir trnak iareti daha aramaya koyuldu. Bu aray srasnda da Bugn
kelimesinin bandaki ift trnak iaretini grd ve karakter dizisinin u olduunu zannetti:
>>> "Ahmet, "

Buraya kadar bir sorun yok. Bu karakter dizisi Pythonn szdizimi kurallarna uygun.
Karakter dizisi bu ekilde tanmlandktan sonra Python cmlenin geri kalann okumaya
devam ediyor ve herhangi bir trnak iareti ile balamayan ve kendisinden nce gelen eden
herhangi bir virgl iareti ile ayrlmam Bugn kelimesini gryor. Eer bir kelime trnak
iareti ile balamyorsa bu kelime ya bir deikendir ya da saydr. Ama Bugn kelimesi
ne bir deiken, ne de bir say olduu, stelik nceki eden de virglle ayrlmad iin
Pythonn hata vermekten baka aresi kalmyor. nk biz burada Bugn kelimesinin
ba tarafndaki ift trnak iaretini karakter dizisi tanmlamak iin deil, bakasnn szlerini
aktarmak amacyla kullandk. Ancak elbette bir programlama dili bizim amacmzn ne
olduunu kestiremez ve hata mesajn suratmza yaptrr:
File "<stdin>", line 1
"Ahmet, "Bugn sinemaya gidiyorum," dedi."
^
SyntaxError: invalid syntax

Peki biz byle bir durumda ne yapmalyz?


Bu hatay engellemek iin karakter dizisini tanmlamaya ift trnak yerine tek trnakla ya da
trnakla balayabiliriz:
>>> 'Ahmet, "Bugn sinemaya gidiyorum," dedi.'

... veya:
>>> """Ahmet, "Bugn sinemaya gidiyorum," dedi."""

Bylece karakter dizisini balatan iaret Bugn sinemaya gidiyorum, cmlesinin bandaki ve
sonundaki iaretlerden farkl olduu iin, Python okuma esnasnda bu cmleye taklmaz ve
doru bir ekilde, karakter dizisini kapatan trnak iaretini bulabilir.
Bu yntem tamamen geerli ve mantkldr. Ama eer istersek, ayn karakter dizisini ift
trnakla tanmlayp, yine de hata almay engelleyebiliriz. Peki ama nasl?
te burada ka dizileri ad verilen birtakm aralardan faydalanacaz.
Peki nedir bu ka dizisi denen ey?
Ka dizileri, Pythonda zel anlam tayan iaret veya karakterleri, sahip olduklar bu zel
anlam dnda bir amala kullanmamz salayan birtakm aralardr. Mesela yukarda da
rneklerini verdiimiz gibi, trnak iaretleri Python asndan zel anlam tayan iaretlerdir.
Normalde Python bu iaretleri karakter dizilerini tanmlamak iin kullanr. Ama eer siz
mesela bir metin iinde bu trnak iaretlerini farkl bir amala kullanacaksanz Python bu
durumdan haberdar etmeniz gerekiyor. te ka dizileri, Python byle bir durumdan
haberdar etmemize yarayan aralardr.

74 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

Pythonda pek ok ka dizisi bulunur. Biz burada bu ka dizilerini tek tek inceleyeceiz. O
halde hemen ie koyulalm.

7.1 Ters Taksim (\)

Yukarda verdiimiz rneklerde, ift trnakla gsterdiimiz karakter dizilerinin iinde de ift
trnak iareti kullanabilmek iin birka farkl yntemden yararlanabildiimizi renmitik.
Buna gre, eer bir karakter dizisi iinde ift trnak iareti geiyorsa, o karakter dizisini tek
trnakla; eer tek trnak geiyorsa da o karakter dizisini ift trnakla tanmlayarak bu sorunun
stesinden gelebiliyorduk. Ama daha nce de sylediimiz gibi, ka dizileri ad verilen
birtakm aralar kullanarak, mesela iinde ift trnak geen karakter dizilerini yine ift trnakla
tanmlayabiliriz.
Dilerseniz, ka dizisi kavramn aklamaya gemeden nce bununla ilgili birka rnek
verelim. Bu sayede ne ile kar karya olduumuz, zihnimizde biraz daha belirginleebilir:
>>> print('Yarn Adana\'ya gidiyorum.')

Yarn Adana'ya gidiyorum.

Bir rnek daha verelim:


>>> print("\"book\" kelimesi Trkede \"kitap\" anlamna gelir.")

"book" kelimesi Trkede "kitap" anlamna gelir.

Burada da cmle iinde ift trnak iaretlerini kullandmz halde, \ iaretleri sayesinde
karakter dizilerini yine ift trnakla tanmlayabildik.
Bir de u rnee bakalm:
>>> print("Python programlama dilinin ad \"piton\" ylanndan gelmez")

Btn bu rneklerde, karakter dizisini hem ift trnakla tanmlayp hem de karakter
dizisi iinde ift trnak iaretlerini kullandmz halde, herhangi bir hata almadmz
gryorsunuz. Yukardaki kodlarda hata almamz nleyen eyin \ iareti olduu belli. Ama
dilerseniz bu iaretin, hata almamz nasl nlediini anlatmadan nce son bir rnek daha
verelim.
Hatrlarsanz nceki sayfalarda yle bir karakter dizisi ile karlamtk:
>>> print('stanbul'un 5 gnlk hava durumu tahmini')

File "<stdin>", line 1


print('stanbul'un 5 gnlk hava durumu tahmini')
^
SyntaxError: invalid syntax

Burada da stanbulun kelimesi iinde geen trnak iareti nedeniyle karakter dizisini tek
trnak kullanarak tanmlayamyorduk. Bu karakter dizisini hatasz bir ekilde tanmlayabilmek
iin ya ift trnak ya da trnak kullanmamz gerekiyordu:
>>> print("stanbul'un 5 gnlk hava durumu tahmini")

stanbul'un 5 gnlk hava durumu tahmini

7.1. Ters Taksim (\) 75


Python 3 iin Trke Klavuz, Srm 3

... veya:
>>> print("""stanbul'un 5 gnlk hava durumu tahmini""")

stanbul'un 5 gnlk hava durumu tahmini

Tpk nceki rneklerde olduu gibi, yukardaki karakter dizisini de aslnda tek trnakla
tanmlayp hata olumasn nleyebiliriz. Hemen grelim:
>>> print('stanbul\'un 5 gnlk hava durumu tahmini')

stanbul'un 5 gnlk hava durumu tahmini

Btn rneklerde \ iaretini kullandmz gryorsunuz. te bu tr iaretlere Pythonda


ka dizisi (escape sequence ) ad verilir. Bu iaretler karakter dizilerini tanmlarken
oluabilecek hatalardan kamamz salar. Peki bu \ iareti nasl oluyor da karakter dizisini
tanmlarken hata almamz nlyor? Gelin bu sreci adm adm tarif edelim:
Python bir karakter dizisi tanmladmzda, karakter dizisini soldan saa doru okumaya
balar. Mesela yukardaki rnekte ilk olarak karakter dizisini tanmlamaya tek trnakla
baladmz grr.
Python karakter dizisini balatan bu tek trnak iaretini grd zaman, soldan saa doru
ilerleyerek karakter dizisini bitirecek olan tek trnak iaretini aramaya balar.
Soldan saa doru ilerlerken stanbulun kelimesi iinde geen kesme iaretini grr ve
karakter dizisinin burada sona erdiini dnr. Ancak karakter dizisini sona erdiren iaret
bu olmad iin Pythonn hata vermekten baka aresi kalmaz.
te biz stanbulun kelimesi iinde geen bu kesme iaretinin sol tarafna bir adet \ iareti
yerletirerek Pythona, Aradn iaret bu deil. Sen karakter dizisini okumaya devam et. Biraz
sonra aradn trna bulacaksn! mesaj vermi, yani orada trnak iaretini farkl bir amala
kullandmz konusunda Python bilgilendirmi oluruz.
urada da ayn durum szkonusu:
>>> print("Python programlama dilinin ad \"piton\" ylanndan gelmez")

Tpk bir nceki rnekte olduu gibi, burada da Python karakter dizisini soldan saa doru
okumaya balyor, karakter dizisini balatan ift trnak iaretini gryor ve bunun zerine
Python karakter dizisini bitirecek olan ift trnak iaretini aramaya koyuluyor.
Karakter dizisini soldan saa doru okuduu srada, karakter dizisi iinde geen piton
kelimesini gryor. Eer burada bir nlem almazsak Python bu kelimenin bandaki ift trnak
iaretini, karakter dizisini sona erdiren trnak olarak alglar ve durum aslnda byle olmad
iin de hata verir.
Bu hatay nlemek iin piton kelimesinin bandaki ift trnan soluna bir adet \ iareti
yerletirerek Pythona, Aradn trnak bu deil! mesaj veriyoruz. Yani bir bakma, \ adl
ka dizisi kendisini trnak iaretine siper edip Pythonn bu trna grmesine mani oluyor...
Bunun zerine Python bu ift trnak iaretini grmezden gelerek, soldan saa doru okumaya
devam eder ve yol zerinde piton kelimesinin sonundaki ift trnak iaretini grr. Eer
burada da bir nlem almazsak Python yine bir hata verecektir.
Tpk biraz nce yaptmz gibi, bu trnak iaretinin de soluna bir adet \ iareti yerletirerek
Pythona, Aradn trnak bu da deil. Sen yine okumaya devam et! mesaj veriyoruz.

76 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

Bu mesaj alan Python karakter dizisini soldan saa doru okumaya devam ediyor ve sonunda
karakter dizisini bitiren ift trnak iaretini bularak bize hatasz bir kt veriyor.
Bylece \ iareti zerinden hem ka dizilerinin ne olduunu renmi, hem de bu ka
dizisinin nasl kullanlacana dair rnekler vermi olduk. Ancak \ ka dizisinin yetenekleri
yukardakilerle snrl deildir. Bu ka dizisini, uzun karakter dizilerini blmek iin de
kullanabiliriz. imdi u rnei dikkatlice inceleyin:
>>> print("Python 1990 ylnda Guido Van Rossum \
... tarafndan gelitirilmeye balanm, olduka \
... gl ve yetenekli bir programlama dilidir.")

Python 1990 ylnda Guido Van Rossum tarafndan gelitirilmeye


balanm, olduka gl ve yetenekli bir programlama dilidir.

Normal artlar altnda, bir karakter dizisini tanmlamaya tek veya ift trnakla balamsak,
karakter dizisinin kapan trnan koymadan Enter tuuna bastmzda Python bize bir hata
mesaj gsterir:
>>> print("Python 1990 ylnda Guido Van Rossum

File "<stdin>", line 1


print("Python 1990 ylnda Guido Van Rossum
^
SyntaxError: EOL while scanning string literal

te \ ka dizisi bizim burada olas bir hatadan kamamz salar. Eer Enter tuuna
basmadan nce bu iareti kullanrsak Python tpk trnak iaretlerinde ahit olduumuz
gibi, hata vermeden bir alt satra geecektir. Bu srada, yani \ ka dizisini koyup Enter tuuna
bastmzda >>> iaretinin ... iaretine dntn gryorsunuz. Bu iaretin, Pythonn
bize verdii bir Yazmaya devam et! mesaj olduunu biliyorsunuz.

7.2 Satr Ba (\n)

Pythondaki en temel ka dizisi biraz nce rneklerini verdiimiz \ iaretidir. Bu ka dizisi


baka karakterlerle birleerek, farkl ilevlere sahip yeni ka dizileri de oluturabilir. Aslnda
bu olguya yabanc deiliz. nceki sayfalarda bu duruma bir rnek vermitik. Hatrlarsanz
print() fonksiyonunu anlatrken end parametresinin n tanml deerinin \n, yani satr ba
karakteri olduunu sylemitik.

Not: Satr ba karakterine yeni satr karakteri dendii de olur.

Satr ba karakterini ilk rendiimizde bu karakteri anlatrken baz rnekler de vermitik:


>>> print("birinci satr\nikinci satr\nnc satr")

birinci satr
ikinci satr
nc satr

Grdnz gibi, \n adl ka dizisi, bir alt satra geilmesini salyor. te aslnda \n ka
dizisi de, \ ile n harnin birlemesinden olumu bir ka dizisidir. Burada \ iaretinin
grevi, n harnin zel bir anlam kazanmasn salamaktr. \ iareti ile n har birletiinde
satr ba karakteri denen zel bir karakter dizisi ortaya karyor.

7.2. Satr Ba (\n) 77


Python 3 iin Trke Klavuz, Srm 3

Gelin bu ka dizisi ile ilgili bir rnek verelim. imdi u kodlar dikkatlice inceleyin:

>>> balk = "Trkiye'de zgr Yazlmn Gemii"


>>> print(balk, "\n", "-"*len(balk), sep="")

Trkiye'de zgr Yazlmn Gemii


----------------------------------

Burada, balk adl deikenin tuttuu Trkiyede zgr Yazlmn Gemii adl karakter
dizisinin altn izdik. Dikkat ederseniz, baln altna koyduumuz izgiler baln
uzunluunu amyor. Yazdmz program, baln uzunluu kadar izgiyi baln altna
ekliyor. Bu programda balk ne olursa olsun, programmz izgi uzunluunu kendisi
ayarlayacaktr. rnein:
>>> balk = "Python Programlama Dili"
>>> print(balk, "\n", "-"*len(balk), sep="")

Python Programlama Dili


-----------------------

>>> balk = "Alveri Listesi"


>>> print(balk, "\n", "-"*len(balk), sep="")

Alveri Listesi
-----------------

Gelin isterseniz bu kodlardaki print() satrn yle bir inceleyelim. Kodumuz u:


>>> print(balk, "\n", "-"*len(balk), sep="")

Burada ncelikle balk adl deikeni print() fonksiyonunun parantezleri iine yazdk.
Bylece balk deikeninin deeri ekrana yazdrlacak.
print() fonksiyonunun ikinci parametresinin \n adl ka dizisi olduunu gryoruz. Bu
ka dizisini eklememiz sayesinde Python ilk parametreyi kt olarak verdikten sonra bir alt
satra geiyor. Bu parametrenin tam olarak ne ie yaradn anlamak iin, yukardaki satr
bir de o parametre olmadan altrmay deneyebilirsiniz:
>>> print(balk, "-"*len(balk), sep="")

Alveri Listesi-----------------

print() fonksiyonunun nc parametresinin ise u olduunu gryoruz:


"-"*len(balk).
te balk deikeninin altna gerekli sayda izgiyi izen kodlar bunlardr. Burada len()
fonksiyonunu nasl kullandmza ok dikkat edin. Bu kod sayesinde balk deikeninin
uzunluu (len(balk)) saysnca - iaretini ekrana kt olarak verebiliyoruz.
Yukardaki kodlarda print() fonksiyonunun son parametresi ise sep=. Peki bu ne ie
yaryor? Her zaman olduu gibi, bu kod parasnn ne ie yaradn anlamak iin program
bir de o kodlar olmadan altrmay deneyebilirsiniz:
>>> print(balk, "\n", "-"*len(balk))

Alveri Listesi
-----------------

78 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, balk deikeninin tam altna gelmesi gereken izgi iaretleri saa kaym.
Bunun nedeni sep parametresinin ntanml deerinin bir adet boluk karakteri olmasdr.
sep parametresinin ntanml deeri nedeniyle izgilerin ba tarafna bir adet boluk
karakteri ekleniyor ktda. O yzden bu izgiler saa kaym grnyor. te biz yukardaki
kodlarda sep parametresinin ntanml deerini deitirip, boluk karakteri yerine bo bir
karakter dizisi yerletiriyoruz. Bylece izgiler ktda saa kaymyor.
Satr ba karakteri, programlama maceramz srasnda en ok kullanacamz ka
dizilerinden biri ve hatta belki de birincisidir. O yzden bu ka dizisini ok iyi renmenizi
tavsiye ederim.
Ayrca bu ka dizisini (ve tabii teki ka dizilerini) tanyp renmeniz, yazacanz
programlarn selameti asndan da byk nem tar. Eer bir karakter dizisi iinde
geen ka dizilerini ayrt edemezseniz Python size hi beklemediiniz ktlar verebilir.
Hatta yazdnz programlar ka dizilerini tanmyor olmanzdan tr bir anda hata verip
kebilir. Peki ama nasl?
imdi u rnee dikkatlice bakn:
Diyelim ki bilgisayarnzn C:\ dizinindeki nisan adl bir klasrn iinde yer alan masraar.txt
adl bir dosyay yazdnz bir program iinde kullanmanz gerekiyor. Mesela bu dosyay, tam
adresiyle birlikte kullanclarnza gstermek istiyorsunuz.
lk denememizi yapalm:
>>> print("C:\nisan\masraflar.txt")

Buradan yle bir kt aldk:


C:
isan\masraflar.txt

Grdnz gibi, bu kty normal yollardan vermeye altmzda Python bize hi de


beklemediimiz bir kt veriyor. Peki ama neden?
Pythonda karakter dizileri ile alrken asla aklmzdan karmamamz gereken bir ey var:
Eer yazdmz herhangi bir karakter dizisinin herhangi bir yerinde \ iaretini kullanmsak,
bu iaretten hemen sonra gelen karakterin ne olduuna ok dikkat etmemiz gerekir. nk
eer dikkat etmezsek, farknda olmadan Python iin zel anlam tayan bir karakter dizisi
oluturmu olabiliriz. Bu da kodlarmzn beklediimiz gibi almasn engeller.
Yukardaki sorunun kaynan anlamak iin "C:\nisan\masraflar.txt" adl karakter dizisine
ok dikkatlice bakn. Python bu karakter dizisinde bizim \nisan olarak belirttiimiz ksmn
bandaki \n karakterlerini bir ka dizisi olarak alglad. nk \n adl karakter dizisi, satr
ba ka dizisi adn verdiimiz, Python asndan zel anlam tayan bir karakter dizisine
iaret ediyor. Zaten yukardaki tuhaf grnen ktya baktnzda da, bu ka dizisinin olduu
noktadan itibaren karakter dizisinin blnp yeni bir satra geildiini greceksiniz. te
biz yukardaki rnekte alelade bir dizin ad belirttiimizi zannederken aslnda hi farknda
olmadan bir ka dizisi retmi oluyoruz. Bu nedenle, daha nce de sylediimiz gibi,
karakter dizileri iinde farknda olarak veya olmayarak kullandmz ka dizilerine kar
her zaman uyank olmalyz. Aksi takdirde, yukarda olduu gibi hi beklemediimiz ktlarla
karlaabiliriz.
Esasen yukardaki problem bir dereceye kadar (ve yerine gre) masum bir kusur olarak
grlebilir. nk bu hata programmzn kmesine yol amyor. Ama bir karakter dizisi
iindeki gizli ka dizilerini gzden karmak, baz durumlarda ok daha ykc sonulara
yol aabilir. Mesela yukardaki sorunlu dizin adn ekrana yazdrmak yerine open()

7.2. Satr Ba (\n) 79


Python 3 iin Trke Klavuz, Srm 3

fonksiyonunu kullanarak, bu karakter dizisi iinde belirttiimiz masraar.txt adl dosyay


amaya altmz dnn:
>>> open("C:\nisan\masraflar.txt")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument: 'C:\nisan\\masraflar.txt'

Eer sorunun gzden kaan bir ka dizisinden kaynaklandn farkedemezseniz, bu sorunu


zebilmek iin saatlerinizi ve hatta gnlerinizi harcamak zorunda kalabilirsiniz. nk
yukardaki hata mesaj sorunun nedenine dair hibir ey sylemiyor. Ancak ve ancak
yukardaki karakter dizisi iinde sinsice gizlenen bir \n ka dizisi olduu gznze arparsa
bu sorunu zme yolunda bir adm atabilirsiniz.
Diyelim ki sorunun \nisan ifadesinin bandaki \n karakterlerinin Python tarafndan bir ka
dizisi olarak alglanmasndan kaynaklandn farkettiniz. Peki bu sorunu nasl zeceksiniz?
Bu sorunun birka farkl zm yolu var. Biz imdilik sadece ikisini greceiz. Bu blmn
sonuna vardnzda teki zm yolunu da renmi olacaksnz.
Yukardaki problemi, ilgili ka dizisi iindeki ters taksim iaretini iftleyerek zebilirsiniz:
>>> open("C:\\nisan\masraflar")

Tabii tutarllk asndan karakter dizisi iindeki btn ters taksim iaretlerini iftlemek
mantkl olacaktr:
>>> open("C:\\nisan\\masraflar")

Bunun dnda, bu rnek iin, dizin adlarn ters taksim yerine dz taksim iaretiyle ayrmay
tercih edebilirsiniz:
>>> open("C:/nisan/masraflar")

Dediimiz gibi, nc (ve aslnda daha kullanl olan) yntemi biraz sonra inceleyeceiz. Biz
imdilik ka dizilerini anlatmaya devam edelim.

7.3 Sekme (\t)

Pythonda \ iareti sadece n haryle deil, baka harerle de birleebilir. rnein \ iaretini
t haryle birletirerek yine zel bir anlam ifade eden bir ka dizisi elde edebiliriz:
>>> print("abc\tdef")

abc def

Burada \t adl ka dizisi, abc ifadesinden sonra sanki Tab (sekme) tuuna baslm gibi bir
etki oluturarak def ifadesini saa doru itiyor. Bir de u rnee bakalm:
>>> print("bir", "iki", "", sep="\t")

bir iki

Bir rnek daha:

80 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

>>> print(*"123456789", sep="\t")

1 2 3 4 5 6 7 8 9

Grdnz gibi, parametreler arasnda belli aralkta bir boluk brakmak istediimizde \t
adl ka dizisinden yararlanabiliyoruz.
Tpk \n ka dizisinde olduu gibi, karakter dizilerinde \t ka dizisinin varlna kar da
uyank olmalyz:
>>> open("C:\nisan\masraflar\toplam_masraf.txt")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument: 'C:\nisan\\masraflar\toplam_masraf.txt'

Burada da \n ile yaadmz soruna benzer bir durum var. Biz toplam_masraf.txt adl
bir dosyaya atfta bulunmaya alyoruz, ama Python bu ifadenin bandaki t harnin,
kendisinden nce gelen \ iareti ile birlemesinden tr, bunu \t ka dizisi olarak alglyor
ve ona gre davranyor.
Belki yukardaki kodlar yle yazarsak durumu anlamak daha kolay olabilir:
>>> print("C:\nisan\masraflar\toplam_masraf.txt")

C:
isan\masraflar oplam_masraf.txt

Grdnz gibi, Python \n ka dizisini grd noktada alt satrn bana geiyor ve \t ka
dizisini grd noktada da nceki ve sonraki eler arasnda bir sekme boluu brakyor.
Bu durumu engellemek iin ne yapmanz gerektiini biliyorsunuz: Ya ters taksim iaretlerini
iftleyeceksiniz:
>>> print("C:\\nisan\\masraflar\\toplam_masraf.txt")

Ya da dizin ad ayrac olarak dz taksim iaretini kullanacaksnz:


>>> print("C:/nisan/masraflar/toplam_masraf.txt")

Daha nce de sylediimiz gibi, nc ve daha pratik olan yolu biraz sonra greceiz.
imdilik sadece biraz sabr...

7.4 Zil Sesi (\a)

\ iaretinin birletiinde farkl bir anlam trettii bir baka harf de a hardir. \ iareti a
haryle birleerek !bip! benzeri bir zil sesi retilmesini salayabilir:
>>> print("\a")

!bip!

sterseniz yukardaki komutu u ekilde yazarak, kafa iirme katsaysn artrabilirsiniz:


>>> print("\a" * 10)

7.4. Zil Sesi (\a) 81


Python 3 iin Trke Klavuz, Srm 3

Bu ekilde !bip! sesi 10 kez tekrar edilecektir. Ancak bu ka dizisi ounlukla sadece
Windows zerinde alacaktr. Bu ka dizisinin GNU/Linux zerinde alma garantisi
yoktur. Hatta bu ka dizisi btn Windows sistemlerinde dahi almayabilir. Dolaysyla
bu ka dizisinin ilevine bel balamak pek mantkl bir i deildir.
Tpk \n ve \t ka dizilerinde olduu gibi bu ka dizisinin varlna kar da uyank olmalyz.
Burada da mesela C:\aylar gibi bir dizin ad tanmlamaya alrken aslnda \a ka dizisini
oluturuyor olabilirsiniz farknda olmadan.

7.5 Ayn Satr Ba (\r)

Bu ka dizisi, bir karakter dizisinde ayn satrn en bana dnlmesini salar. Bu ka


dizisinin ilevini tanmna bakarak anlamak biraz zor olabilir. O yzden dilerseniz bu ka
dizisinin ne ie yaradn bir rnek zerinde gstermeye alalm:
>>> print("Merhaba\rZalim Dnya!")

Zalim Dnya!

Burada olan ey u: Normal artlar altnda, print() fonksiyonu iine yazdmz bir karakter
dizisindeki btn karakterler soldan saa doru tek tek ekrana yazdrlr:
>>> print("Merhaba Zalim Dnya!")

Merhaba Zalim Dnya!

Ancak eer karakter dizisinin herhangi bir yerine \r adl ka dizisini yerletirirsek, bu ka
dizisinin bulunduu konumdan itibaren ayn satrn bana dnlecek ve \r ka dizisinden
sonra gelen btn karakterler satr bandaki karakterlerin zerine yazacaktr. u rnek daha
aklayc olabilir:
>>> print("Merhaba\rDnya")

Dnyaba

Burada, Merhaba karakter dizisi ekrana yazdrldktan sonra \r ka dizisinin etkisiyle satr
bana dnlyor ve bu ka dizisinden sonra gelen Dnya karakter dizisi Merhaba
karakter dizisinin zerine yazyor. Tabii Dnya karakter dizisi iinde 5 karakter, Merhaba
karakter dizisi iinde ise 7 karakter olduu iin, Merhaba karakter dizisinin son iki karakteri
(ba ) darda kalyor. Bylece ortaya Dnyaba gibi bir ey kyor.
nceki ka dizilerinde olduu gibi, bu ka dizisini de farknda olmadan karakter dizisi
iinde kullanrsanz beklemediiniz ktlar alrsnz:
>>> print("C:\lke\trkiye\iller\rize\nfus.txt")

izelke rkiye\iller
fus.txt

Burada farknda olmadan sadece bir deil, ka dizisi birden oluturduk!

82 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

7.6 Dey Sekme (\v)

Eer \ iaretini v haryle birlikte kullanrsak dey sekme denen eyi elde ederiz. Hemen bir
rnek verelim:
>>> print("dey\vsekme")

dey
sekme

Yalnz bu \v adl ka dizisi her iletim sisteminde almayabilir. Dolaysyla, birden


fazla platform zerinde almak zere tasarladnz programlarnzda bu ka dizisini
kullanmanz nermem.

7.7 mle Kaydrma (\b)

\ ka dizisinin, biraraya geldiinde zel bir anlam kazand bir baka harf de bdir. \b ka
dizisinin grevi, imleci o anki konumundan sola kaydrmaktr. Bu tanm pek anlalr deil. O
yzden bir rnek verelim:
>>> print("yahoo.com\b")

Bu kodu altrdnzda herhangi bir deiiklik grmeyeceksiniz. Ama aslnda en sonda


grdmz \b ka dizisi, imleci bir karakter sola kaydrd. Dikkatlice bakn:
>>> print("yahoo.com\b.uk")

Grdnz gibi, \b ka dizisinin etkisiyle imle bir karakter sola kayd iin, com
kelimesinin son har silindi ve bunun yerine \b ka dizisinden sonra gelen .uk karakterleri
yerletirildi. Dolaysyla biz de u kty aldk:
yahoo.co.uk

Bir rnek daha verelim...


Bildiiniz gibi, print() fonksiyonu, kendisine verilen parametreler arasna birer boluk
yerletirir:
>>> print('istihza', '.', 'com')

istihza . com

Biz bu eleri birbirine bititirmek iin yle bir yol izleyebileceimizi biliyoruz:
>>> print('istihza', '.', 'com', sep='')

istihza.com

te ayn etkiyi \b ka dizisini kullanarak da elde edebiliriz:


>>> print('istihza', '\b.', '\bcom')

istihza.com

Grdnz gibi, \b ka dizisi, . ve com parametrelerinden nce imleci birer karakter sola
kaydrd iin, parametreler arasndaki boluk karakterleri ortadan kalkt.

7.6. Dey Sekme (\v) 83


Python 3 iin Trke Klavuz, Srm 3

Bu ka dizisini kullanarak yle gereksiz iler peinde de koabilirsiniz:


>>> print('istihza\b\b\bsn')

istisna

Burada \b ka dizisini st ste birka kez kullanarak imleci birka karakter sola kaydrdk ve
sn harerini hz harerinin zerine bindirdik. Bylece istihza kelimesi istisna kelimesine
dnm oldu...
Daha fazla uzatmadan, bu ka dizisinin Pythonda ok nadir kullanld bilgisini vererek
yolumuza devam edelim...

7.8 Kk Unicode (\u)

Tpk bundan nceki ka dizileri gibi, karakter dizileri iindeki varl konusunda dikkatli
olmamz gereken bir baka ka dizisi de \u adl ka dizisidir. Eer bu ka dizisini tanmaz
ve dikkatli kullanmazsak, yazdmz programlar tespit etmesi ok g hatalar retebilir.
rnein yle bir kt vermek istediinizi dnn:
Dosya konumu: C:\users\zeynep\gizli\dosya.txt
Bu kty normal yollardan vermeye alrsak Python bize bir hata mesaj gsterecektir:
>>> print("Dosya konumu: C:\users\zeynep\gizli\dosya.txt")

File "<stdin>", line 1


SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 16-18: truncated \uXXXX escape

Belki sada solda UNICODE diye bir ey duymusunuzdur. Eer imdiye kadar byle bir
ey duymadysanz veya duyduysanz bile ne olduunu bilmiyorsanz hi ziyan yok. Birka
blm sonra bunun ne anlama geldiini btn ayrntlaryla anlatacaz. Biz imdilik sadece
unu bilelim: UNICODE, karakterlerin, harerin, saylarn ve bilgisayar ekrannda grdmz
teki btn iaretlerin her biri iin tek ve benzersiz bir numarann tanmland bir sistemdir.
Bu sistemde, kod konumu (code point ) ad verilen bu numaralar zel bir ekilde gsterilir.
rnein har UNICODE sisteminde u ekilde temsil edilir:
u+0131

Ayn ekilde a har bu sistemde u kod konumu ile gsterilir:


u+0061

Python programlama dilinde ise, yukardaki kod konumu dzeni yle gsterilir:
\\u0131

Grdnz gibi, Python UNICODE sistemindeki her bir kod konumunu gsterebilmek iin,
nce \u eklinde bir ka dizisi tanmlyor, ardndan UNICODE sisteminde + iaretinden sonra
gelen sayy bu ka dizisinin hemen sana ekliyor. Gelin kendi kendimize birka deneme
almas yapalm:
>>> '\u0130'

''

84 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

>>> '\u0070'

'p'

>>> "\ufdsf"

File "<stdin>", line 1


SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 0-4: truncated \uXXXX escape

Grdnz gibi, eer \u ka dizisinden sonra doru bir kod konumu belirtmezsek Python
bize bir hata mesaj gsteriyor...
Bu hata mesajnn, biraz nce print("Dosya konumu: C:\users\zeynep\gizli\dosya.txt")
kodunu yazdktan sonra aldmz hata ile ayn olduuna dikkat edin. Tpk \ufdsf rneinde
olduu gibi, \users ifadesi de varolan bir UNICODE kod konumuna karlk gelmedii iin,
Pythonn hata vermekten baka aresi kalmyor.
Biz bu rnekte users kelimesini kullanmaya alyoruz, ama u harnden hemen nce gelen
\ ka dizisi nedeniyle, hi farknda olmadan Python asndan nemli bir karakter dizisi (\u )
meydana getirmi oluyoruz. O yzden, byle can skc hatalarla karlamamak iin olas
ka dizilerine kar her zaman uyank olmamz gerekiyor.
Pek biz bu ka dizisi yznden, yazdmz programlarda Dosya konumu:
C:\users\zeynep\gizli\dosya.txt) gibi bir kt veremeyecek miyiz?
Verebileceimizi, ama bunun bir yolu yordam olduunu biliyorsunuz. Biz yine de tekrar
edelim:
>>> print("Dosya konumu: C:\\users\\zeynep\\gizli\\dosya.txt")

Dosya konumu: C:\users\zeynep\gizli\dosya.txt

Grdnz gibi, karakter dizisi iinde geen btn \ iaretlerini iftleyerek sorunumuzu
zdk. Buradaki gibi bir sorunla karlamamak iin, dizin adlarn ayrrken ters taksim
iareti yerine dz taksim iaretini kullanmay da tercih edebilirsiniz:
>>> print("Dosya konumu: C:/users/zeynep/gizli/dosya.txt")

Biraz sonra bu sorunu halletmenin nc ve daha kolay bir ynteminden daha sz edeceiz.
Ama biz imdilik bu ka dizisini bir kenara brakp baka bir ka dizisini incelemeye geelim.

7.9 Byk Unicode (\U)

Bu ka dizisi biraz nce grdmz \u adl ka dizisiyle hemen hemen ayn anlama
gelir. Bu ka dizisi de, tpk \u gibi, UNICODE kod konumlarn temsil etmek iin kullanlr.
Ancak U ile gsterilen kod konumlar u ile gsterilenlere gre biraz daha uzundur. rnein,
hatrlarsanz u ka dizisini kullanarak harnin UNICODE kod konumunu yle temsil
ediyorduk:
>>> '\u0131'

''

7.9. Byk Unicode (\U) 85


Python 3 iin Trke Klavuz, Srm 3

Eer ayn kod konumunu U adl ka dizisi ile gstermek istersek yle bir ey yazmamz
gerekir:
>>> '\U00000131'

Grdnz gibi, burada \U ka dizisinden sonra gelen ksm toplam 8 haneli bir saydan
oluuyor. u ka dizisinde ise bu ksm toplam 4 haneli bir say olarak yazyorduk. te \u
ka dizisi ile U ka dizisi arasndaki fark budur. u ka dizisi hakknda sylediimiz teki
her ey U ka dizisi iin de geerlidir.

7.10 Uzun Ad (\N)

UNICODE sistemi ile ilgili bir baka ka dizisi de \N adl ka dizisidir.


Dediimiz gibi, UNICODE sistemine ilikin ayrntlardan ilerleyen derslerde sz edeceiz, ama
bu sistemle ilgili ufak bir bilgi daha verelim.
UNICODE sisteminde her karakterin tek ve benzersiz bir kod konumu olduu gibi, tek ve
benzersiz bir de uzun ad vardr. rnein a harnin UNICODE sistemindeki uzun ad udur:
LATIN SMALL LETTER A

Bir karakterin UNICODE sistemindeki uzun adn renmek iin unicodedata adl bir
modlden yararlanabilirsiniz:
>>> import unicodedata
>>> unicodedata.name('a')

LATIN SMALL LETTER A

>>> unicodedata.name('')

LATIN CAPITAL LETTER S WITH CEDILLA

Bu arada, daha nce de sylediimiz gibi, bu modl kavramna imdilik taklmayn. lerde
modlleri ayrntl olarak inceleyeceiz. imdilik unicodedata denen eyin, (tpk daha nce
rneklerini grdmz os, sys ve keyword gibi) bir modl olduunu ve bu modl iindeki
name adl bir fonksiyonu kullanarak, parantez iinde belirttiimiz herhangi bir karakterin
UNICODE sistemindeki uzun adn elde edebileceimizi bilelim yeter.
te \N ka dizisi bu uzun isimleri, Python programlarmzda kullanma imkan verir bize.
Bu ka dizisini, karakterlerin UNICODE sistemindeki uzun adlar ile birlikte kullanarak asl
karakterleri elde edebiliriz. Dikkatlice bakn:
>>> print("\N{LATIN SMALL LETTER A}")

>>> print("\N{LATIN CAPITAL LETTER S WITH CEDILLA}")

>>> print("\Nisan")

File "<stdin>", line 1

86 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in


position 0-1: malformed \N character escape

Grdnz gibi, herhangi bir karl olmayan bir uzun ad belirttiimizde Python bize
bir hata mesaj gsteriyor. nk Python \N ka dizisinin hemen ardndan { iaretinin
getirilmesini ve sonra da UNICODE sistemi dahilinde geerli bir uzun ad belirtilmesini
bekliyor. Yukardaki rnekte \N ka dizisinden sonra { iareti yok. Zaten \N ka dizisinin
hemen ardndan gelen isan ifadesi de doru bir uzun ada iaret etmiyor. Dolaysyla da
Pythonn bize hata mesaj gstermekten baka aresi kalmyor...
\u, \U ve \N ka dizileri, UNICODE sistemi ile ilgili almalar yapmak isteyen programclar
iin Python programlama dilinin sunduu faydal aralardan yalnzca birkadr. Ancak bu
aralarn sizin iinize yaramayacan asla dnmeyin. Zira \u, \U ve \N ka dizileri ile ilgili
yukardaki durum hi beklemediiniz bir anda sizi de vurabilir. nk bu ka dizilerinin
oluturduu risk hi de yle nadir karlalacak bir sorun deildir.
Bildiiniz gibi Windows 7de kullancnn dosyalarn ieren dizin ad C:\Users\kullanc_ad
eklinde gsteriliyor. Dolaysyla Windows kullananlar UNICODE ka dizilerinden
kaynaklanan bu tuzaa her an debilir. Ya da eer adnz u veya n har ile balyorsa yine
bu tuzaa dme ihtimaliniz epey yksek olacak, C:\Users\umut veya C:\Users\Nihat gibi bir
dizin ad belirtirken ok dikkatli olmanz gerekecektir. Zira zellikle dosyalar zerinde ilem
yaparken, bu tr dizin adlarn sk sk kullanmak durumunda kalacaksnz. Bu yzden, alelade
bir kelime yazdnz zannederken hi farknda olmadan bir ka dizisi tanmlyor olma
ihtimalini her zaman gz nnde bulundurmal ve buna uygun nlemleri alm olmalsnz.

7.11 Onaltl Karakter (\x)

x har de \ iareti ile birletiinde zel anlam kazanarak bir ka dizisi meydana getirir.
\x ka dizisini kullanarak, onaltl (hexadecimal ) sayma sistemindeki bir saynn karakter
karln gsterebilirsiniz. Dikkatlice bakn:
>>> "\x41"

'A'

Onaltl sayma sistemindeki 41 says A harne karlk gelir. Eer hangi karakterlerin
hangi saylara karlk geldiini merak ediyorsanz http://www.ascii.cl/ adresindeki tabloyu
inceleyebilirsiniz. Bu tabloda hex stunu altnda gsterilen saylar onaltl saylar olup,
symbol stununda gsterilen karakterlere karlk gelirler. rnein hex stunundaki
4E says symbol stunundaki N harne karlk gelir. Bu durumu Pythonla da teyit
edebilirsiniz:
>>>"\x4E"

Eer saylarla karakterler arasndaki balantnn tam olarak ne olduunu bilmiyorsanz hi


endie etmeyin. Birka blm sonra saylarla karakterler arasnda nasl bir ba olduunu
gayet ayrntl bir ekilde anlatacaz. Biz imdilik yalnzca \x karakter dizisinin zel bir
ka dizisine karlk geldiini ve bu ka dizisini karakter dizileri iinde kullanrken dikkatli
olmamz gerektiini bilelim yeter:

7.11. Onaltl Karakter (\x) 87


Python 3 iin Trke Klavuz, Srm 3

>>> print("C:\Users\Aye\xp_dosyalar")

File "<stdin>", line 1


SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in
position 2-4: truncated \UXXXXXXXX escape

Grdnz gibi, Python \x ifadesinden sonra onaltl bir say belirtmenizi bekliyor.
Halbuki biz burada \x ifadesini xp_dosyalar adl dizini gsterebilmek iin kullanmtk.
Ama grne gre yanllkla Python iin zel bir anlam ifade eden bir karakter dizisi
oluturmuuz...

7.12 Etkisizletirme (r)

Dediimiz gibi, Pythondaki en temel ka dizisi \ iaretidir. Bu iaret baz baka harerle
birleerek yeni ka dizileri de oluturabilir.
Pythonda \ iaretinin dnda temel bir ka dizisi daha bulunur. Bu ka dizisi r hardir.
imdi bu ka dizisinin nasl kullanlacan ve ne ie yaradn inceleyelim:
yle bir kt vermek istediimizi dnn:
Kurulum dizini: C:\aylar\nisan\toplam masraf

Bildiimiz yoldan bu kty vermeye alrsak neler olacan adnz gibi biliyorsunuz:
>>> print("Kurulum dizini: C:\aylar\nisan\toplam masraf")

Kurulum dizini: C:ylar


isan oplam masraf

Not: Eer Windows zerinde alyorsanz bu komutu verdikten sonra bir !bip! sesi de
duymu olabilirsiniz...

Python tabii ki, karakter dizisi iinde geen \aylar, \nisan, ve \toplam masraf ifadelerinin
ilk karakterlerini yanl anlad! \a, \n ve \t gibi ifadeler Pythonn gznde birer ka dizisi.
Dolaysyla Python \a karakterlerini grnce bir !bip! sesi karyor, \n karakterlerini grnce
satr bana geiyor ve \t karakterlerini grnce de Tab tuuna baslm gibi bir tepki veriyor.
Sonu olarak da yukardaki gibi bir kt retiyor.
Daha nce bu durumu yle bir kod yazarak engellemitik:
>>> print("Kurulum dizini: C:\\aylar\\nisan\\toplam masraf")

Kurulum dizini: C:\aylar\nisan\toplam masraf

Burada, \ iaretlerinin her birini iftleyerek sorunun stesinden geldik. Yukardaki yntem
doru ve kabul grm bir zmdr. Ama bu sorunun stesinden gelmenin ok daha basit
ve pratik bir yolu var. Bakalm:
>>> print(r"Kurulum dizini: C:\aylar\nisan\toplam masraf")

Kurulum dizini: C:\aylar\nisan\toplam masraf

88 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, karakter dizisinin ba ksmnn d tarafna bir adet r har yerletirerek
sorunun stesinden geliyoruz. Bu ka dizisinin, kullanm asndan teki ka dizilerinden
farkl olduuna dikkat edin. teki ka dizileri karakter dizisinin iinde yer alrken, bu ka
dizisi karakter dizisinin dna yerletiriliyor.
Bu ka dizisinin tam olarak nasl ilediini grmek iin dilerseniz bir rnek daha verelim:
>>> print("Ka dizileri: \, \n, \t, \a, \\, r")

Ka dizileri: \,
, , , \, r

Burada da Python bizim yapmak istediimiz eyi anlayamad ve karakter dizisi iinde geen
ka dizilerini dorudan ekrana yazdrmak yerine bu ka dizilerinin ilevlerini yerine
getirmesine izin verdi. Tpk biraz nceki rnekte olduu gibi, istersek ka dizilerini
iftleyerek bu sorunu aabiliriz:
>>> print("Ka dizileri: \\, \\n, \\t, \\a, \\\, r")

Ka dizileri: \, \n, \t, \a, \\, r

Ama tabii ki bunun ok daha kolay bir yntemi olduunu biliyorsunuz:


>>> print(r"Ka dizileri: \, \n, \t, \a, \\, r")

Ka dizileri: \, \n, \t, \a, \\, r

Grdnz gibi, karakter dizisinin bana getirdiimiz r ka dizisi, karakter dizisi iinde
geen ka dizilerinin ilevlerini yerine getirmesine engel olarak, istediimiz kty elde
etmemizi salyor.
Bu arada bu ka dizisini, daha nce rendiimiz \r adl ka dizisi ile kartrmamaya dikkat
ediyoruz.
Pythondaki btn ka dizilerinden sz ettiimize gre, konuyu kapatmadan nce nemli bir
ayrntdan sz edelim.
Pythonda karakter dizilerinin sonunda sadece ift sayda \ iareti bulunabilir. Tek sayda
\ iareti kullanldnda karakter dizisini bitiren trnak iareti etkisizleecei iin akma
sorunu ortaya kar. Bu etkisizlemeyi, karakter dizisinin bana koyduunuz r ka dizisi
de engelleyemez. Yani:
>>> print("Ka dizisi: \")

Bu ekilde bir tanmlama yaptmzda Python bize bir hata mesaj gsterir. nk kapan
trnann hemen ncesine yerletirdiimiz \ ka dizisi, Pythonn karakter dizisini kapatan
trnak iaretini grmezden gelmesine yol aarak bu trna etkisizletiriyor. Bylece sanki
karakter dizisini tanmlarken kapan trnan hi yazmamz gibi bir sonu ortaya kyor:
>>> print("Ka dizisi: \")
File "<stdin>", line 1
print("Ka dizisi: \")
^
SyntaxError: EOL while scanning string literal

stelik bu durumu, r adl ka dizisi de engelleyemiyor:

7.12. Etkisizletirme (r) 89


Python 3 iin Trke Klavuz, Srm 3

>>> print(r"Ka dizisi: \")


File "<stdin>", line 1
print(r"Ka dizisi: \")
^
SyntaxError: EOL while scanning string literal

zm olarak birka farkl yntemden yararlanabilirsiniz. Mesela karakter dizisini


kapatmadan nce karakter dizisinin sonundaki \ iaretinin sana bir adet boluk karakteri
yerletirmeyi deneyebilirsiniz:
>>> print("Ka dizisi: \ ")

Veya ka dizisini iftleyebilirsiniz:


>>> print("Ka dizisi: \\")

Ya da karakter dizisi birletirme yntemlerinden herhangi birini kullanabilirsiniz:


>>> print("Ka dizisi: " + "\\")
>>> print("Ka dizisi:", "\\")
>>> print("Ka dizisi: " "\\")

Byle bir durumla ilk kez karlatnzda bunun Python programlama dilinden kaynaklanan
bir hata olduunu dnebilirsiniz, ancak bu durum Pythonn resmi internet sitesinde Ska
Sorulan Sorular blmne alnacak kadar nemli bir tasarm tercihidir: http://goo.gl/i3tkk

7.13 Sayfa Ba (\f)

\f artk gnmzde pek kullanlmayan bir ka dizisidir. Bu ka dizisinin grevi, zellikle


eski yazclarda, bir sayfann sona erip yeni bir sayfann baladn gstermektir. Dolaysyla
eski model yazclar, bu karakteri grdkleri noktada mevcut sayfay sona erdirip yeni bir
sayfaya geer.
Bu ka dizisinin tam olarak ne ie yaradn test etmek iin u kodlar altrn:
>>> f = open("deneme.txt", "w")
>>> print("deneme\fdeneme", file=f)
>>> f.close()

imdi bu kodlarla oluturduunuz deneme.txt adl dosyay LibreOce veya Microsoft Word
gibi bir programla an. deneme satrlarnn iki farkl sayfaya yazdrldn greceksiniz. Bu
arada, eer Microsoft Word dosyay aarken bir hata mesaj gsterirse, o hata mesajna birka
kez tamam diyerek hata penceresini kapatn. Dosya normal bir ekilde alacaktr.
Dediimiz gibi, bu ka dizisi artk pek kullanlmyor. Ama yine de bu ka dizisine kar
da uyank olmalsnz. nk bu ka dizisi de beklemediiniz ktlar almanza yol aabilir.
Mesela u rnee bir bakalm:
>>> "\frat"

'\x0crat'

Grdnz gibi, siz aslnda \frat yazmak isterken, Python bu kelimenin ba tarafndaki \f
karakter dizisini bir ka dizisi olarak deerlendirip ona gre bir kt verdi.

90 Blm 7. Ka Dizileri
Python 3 iin Trke Klavuz, Srm 3

Btn bu anlattklarmzn ardndan, ka dizilerinin, birletirildikleri karakterlerin farkl bir


anlam yklenmesini salayan birtakm iaretler olduunu anlyoruz. rnein \ iareti (tek
trnak) iareti ile bir araya gelerek, tek trnak iaretinin karakter dizisi tanmlama dnda baka
bir anlam yklenmesini salyor. Ayn ekilde yine \ iareti (ift trnak) iareti ile birleerek
ift trnak iaretinin de karakter dizisi tanmlama dnda bir anlama kavumasn salyor.
Bylece trnak iaretlerini karakter dizileri iinde rahatlkla kullanabiliyoruz.
Ya da yine \ iareti n har ile bir araya gelip, bu harn satr bana geilmesini salayan bir
ka dizisi oluturmasn mmkn klyor. Veya ayn iaret t haryle birleip, eler arasnda
sekme oluturulmasn salayabiliyor. Bu aralar sayesinde ekrana yazdrdmz bir metnin
akn kontrol etme imkanna kavuuyoruz.

7.14 Ka Dizilerine Toplu Bak

Biraz sonra bu nemli konuyu kapatacaz. Ama dilerseniz kapatmadan nce, bu blmde
rendiimiz ka dizilerini yle bir topluca grelim:
Ka Dizisi Anlam
\ Karakter dizisi iinde tek trnak iaretini kullanabilmemizi salar.
\ Karakter dizisi iinde ift trnak iaretini kullanabilmemizi salar.
\\ Karakter dizisi iinde \ iaretini kullanabilmemizi salar.
\n Yeni bir satra gememizi salar.
\t Karakterler arasnda sekme boluu brakmamz salar.
\u UNICODE kod konumlarn gsterebilmemizi salar.
\U UNICODE kod konumlarn gsterebilmemizi salar.
\N Karakterleri UNICODE adlarna gre kullanabilmemizi salar.
\x Onaltl sistemdeki bir saynn karakter karln gsterebilmemizi salar.
\a Destekleyen sistemlerde, kasa hoparlrnden bir bip sesi verilmesini
salar.
\r Ayn satrn bana dnlmesini salar.
\v Destekleyen sistemlerde dey sekme oluturulmasn salar.
\b mlecin sola doru kaydrlmasn salar
\f Yeni bir sayfaya geilmesini salar.
r Karakter dizisi iinde ka dizilerini kullanabilmemizi salar.
Ka dizileriyle ilgili son olarak unu syleyebiliriz: Ka dizileri, grmezden gelebileceiniz,
renmesem de olur, diyebileceiniz nemsiz birtakm iaretler deildir. Bu konu
boyunca verdiimiz rneklerden de grdnz gibi, ka dizileri, kullancya gstereceiniz
metinlerin biimini dorudan etkiliyor. Btn bu rnekler, bu ka dizilerinin yersiz
veya yanl kullanlmasnn ya da bunlarn bir metin iinde gzden kamasnn, yazdnz
programlarn hata verip kmesine, yani programnzn durmasna sebep olabileceini de
gsteriyor bize.
Bylece bir blm daha bitirmi olduk. Artk Pythonla gerek programlar yazmamzn
nnde hibir engel kalmad.

7.14. Ka Dizilerine Toplu Bak 91


BLM 8

Programlar Kaydetme ve altrma

Bu noktaya kadar btn ilerimizi Pythonn etkileimli kabuu zerinden hallettik. Her ne
kadar etkileimli kabuk son derece kullanl bir ortam da olsa, bizim asl alma alanmz
deildir. Daha nce de dediimiz gibi, etkileimli kabuu genellikle ufak tefek Python kodlarn
test etmek iin kullanacaz. Ama asl programlarmz tabii ki etkileimli kabua deil,
program dosyasna yazacaz.
Ne dedik? zellikle kk kod paralar yazp bunlar denemek iin etkileimli kabuk
mkemmel bir ortamdr. Ancak kodlar oalp bymeye balaynca bu ortam yetersiz
gelmeye balayacaktr. stelik tabii ki yazdnz kodlar bir yere kaydedip saklamak
isteyeceksiniz. te burada metin dzenleyiciler devreye girecek.
Python kodlarn yazmak iin istediiniz herhangi bir metin dzenleyiciyi kullanabilirsiniz.
Hatta Notepad bile olur. Ancak Python kodlarn ayrt edip renklendirebilen bir metin
dzenleyici ile yola kmak her bakmdan hayatnz kolaylatracaktr.

Not: Python kodlarnz yazmak iin Microsoft Word veya OpenOce.Org OOWriter gibi,
belgeleri ikili (binary ) dzende kaydeden programlar uygun deildir. Kullanacanz metin
dzenleyici, belgelerinizi dz metin (plain text ) biiminde kaydedebilmeli.

Biz bu blmde farkl iletim sistemlerinde, metin dzenleyici kullanlarak Python


programlarnn nasl yazlacan ve bunlarn nasl altrlacan tek tek inceleyeceiz.
Daha nce de sylediimiz gibi, hangi iletim sistemini kullanyor olursanz olun, hem
Windows hem de GNU/Linux bal altnda yazlanlar okumalsnz.
Dilerseniz nce GNU/Linux ile balayalm:

8.1 GNU/Linux

Eer kullandnz sistem GNU/Linuxta Unity veya GNOME masast ortam ise balang
dzeyi iin Gedit adl metin dzenleyici yeterli olacaktr.
Eer kullandnz sistem GNU/Linuxta KDE masast ortam ise Kwrite veya Kate adl metin
dzenleyicilerden herhangi birini kullanabilirsiniz. u aamada kullanm kolayl ve sadelii
nedeniyle Kwrite nerilebilir.
e yeni bir Gedit belgesi aarak balayalm. Yeni bir Gedit belgesi amann en kolay yolu
Alt+F2 tularna bastktan sonra kan ekranda:

92
Python 3 iin Trke Klavuz, Srm 3

gedit

yazp Enter dmesine basmaktr.


Eer Gedit yerine mesela Kwrite kullanyorsanz, yeni bir Kwrite belgesi oluturmak iin Alt+F2
tularna bastktan sonra:
kwrite

komutunu vermelisiniz. Elbette kullanacanz metin dzenleyiciye, komut vermek yerine,


datmnzn menleri araclyla da ulaabilirsiniz.
Python kodlarmz, karmza kan bu bo metin dosyasna yazp kaydedeceiz.
Aslnda kodlar metin dosyasna yazmakla etkileimli kabua yazmak arasnda ok fazla fark
yoktur. Dilerseniz hemen bir rnek vererek ne demek istediimizi anlatmaya alalm:
1. Bo bir Gedit ya da Kwrite belgesi ayoruz ve bu belgeye u kodlar eksiksiz bir ekilde
yazyoruz:
tarih = "02.01.2012"
gn = "Pazartesi"
vakit = "leden sonra"

print(tarih, gn, vakit, "bulualm", end=".\n")

2. Bu kodlar yazp bitirdikten sonra dosyay masastne randevu.py adyla kaydedelim.


3. Sonra iletim sistemimize uygun bir ekilde komut satrna ulaalm.
4. Ardndan komut satr zerinden masastne gelelim. (Bunun nasl yaplacan
hatrlyorsunuz, deil mi?)
5. Son olarak u komutla programmz altralm:
python3 randevu.py

yle bir kt alm olmalyz:


02.01.2012 Pazartesi leden sonra bulualm.

Eer bu kt yerine bir hata mesaj alyorsanz bunun birka farkl sebebi olabilir:
1. Kodlarda yazm hatas yapm olabilirsiniz. Bu ihtimali bertaraf etmek iin yukardaki
kodlarla kendi yazdnz kodlar dikkatlice karlatrn.
2. Kodlarnz kaydettiiniz randevu.py adl dosyann adn yanl yazm olabilirsiniz.
Dolaysyla python3 randevu.py komutu, var olmayan bir dosyaya atfta bulunuyor
olabilir.
3. python3 randevu.py komutunu verdiiniz dizin konumu ile randevu.py dosyasnn
bulunduu dizin konumu birbirinden farkl olabilir. Yani siz randevu.py dosyasn
masastne kaydetmisinizdir, ama python3 randevu.py komutunu yanllkla baka
bir dizin altnda veriyor olabilirsiniz. Bu ihtimali ortadan kaldrmak iin, nceki derslerde
rendiimiz yntemleri kullanarak hangi dizin altnda bulunduunuzu kontrol edin.
O anda iinde bulunduunuz dizinin ieriini listeleyerek, randevu.py dosyasnn
orada grnp grnmediini kontrol edebilirsiniz. Eer program dosyanz bu listede
grnmyorsa, elbette python3 randevu.py komutu almayacaktr.

8.1. GNU/Linux 93
Python 3 iin Trke Klavuz, Srm 3

4. Geen derslerde anlattmz ekilde Python3 kaynaktan root haklaryla derlemenize


ramen, derleme sonrasnda /usr/bin/ dizini altna python3 adl bir sembolik ba
oluturmadnz iin python3 komutu almyor olabilir.
5. Eer Python3 yetkisiz kullanc olarak derlediyseniz, $HOME/python/bin/ dizini altnda
hem python3 adl bir sembolik ba oluturmu, hem de $HOME/python/bin/ dizinini
YOLa (PATH ) eklemi olmanz gerekirken bunlar yapmam olabilirsiniz.
6. Asla unutmayn, Pythonn etkileimli kabuunu balatmak iin hangi komutu
kullanyorsanz, randevu.py dosyasn altrmak iin de ayn komutu kullanacaksnz.
Yani eer Pythonn etkileimli kabuunu python3.5 gibi bir komutla altryorsanz,
programnz da python3.5 randevu.py eklinde altrmanz gerekir. Ayn ekilde,
eer etkileimli kabuu mesela python (veya py3) gibi bir komutla altryorsanz,
programnz da python randevu.py (veya py3 randevu.py) eklinde altrmalsnz.
Neticede etkileimli kabuu altrrken de, bir program dosyas altrrken de aslnda
temel olarak Python programlama dilini altrm oluyorsunuz. Python programn
altrrken bir dosya ad belirtmezseniz, yani Python balatan komutu tek bana
kullanrsanz etkileimli kabuk almaya balar. Ama eer Python balatan komutla
birlikte bir program dosyas ismi de belirtirseniz, o belirttiiniz program dosyas
almaya balar.
Kodlarnz dzgn bir ekilde altrabildiinizi varsayarak yolumuza devam edelim...
Grdnz gibi, kod dosyamz altrmak iin python3 komutundan yararlanyoruz. Bu
arada tekrar etmekte fayda var: Pythonn etkileimli kabuunu altrmak iin hangi
komutu kullanyorsanz, dosyaya kaydettiiniz programlarnz altrmak iin de ayn komutu
kullanacaksnz.
Gelelim Windows kullanclarna...

8.2 Windows

Daha nce de sylediimiz gibi, Python kodlarmz yazmak iin istediimiz bir metin
dzenleyiciyi kullanabiliriz. Hatta Notepadi bile kullansak olur. Ancak Notepadden biraz
daha gelimi bir metin dzenleyici ile balamak iinizi kolaylatracaktr.
Python programlama dilini renmeye yeni balayan Windows kullanclar iin en uygun
metin dzenleyici IDLEdr. Balat > Tm Programlar > Python 3.5 > IDLE (Python GUI) yolunu
takip ederek IDLEa ulaabilirsiniz.
IDLE atnzda yle bir ekranla karlaacaksnz:

Aslnda bu ekran size bir yerlerden tandk geliyor olmal. Dikkat ederseniz beyaz ekrann en
sonunda bordo renkli bir >>> iareti var. Evet, tahmin ettiiniz gibi, buras aslnda Pythonn
etkileimli kabuudur. Yani o siyah etkileimli kabuk ekrannda ne yapabilirseniz burada da
ayn eyi yapabilirsiniz. Dilerseniz kendi kendinize baz denemeler yapn. Ama u anda biz
IDLEn bu zelliini deil, metin dzenleyici olma zelliini kullanacaz. O yzden yolumuza
devam ediyoruz.

94 Blm 8. Programlar Kaydetme ve altrma


Python 3 iin Trke Klavuz, Srm 3

Not: Dediimiz gibi, yukarda grnen ekran aslnda Pythonn etkileimli kabuudur.
Dolaysyla biraz sonra gstereceimiz kodlar buraya yazmayacaz. Python programlama
diline yeni balayanlarn en sk yapt hatalardan biri de, kaydetmek istedikleri kodlar
yukarda grnen ekrana yazmaya almalardr. Unutmayn, Pythonn etkileimli
kabuunda ne yapabiliyorsanz, IDLE atnzda ilk karnza kan ekranda da onu
yapabilirsiniz. Pythonn etkileimli kabuunda yazdnz kodlar etkileimli kabuu
kapattnzda nasl kayboluyorsa, yukardaki ekrana yazdnz kodlar da IDLE kapattnzda
kaybolur...

Bir nceki ekranda sol st kede File [Dosya] mens gryorsunuz. Oraya tklayn ve men
iindeki New Window [Yeni Pencere] dmesine basn. yle bir ekranla karlaacaksnz:

te Python kodlarmz bu beyaz ekrana yazacaz. imdi bu ekrana u satrlar yazalm:


tarih = "02.01.2012"
gn = "Pazartesi"
vakit = "leden sonra"

print(tarih, gn, vakit, "bulualm", end=".\n")

Bu noktadan sonra yapmamz gereken ey dosyamz kaydetmek olacak. Bunun iin File >
Save as yolunu takip ederek programmz masastne randevu.py adyla kaydediyoruz.
u anda programmz yazdk ve kaydettik. Artk programmz altrabiliriz. Bunun iin
IDLEda Run > Run Module yolunu takip etmeniz veya ksaca F5 tuuna basmanz yeterli
olacaktr. Bu iki yntemden birini kullanarak programnz altrdnzda yle bir kt elde
edeceksiniz:
02.01.2012 Pazartesi leden sonra bulualm.

Tebrikler! lk Python programnz yazp altrdnz... Eer altramadysanz veya


yukardaki kt yerine bir hata mesaj aldysanz muhtemelen kodlar yazarken yazm hatas
yapmsnzdr. Kendi yazdnz kodlar buradaki kodlarla dikkatlice karlatrp tekrar
deneyin.
imdi gelin isterseniz yukarda yazdmz kodlar yle bir ksaca inceleyelim.
Programmzda farkl deiken tanmladmza dikkat edin. Bu deikenler tarih, gn ve
vakit adl deikenlerdir. Daha sonra bu deikenleri birbiriyle birletiriyoruz. Bunun iin
print() fonksiyonundan nasl yararlandmz gryorsunuz. Ayrca print() fonksiyonunu
kullan biimimize de dikkat edin. Buradaki end parametresinin anlamn ve bunun ne ie
yaradn artk gayet iyi biliyorsunuz. end parametresi yardmyla cmlenin en sonuna bir
adet nokta yerletirip, \n adl ka dizisi yardmyla da bir alt satra geiyoruz.
Bylece basit bir Python programnn temel olarak nasl yazlp bir dosyaya kaydedileceini
ve bu programn nasl altrlacan renmi olduk.

8.2. Windows 95
BLM 9

alma Ortam Tavsiyesi

Bu blmde, Python programlar gelitirirken rahat bir alma ortam elde edebilmek iin
yapmanz gerekenleri sralayacaz. ncelikle Windows kullanclarndan balayalm.

9.1 Windows Kullanclar

Windowsta bir Python program yazp kaydettikten sonra bu program komut satrndan
altrabilmek iin, MS-DOSu ap, ncelikle cd komutuyla programn bulunduu dizine
ulamamz gerekir. lgili dizine ulatktan sonra programmz python program_ad
komutuyla altrabiliriz. Ancak bir sre sonra, program altrmak iin her defasnda
programn bulunduu dizine ulamaya almak skc bir hal alacaktr. Ama bu konuda
aresiz deiliz.
Windows 7, istediimiz dizin altnda bir MS-DOS ekran aabilmemiz iin bize ok gzel bir
kolaylk sunuyor. Normal artlar altnda mesela masastnde bir MS-DOS ekran aabilmek
iin u yolu izlemeniz gerekiyor:
1. Windows logolu tua ve R tuuna birlikte bas,
2. Alan pencereye cmd yazp Enter dmesine bas,
3. Bu ekilde ulatn MS-DOS ekrannda cd Desktop komutunu ver.
Bu admla, MS-DOS ekran zerinden masastne ulam oluyoruz. Ama aslnda bunun
ok daha kolay bir yolu var: Masastne sa tklarken Shift tuunu da basl tutarsanz, sa-tk
mensnde Komut penceresini burada a adl bir satr grrsnz. te bu satra tklayarak,
MS-DOS komut satrn tek harekette masast konumunda altrabilirsiniz. Elbette bu
zellik sadece masast iin deil, btn konumlar iin geerlidir. Yani bilgisayarnzda
herhangi bir yere sa tklarken Shift tuunu da basl tutarak o konumda bir MS-DOS
penceresi aabilirsiniz.
Ayrca, herhangi bir klasr akken dosya taraycsnn adres ubuuna cmd yazp
Enter dmesine basarak da, o klasrn bulunduu konumda bir komut ekran
aabilirsiniz. rnein eer o anda nnzde ndirilenler (veya Kardan Yklenenler)
dizini aksa, adres ubuuna (aadaki resimde krmz ile gsterilen blge) cmd yazarak
C:\Users\Kullanc\Downloads> konumunda bir komut ekran aabilirsiniz.
kinci olarak, alma kolayl asndan Windowsta dosya uzantlarnn her zaman
grnmesini salamanz da tavsiye ederim. Windows ilk kurulduunda hibir dosyann
uzants grnmez. Yani mesela deneme.txt adl bir dosya Windows ilk kurulduunda
deneme eklinde grnecektir. Bu durumda, bir dosyann uzantsn deitirmek

96
Python 3 iin Trke Klavuz, Srm 3

istediinizde baz skntlar yaarsnz. rnein, masastnde bir metin dosyas


oluturduunuzu varsayalm. Diyelim ki amacnz bu dosyann iine bir eyler yazp daha
sonra mesela bu dosyann uzantsn .bat veya .py yapmak olsun. Byle bir durumda,
dosya uzantlarn gremediiniz iin, metin dosyasnn uzantsn deitirmeye altnzda
deneme.bat.txt gibi bir dosya ad elde edebilirsiniz. Tabii ki bu dosya bir .bat dosyas deil, bir
.txt, yani metin dosyasdr. Dolaysyla aslnda dosya uzantsn deitirememi oluyorsunuz.
Yukardaki nedenlerden tr, ben size u yolu takip ederek dosya uzantlarn her zaman
grnr hale getirmenizi neririm:
1. Balat > Denetim Masas yolunu takip ederek denetim masasna ulan,
2. Denetim masasnda Grnm ve Kiiselletirme seeneine tklayn,
3. Alan mennn sa tarafnda Klasr Seenekleri satrna tklayn,
4. Alan pencerede Grnm sekmesine tklayn,
5. Gelimi Ayarlar listesinde Bilinen dosya trleri iin uzantlar gizle seeneinin
yanndaki onay iaretini kaldrn,
6. Uygula ve Tamam dmelerine basarak btn pencereleri kapatn,
7. Artk btn dosyalarnzn uzants da grnecei iin, uzant deitirme ilemlerini ok
daha kolay bir ekilde halledebilirsiniz.

9.1. Windows Kullanclar 97


Python 3 iin Trke Klavuz, Srm 3

9.2 GNU/Linux Kullanclar

Eer KDE temelli bir GNU/Linux datm kullanyorsanz, yazp kaydettiiniz Python
programn barndran dizin akken F4 tuuna bastnzda, komut satr o dizin altnda
alacaktr.
Unity ve GNOME kullanclarnn ise benzer bir kolayla ulamak iin nautilus-open-terminal
adl betii sistemlerine kurmalar gerekiyor. Eer Ubuntu kullanyorsanz bu betii u komutla
kurabilirsiniz:
sudo apt-get install nautilus-open-terminal

Bu betii kurduktan sonra bilgisayarnz yeniden balatn veya u komutu verin:


killall nautilus

Artk komut satrn hangi dizin altnda balatmak istiyorsanz o dizine sa tklayn. Menler
arasnda Open in Terminal [Ubirimde a] adl bir seenek greceksiniz. Buna tkladnzda
o dizin altnda bir komut satr penceresi alacaktr.

9.3 Metin Dzenleyici Ayarlar

Daha nce de sylediimiz gibi, Python ile program yazmak iin istediiniz metin dzenleyiciyi
kullanabilirsiniz. Ama kodlarnzn kusursuz grnmesi ve hatasz almas iin kullandnz
metin dzenleyicide birtakm ayarlamalar yapmanz gerekir. te bu blmde bu ayarlarn
neler olduunu gstereceiz.
Eer programlarnz IDLE ile yazyorsanz aslnda bir ey yapmanza gerek yok. IDLE Python
ile program yazmak zere tasarlanm bir dzenleyici olduu iin bu programn btn ayarlar
Python ile uyumludur. Ama eer IDLE dnda bir metin dzenleyici kullanyorsanz bu
dzenleyicide temel olarak u ayarlar yapmanz gerekir:
1. Sekme geniliini [TAB width ] 4 olarak ayarlayn.
2. Girinti geniliini [Indent width ] 4 olarak ayarlayn.
3. Girintilemede sekme yerine boluk kullanmay tercih edin [Use spaces instead of tabs ]
4. Tercih edilen kodlama biimini [Preferred encoding ] utf-8 olarak ayarlayn.
zellikle son sylediimiz kodlama biimi ayar ok nemlidir. Bu ayarn yanl olmas
halinde, yazdnz program altrmak istediinizde yle bir hata alabilirsiniz:
SyntaxError: Non-UTF-8 code starting with '\xfe' in file deneme.py on line 1,
but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

Eer yazdnz bir program byle bir hata mesaj retiyorsa, ilk olarak metin dzenleyicinizin
kodlama biimi (encoding ) ayarlarn kontrol edin. Metin dzenleyiciler genellikle tercih
edilen kodlama biimini aadaki rnek resimde grld gibi, durum ubuunda srekli
olarak gsterir.

98 Blm 9. alma Ortam Tavsiyesi


Python 3 iin Trke Klavuz, Srm 3

Ancak kodlama biimi doru bir ekilde utf-8 olarak ayarlanm metin dzenleyicilerde,
zellikle internet zerinden kod kopyalanp yaptrlmas srasnda bu ayar siz farknda
olmadan deiebilir. Byle bir durumda da program alrken yukarda bahsedilen hatay
alabilirsiniz. Dolaysyla, programnz yazdnz metin dzenleyicinin kodlama ayarlarnn siz
farknda olmadan deime ihtimaline kar uyank olmanz gerekir.
Elbette piyasada yzlerce metin dzenleyici olduu iin yukarda bahsedilen ayarlarn her
metin dzenleyicide nasl yaplacan tek tek gstermemiz mmkn deil. Ancak iyi bir
metin dzenleyicide yukardaki ayarlarn hepsi bulunur. Tek yapmanz gereken, bu ayarlarn,
kullandnz metin dzenleyicide nereden yapldn bulmak. Eer kullandnz metin
dzenleyiciyi ayarlamakta zorlanyorsanz, her zamanki gibi istihza.com/forum adresinde
skntnz dile getirebilirsiniz.
Kodlama biimi kavramndan sz etmiken, Pythonla ilgili nemli bir konuya daha deinelim.
En bata da sylediimiz gibi, u anda piyasada Python iki farkl seri halinde gelitiriliyor.
Bunlardan birinin 2.x serisi, brnn de 3.x serisi olduunu biliyoruz. Pythonn 2.x serisinde
Trke karakterlerin gsterimi ile ilgili ok ciddi problemler vard. rnein Pythonn 2.x
serisinde yle bir kod yazamyorduk:
print("Gnaydn irin Baba!")

Bu kodu bir dosyaya kaydedip, Pythonn 2.x serisine ait bir srmle altrmak istediimizde
Python bize yle bir hata mesaj veriyordu:
SyntaxError: Non-ASCII character '\xc3' in file
test.py on line 1, but no encoding declared;
see http://www.python.org/peps/pep-0263.html for details

Bunun sebebi, Pythonn 2.x srmlerinde ASCII adl kodlama biiminin kullanlyor olmasdr.
Zaten hata mesajna baktmzda da, Pythonn ASCII olmayan karakterlerin varlndan
ikayet ettiini gryoruz.
Yukardaki kodlarn alabilmesi iin programmza yle bir ekleme yapmamz gerekiyordu:
# -*- coding: utf-8 -*-
print("Gnaydn irin Baba!")

Buradaki ilk satra dikkat edin. Bu kodlarla yaptmz ey, Pythonn ASCII adl kodlama biimi
yerine UTF-8 adl kodlama biimini kullanmasn salamaktr. ASCII adl kodlama biimi
Trke karakterleri gsteremez, ama UTF-8 adl kodlama biimi Trke karakterleri ok rahat
bir ekilde gsterebilir.

Not: Kodlama biimlerinden, ileride ayrntl bir ekilde sz edeceiz. O yzden bu


anlattklarmzda eer anlamadnz yerler olursa bunlara taklmanza gerek yok.

Pythonn 3.x serisinin gelii ile birlikte Pythonda ntanml olarak ASCII yerine UTF-8
kodlama biimi kullanlmaya baland. Dolaysyla yazdmz programlara # -*- coding:
utf-8 -*- satrn eklememize gerek kalmad. nk zaten Python UTF-8 kodlama biimini

9.3. Metin Dzenleyici Ayarlar 99


Python 3 iin Trke Klavuz, Srm 3

ntanml olarak kendisi kullanyor. Ama eer UTF-8 dnda baka bir kodlama biimine
ihtiya duyarsanz yine bu satrdan yararlanabilirsiniz.
rnein GNU/Linux datmlarnn geleneksel olarak UTF-8 kodlama biimi ile aras
iyidir. Dolaysyla eer GNU/Linux zerinde Python programlar gelitiriyorsanz bu
satr hi yazmadan bir mr geirebilirsiniz. Ama Windows iletim sistemleri UTF-8 i
desteklemekle birlikte, bu destek GNU/Linuxtaki kadar iyi deildir. Dolaysyla zaman zaman
Windowsta UTF-8 dnda baka bir kodlama biimini kullanmanz gerekebilir. rnein
yazdnz bir programda Trke karakterleri gremiyorsanz, programnzn ilk satrn yle
dzenleyebilirsiniz:
# -*- coding: cp1254 -*-

Burada UTF-8 yerine cp1254 adl kodlama biimini kullanm oluyoruz. Windows iletim
sisteminde cp1254 adl kodlama biimi UTF-8 e kyasla daha fazla desteklenir.

9.4 MS-DOS Komut Satr Ayarlar

Eer yukarda anlattmz btn ayarlar doru bir ekilde yapmanza ramen, zellikle
MS-DOS komut satrnda hala Trke karakterleri dzgn grntleyemiyorsanz,
kullandnz Windows srmnn komut satr, ntanml olarak Trke karakterleri
gsteremeyen bir yaz tipine ayarlanm olabilir. Dolaysyla Trke karakterleri
gsterebilmek iin ncelikle uygun bir yaz tipi semeniz gerekir. Bunun iin u basamaklar
takip ediyoruz:
1. Komut satrn ayoruz,
2. Alan pencerenin balk ubuuna sa tklayarak, zellikler mensne giriyoruz,
3. Yaz tipi sekmesinde yaz tipi olarak Lucida Consoleu (veya varsa Consolas) seiyoruz,
4. Tamam dmesine basyoruz.
5. Eer nnze bir onay penceresi alrsa, zellikleri ayn balkla ileride oluturulacak
pencereler iin kaydet seeneini iaretleyip Tamama bastktan sonra kyoruz.
6. Bu ilemin nasl yaplacan gsteren bir videoyu
http://media.istihza.com/videos/ms-dos.swf adresinden izleyebilirsiniz.
Bylece MS-DOS komut satr iin Trke karakterleri gsterebilen bir yaz tipi belirlemi
olduk. Ancak bu, Trke karakterleri dzgn grntlemeye yetmeyebilir. Eer Trke
karakterler hala dzgn grnmyorsa, kullandnz sistemde MS-DOSun dil kodlamas
Trke karakterleri grntlemeye uygun olmayabilir. Trke karakterleri gsterebilen bir
dil kodlamas belirlemek iin komut satrnda u komutu verin:
chcp 1254

CP1254, Trke karakterleri de ieren bir dil kodlamasdr. Bu komutu verdikten sonra artk
Trke karakterleri dzgn grntleyebiliyor olmanz lazm.

9.5 Program rnekleri

Yukarda Python ve programlamaya ilikin pek ok teknik bilgi verdik. Bunlar renmemiz,
ilerimizi kuru kuruya ezberleyerek deil, anlayarak yapmamz salamas asndan byk

100 Blm 9. alma Ortam Tavsiyesi


Python 3 iin Trke Klavuz, Srm 3

nem tayordu. Ancak yukarda pratie ynelik pek bir ey sunamadk. te bu blmde
pratik eksikliimizi biraz olsun kapamaya dnk rnekler yapacaz.
Hatrlarsanz Pythonla tanmamz salayan ilk rneimiz ekrana basit bir Merhaba Zalim
Dnya! cmlesi yazdrmakt. Bu ilk rnei etkileimli kabukta verdiimizi hatrlyorsunuz:
>>> "Merhaba Zalim Dnya!"

Ama artk programlarmz dosyaya kaydetmeyi rendiimize gre bu kodlar etkileimli


kabua yazmak yerine bir dosyaya yazmay tercih edebiliriz. Bu sayede yazdmz kodlar
kalclk kazanacaktr.
Hemen bir deneme yapalm. Bo bir metin belgesi ap oraya u satr yazalm:
"Merhaba Zalim Dnya!"

imdi de bu dosyay daha nce anlattmz ekilde masastne deneme.py adyla kaydedip
programmz altralm.
Ne oldu? Programnz hibir kt vermeden kapand, deil mi?
Hemen hatrlayacanz gibi, print() fonksiyonu iine alnmayan ifadelerin ekrana kt
olarak verilebilmesi sadece etkileimli kabua zg bir durumdur. Programlarmz dosyadan
altrrken, print() fonksiyonu iine alnmayan ifadeler ekranda grnmeyecektir.
Yukardaki rnek bu durumun bir gstergesidir. Dolaysyla yukardaki ifadenin ekrana kt
olarak verilebilmesi iin o kodu yle yazmamz gerekiyor:
print("Merhaba Zalim Dnya!")

Programnz bu ekilde tekrar altrdnzda yle bir kt alyoruz:


Merhaba Zalim Dnya!

Bu olduka basit bir rnekti. imdi biraz daha karmak bir rnek verelim.
Yine hatrlayacanz gibi, nceki blmlerden birinde aylk yol masrafmz hesaplayan bir
program yazmtk.
Orada elimizdeki verilerin unlar olduunu varsaymtk:
1. Cumartesi-Pazar gnleri almyoruz.
2. Dolaysyla ayda 22 gn alyoruz.
3. Evden ie gitmek iin kullandmz vastann creti 1.5 TL
4. ten eve dnmek iin kullandmz vastann creti 1.4 TL
Elimizdeki bu bilgilere gre aylk yol masrafmz hesaplamak iin de yle bir forml
retmitik:
masraf = gn says x (gidi creti + dn creti)

Gelin imdi yukardaki bilgileri kullanarak programmz dosyaya yazalm:


gn = 22
gidi_creti = 1.5
dn_creti = 1.4

masraf = gn * (gidi_creti + dn_creti)

9.5. Program rnekleri 101


Python 3 iin Trke Klavuz, Srm 3

print(masraf)

Tpk ncekiler gibi, bu program da masastne deneme.py adyla kaydedelim ve


komut satrnda masastnn bulunduu konuma giderek python3 deneme.py komutuyla
programmz altralm. Program altrdmzda yle bir kt alyoruz:
63.8

Programmz gayet dzgn alyor. Ancak grdnz gibi, elde ettiimiz kt ok


yavan. Ama eer isterseniz yukardaki programa daha profesyonel bir grnm de
kazandrabilirsiniz. Dikkatlice inceleyin:
gn = 22
gidi_creti = 1.5
dn_creti = 1.4

masraf = gn * (gidi_creti + dn_creti)

print("-"*30)
print("allan gn says\t:", gn)
print("ie gidi creti\t:", gidi_creti)
print("iten dn creti\t:", dn_creti)
print("-"*30)

print("AYLIK YOL MASRAFI\t:", masraf)

Bu defa programmz yle bir kt verdi:


------------------------------
allan gn says : 22
ie gidi creti : 1.5
iten dn creti : 1.4
------------------------------
AYLIK YOL MASRAFI : 63.8

Grdnz gibi, bu kodlar sayesinde kullancya daha ayrntl bilgi vermi olduk. stelik
elde ettiimiz kt daha k grnyor.
Yukardaki kodlarda imdiye kadar renmediimiz hibir ey yok. Yukardaki kodlarn
tamamn anlayabilecek kadar Python bilgimiz var. Bu kodlarda ok basit paralar bir araya
getirerek istediimiz kty nasl elde ettiimizi dikkatlice inceleyin. Mesela elde etmek
istediimiz ktnn grnn gzelletirmek iin iki yerde u satr kullandk:
print("-"*30)

Bylece 30 adet - iaretini yan yana basm olduk. Bu sayede elde ettiimiz kt daha derli
toplu bir grnme kavutu. Ayrca kodlarmz iinde \t adl ka dizisinden de yararlandk.
Bylelikle ekrana baslan ktlar alt alta dzgn bir ekilde hizalanm oldu.
Bu arada, yukardaki kodlar sayesinde deiken kullanmnn ilerimizi ne kadar
kolaylatrdna da birebir tank olduk. Eer deikenler olmasayd yukardaki kodlar yle
yazacaktk:
print("-"*30)
print("allan gn says\t:", 22)
print("ie gidi creti\t:", 1.5)
print("iten dn creti\t:", 1.4)

102 Blm 9. alma Ortam Tavsiyesi


Python 3 iin Trke Klavuz, Srm 3

print("-"*30)

print("AYLIK YOL MASRAFI\t:", 22 * (1.5 + 1.4))

Eer gnn birinde mesela allan gn says deiirse yukardaki kodlarn iki farkl yerinde
deiiklik yapmamz gerekecekti. Bu kodlarn ok byk bir programn paras olduunu
dnn. Kodlarn iinde deer arayp bunlar tek tek deitirmeye kalkmann ne kadar
hataya ak bir yntem olduunu tahmin edebilirsiniz. Ama deikenler sayesinde, sadece
tek bir yerde deiiklik yaparak kodlarmz gncel tutabiliriz. Mesela allan gn says 20 ye
dm olsun:
gn = 20
gidi_creti = 1.5
dn_creti = 1.4

masraf = gn * (gidi_creti + dn_creti)

print("-"*30)
print("allan gn says\t:", gn)
print("ie gidi creti\t:", gidi_creti)
print("iten dn creti\t:", dn_creti)
print("-"*30)

print("AYLIK YOL MASRAFI\t:", masraf)

Grdnz gibi, sadece en bataki gn adl deikenin deerini deitirerek istediimiz


sonucu elde ettik.
Kendiniz isterseniz yukardaki rnekleri eitlendirebilirsiniz.
Grdnz gibi, Pythonda az da olsa ie yarar bir eyler yazabilmek iin ok ey bilmemize
gerek yok. Srf u ana kadar rendiklerimizi kullanarak bile ufak tefek programlar
yazabiliyoruz.

9.5. Program rnekleri 103


BLM 10

Yorum ve Aklama Cmleleri

Pythonla ilgili imdiye kadar rendiimiz bilgileri kullanarak yazabileceimiz en karmak


programlardan biri herhalde yle olacaktr:
isim = "Frat"
soyisim = "zgl"
isis = "Ubuntu"
ehir = "stanbul"

print("isim : ", isim, "\n",


"soyisim : ", soyisim, "\n",
"iletim sistemi: ", isis, "\n",
"ehir : ", ehir, "\n",
sep="")

Yukardaki kodlar rahatlkla anlayabildiinizi zannediyorum. Ama isterseniz yine de bu


kodlar satr satr inceleyelim:
lk olarak isim, soyisim, isis ve ehir adnda drt farkl deiken tanmladk. Bu deikenlerin
deeri srasyla Frat, zgl, Ubuntu ve stanbul.
Daha sonra da tanmladmz bu deikenleri belli bir dzen iinde kullanclarmza
gsterdik, yani ekrana yazdrdk. Elbette bu i iin print() fonksiyonunu kullandk. Bildiiniz
gibi, print() birden fazla parametre alabilen bir fonksiyondur. Yani print() fonksiyonunun
parantezleri iine istediimiz sayda e yazabiliriz.
Eer print() fonksiyonunun yukardaki kullanm ilk bakta gznze anlalmaz
grndyse, fonksiyonda geen ve ne ie yaradn anlayamadnz eleri, bir de kartarak
yazmay deneyebilirsiniz bu fonksiyonu.
Pythonla yazlm herhangi bir programn tam olarak nasl ilediini anlamann en iyi
yolu program iindeki kodlarda baz deiiklikler yaparak ortaya kan sonucu incelemektir.
rnein print() fonksiyonunda sep parametresinin deerini bo bir karakter dizisi
yapmamzn nedenini anlamak iin, fonksiyondaki bu sep parametresini kaldrp, program
bir de bu ekilde altrmay deneyebilirsiniz.
Yukardaki rnekte btn eleri tek bir print() fonksiyonu iine yazdk. Ama tabii eer
isterseniz birden fazla print() fonksiyonu da kullanabilirsiniz. yle:
isim = "Frat"
soyisim = "zgl"
isis = "Ubuntu"
ehir = "stanbul"

104
Python 3 iin Trke Klavuz, Srm 3

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

Yukardaki kodlarla ilgili birka noktaya daha dikkatinizi ekmek istiyorum:


Birincisi, grdnz gibi kodlar yazarken biraz ekil vererek yazdk. Bunun sebebi kodlarn
grn olarak anlalr olmasn salamak. Daha nce de dediimiz gibi, Pythonda
doru kod yazmak kadar, yazdnz kodlarn anlalr olmas da nemlidir. Bu sebepten,
Pythonla kod yazarken, mesela kodlarmzdaki her bir satrn uzunluunun 79 karakteri
gememesine zen gsteriyoruz. Bunu salamak iin, kodlarmz yukarda grld ekilde
belli noktalardan blmemiz gerekebilir.
Esasnda yukardaki kodlar yle de yazabilirdik:
isim = "Frat"
soyisim = "zgl"
isis = "Ubuntu"
ehir = "stanbul"

print("isim: ", isim, "\n", "soyisim: ", soyisim, "\n",


"iletim sistemi: ", isis, "\n", "ehir: ", ehir, "\n", sep="")

Ancak bu ekilde kod yaps biraz karmak grnyor. Ayrca parantez iindeki eleri yan
yana yazdmz iin, isim:, soyisim:, iletim sistemi: ve ehir: ifadelerini alt alta dzgn bir
ekilde hizalamak da kolay olmayacaktr.
Belki bu basit kodlarda ok fazla dikkati ekmiyordur, ama zellikle byk boyutlu
programlarda kodlarmz hem yap hem de grnt olarak olabildiince anlalr bir hale
getirmek hem kodu okuyan bakalar iin, hem de kendimiz iin byk nem tar.
Unutmayn, bir program yazdktan 5-6 ay sonra geri dnp baktnzda kendi yazdnz
kodlardan siz dahi hibir ey anlamadnz farkedebilirsiniz!
Bir program yazarken kodlarn olabildiince okunakl olmasn salamann bir ka yolu vardr.
Biz bunlardan bazlarn yukarda grdk. Ancak bir program okunakl hale getirmenin en iyi
yolu kodlar iine baz yorum cmleleri ekleyerek kodlar aklamaktr.
te bu blmde, Python programlama dili ile yazdmz kodlara nasl yorum ve aklama
cmleleri ekleyeceimizi inceleyeceiz.

10.1 Yorum areti

Programclkta en zor ey bakasnn yazd kodlar okuyup anlamaktr. Hatta yazlm


bir program dzeltmeye almak, bazen o program sfrdan yazmaktan daha zor olabilir.
Bunun nedeni, program iindeki kodlarn ne ie yaradn anlamann zorluudur. Program
yazan kii kendi dnne gre bir yol izlemi ve program gelitirirken karlat sorunlar
zmek iin kimi yerlerde enteresan zmler retmi olabilir. Ancak kodlara dardan bakan
birisi iin o programn mantk dzenini ve iindeki kodlarn tam olarak ne yaptn anlamak
bir hayli zor olacaktr. Byle durumlarda, kodlar okuyan programcnn en byk yardmcs,
program gelitiren kiinin kodlar arasna ekledii notlar olacaktr. Tabii program gelitiren
kii kodlara yorum ekleme zahmetinde bulunmusa...
Pythonda yazdmz kodlar bakalarnn da anlayabilmesini salamak iin, programmzn

10.1. Yorum areti 105


Python 3 iin Trke Klavuz, Srm 3

yorumlarla desteklenmesi tavsiye edilir. Elbette programnz yorumlarla desteklemeseniz


de programnz sorunsuz bir ekilde alacaktr. Ama program yorumlarla desteklemek en
azndan nezaket gereidir.
Ayrca iin baka bir boyutu daha var. Sizin yazdnz kodlar nasl bakalar okurken
zorlanyorsa, kendi yazdnz kodlar okurken siz bile zorlanabilirsiniz. zellikle uzun sredir
ilgilenmediiniz eski programlarnz gzden geirirken byle bir sorunla karlaabilirsiniz.
Programn iindeki bir kod paras, programn ilk yazlnn zerinden 5-6 ay getikten
sonra size artk hibir ey ifade etmiyor olabilir. Kodlara bakp, Acaba burada ne yapmaya
almm? diye dndnz zamanlar da olacaktr. te bu tr skntlar ortadan
kaldrmak veya en aza indirmek iin kodlarmzn arasna aklayc notlar ekleyeceiz.
Pythonda yorumlar # iareti ile gsterilir. Mesela bu blmn ilk banda verdiimiz kodlar
yorumlarla destekleyelim:
isim = "Frat"
soyisim = "zgl"
isis = "Ubuntu" #iletim sistemi
ehir = "stanbul"

#isim, soyisim, isis ve ehir adl deikenleri


#alt alta, dzgn bir ekilde ekrana basyoruz.
#Uygun yerlerde alt satra geebilmek iin "\n"
#adl ka dizisini kullanyoruz.
print("isim : ", isim, "\n",
"soyisim : ", soyisim, "\n",
"iletim sistemi: ", isis, "\n",
"ehir : ", ehir, "\n",
sep="") #parametreler arasnda boluk brakmyoruz.

Burada dikkat edeceimiz nokta her yorum satrnn bana # iaretini koymay
unutmamaktr.
Yazdmz yorumlar Pythona hi bir ey ifade etmez. Python bu yorumlar tamamen
grmezden gelecektir. Bu yorumlar bilgisayardan ziyade kodlar okuyan kii iin bir anlam
tar.
Elbette yazdnz yorumlarn ne kadar faydal olaca, yazdnz yorumlarn kalitesine
baldr. Dediimiz gibi, yerli yerinde kullanlm yorumlar bir programn okunaklln artrr,
ama her taraf yorumlarla kapl bir program okumak da bazen hi yorum girilmemi bir
program okumaktan daha zor olabilir! Dolaysyla Pythonda kodlarmza yorum eklerken
nemli olan ey, ka yapmaya alrken gz karmamaktr. Yani yorumlarmz, bir
kodun okunaklln artrmaya alrken daha da bozmayacak ekilde yerletirmeye dikkat
etmeliyiz.

10.2 Yorum aretinin Farkl Kullanmlar

Yukarda yorum (# ) iaretini kullanarak, yazdmz Python kodlarn nasl aklayacamz


rendik. Pythonda yorum iaretleri ounlukla bu ama iin kullanlr. Yani kodlar
aklamak, bu kodlar hem kendimiz hem de kodlar okuyan bakalar iin daha anlalr hale
getirmek iin... Ama Pythonda # iareti asl amacnn dnda baz baka amalara da hizmet
edebilir.

106 Blm 10. Yorum ve Aklama Cmleleri


Python 3 iin Trke Klavuz, Srm 3

10.2.1 Etkisizletirme Amal

Dediimiz gibi, yorum iaretinin birincil grevi, tabii ki, kodlara aklayc notlar eklememizi
salamaktr. Ama bu iaret baka amalar iin de kullanlabilir. rnein, diyelim ki yazdmz
programa bir zellik eklemeyi dnyoruz, ama henz bu zellii yeni srme eklemek
istemiyoruz. O zaman yle bir ey yapabiliriz:
isim = "Frat"
soyisim = "zgl"
isis = "Ubuntu"
ehir = "stanbul"
#uyruu = "T.C"

print("isim : ", isim, "\n",


"soyisim : ", soyisim, "\n",
"iletim sistemi: ", isis, "\n",
"ehir : ", ehir, "\n",
#"uyruu : ", uyruu, "\n",
sep="")

Burada, programa henz eklemek istemediimiz bir zellii, yorum iine alarak imdilik iptal
ediyoruz yani etkisizletiriyoruz (ngilizcede bu yorum iine alma ilemine comment out
deniyor). Python yorum iinde bir kod bile yer alsa o kodlar altrmayacaktr. nk Python
# iareti ile balayan satrlarn ieriini grmez (#!/usr/bin/env python3 ve # -*- coding:
utf-8 -*- satrlar hari).
Peki eklemek istemediimiz zellii yorum iine almaktansa dorudan silsek olmaz m?
Elbette olur. Ama programn daha sonraki bir srmne ilave edeceimiz bir zellii yorum
iine almak yerine silecek olursak, vakti geldiinde o zellii nasl yaptmz hatrlamakta
zorlanabiliriz! Hatta bir sre sonra programmza hangi zellii ekleyeceimizi dahi unutmu
olabiliriz. Hayr, ben hafzama gveniyorum! diyorsanz karar sizin.
Yorum iine alarak iptal ettiiniz bu kodlar programa ekleme vakti geldiinde yapacanz tek
ey, kodlarn bandaki # iaretlerini kaldrmak olacaktr. Hatta baz metin dzenleyiciler
bu ilemi tek bir tua basarak da gerekletirme yeteneine sahiptir. rnein IDLE ile
alyorsanz, yorum iine almak istediiniz kodlar fare ile setikten sonra Alt+3 tularna
basarak ilgili kodlar yorum iine alabilirsiniz. Bu kodlar yorumdan kurtarmak iin ise ilgili
alan setikten sonra Alt+4 tularna basmanz yeterli olacaktr (yorumdan kurtarma ilemine
ngilizcede uncomment diyorlar).

10.2.2 Ssleme Amal

Btn bunlarn dnda, isterseniz yorum iaretini kodlarnz sslemek iin dahi
kullanabilirsiniz:
#######################################################
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
# FALANCA v.1 #
# Yazan: Keramet Su #
# Lisans: GPL v2 #
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~#
#######################################################

isim = "Frat"
soyisim = "zgl"

10.2. Yorum aretinin Farkl Kullanmlar 107


Python 3 iin Trke Klavuz, Srm 3

isis = "Ubuntu"
ehir = "stanbul"

print("isim : ", isim, "\n",


"soyisim : ", soyisim, "\n",
"iletim sistemi: ", isis, "\n",
"ehir : ", ehir, "\n",
sep="")

Yani ksaca, Pythonun grmesini, altrmasn istemediimiz her eyi yorum iine alabiliriz.
Unutmamamz gereken tek ey, yorumlarn yazdmz programlarn nemli bir paras
olduu ve bunlar mantkl, makul bir ekilde kullanmamz gerektiidir.

108 Blm 10. Yorum ve Aklama Cmleleri


BLM 11

Kullancdan Bilgi Almak

imdiye kadar Python programlama dili ile ilgili epey bilgi edindik. Ama muhtemelen buraya
kadar rendiklerimiz sizi heyecanlandrmaktan bir hayli uzakt. Zira u ana kadar hep tek
ynl bir programlama faaliyeti yrttk.
Mesela imdiye kadar rendiklerimizi kullanarak ancak yle bir program yazabildik:
isim = "Mbeccel"

print("Merhaba", isim, end="!\n")

Bu program altrdmzda yle bir kt alacamz biliyorsunuz:


Merhaba Mbeccel!

Bu programn ne kadar skc olduunu herhalde sylemeye gerek yok. Bu programda


isim deikenini dorudan kendimiz yazdmz iin programmz hibir koulda Merhaba
Mbeccel dnda bir kt veremez. nk bu program, tek ynl bir programlama
faaliyetinin rndr.
Halbuki bu deikenin deerini kendimiz yazmasak, bu deeri kullancdan alsak ne ho
olurdu, deil mi?
Pythonda kullancdan herhangi bir veri alp, yazdmz programlar tek tara olmaktan
kurtarmak iin input() adl bir fonksiyondan faydalanyoruz.
te biz bu blmde, programclk maceramz bir st seviyeye tayacak ok nemli bir ara
olan bu input() fonksiyonunu derinlemesine inceleyeceiz. Ama bu blmde sadece bu
fonksiyonu ele almayacaz elbette. Burada kullancdan veri almann yansra, aldmz bu
veriyi nasl dntreceimizi ve bu veriyi, yazdmz programlarda nasl kullanacamz da
derin derin inceleyeceiz.
lkin input() fonksiyonunu anlatarak yola koyulalm.

11.1 input() Fonksiyonu

input() da daha nce rendiimiz type(), len() ve print() gibi bir fonksiyondur. Esasnda
biz bu fonksiyonu ilk kez burada grmyoruz. Windows ve GNU/Linux kullanclar, yazdklar
bir program ift tklayarak altrabilmek iin bu fonksiyonu kullandklarn hatrlyor
olmallar. Mesela u program ele alalm:

109
Python 3 iin Trke Klavuz, Srm 3

#!/usr/bin/env python3

kartvizit = """
stihza Anonim irketi
Frat zgl
Tel: 0212 123 23 23
Faks: 0212 123 23 24
e.posta: kistihza@yahoo.com
"""

print(kartvizit)

Bu program yazp kaydettikten sonra bu programn simgesi zerine ift tkladmzda siyah
bir komut ekrannn ok hzl bir ekilde alp kapandn grrz. Aslnda programmz
alyor, ama programmz yapmas gereken ii yaptktan hemen sonra kapand iin biz
program penceresini grmyoruz.
Programmzn altktan sonra hemen kapanmamasn salamak iin son satra bir input()
fonksiyonu yerletirmemiz gerektiini biliyoruz:
#!/usr/bin/env python3

kartvizit = """
stihza Anonim irketi
Frat zgl
Tel: 0212 123 23 23
Faks: 0212 123 23 24
e.posta: kistihza@yahoo.com
"""

print(kartvizit)

input()

Bu sayede programmz kullancdan bir giri bekleyecek ve o girii alana kadar da


kapanmayacaktr. Program kapatmak iin Enter dmesine basabiliriz.
input() bir fonksiyondur dedik. Henz fonksiyon kavramnn ayrntlarn renmemi olsak
da, imdiye kadar pek ok fonksiyon grdmz iin artk bir fonksiyonla karlatmzda
bunun nasl kullanlacan az ok tahmin edebiliyoruz. Tpk dndnz ve yukardaki
rnekten de grdnz gibi, birer fonksiyon olan type(), print(), len() ve open()
fonksiyonlarn nasl kullanyorsak input() fonksiyonunu da yle kullanacaz.
Dilerseniz laf daha fazla uzatmadan rnek bir program yazalm:
isim = input("sminiz nedir? ")

print("Merhaba", isim, end="!\n")

Bu program kaydedip altrdnzda, sorulan soruya verdiiniz cevaba gre kt farkl


olacaktr. rnein eer bu soruya Niyazi cevabn vermiseniz ktnz Merhaba Niyazi!
eklinde olacaktr.
Gryorsunuz ya, tpk daha nce grdmz fonksiyonlarda olduu gibi, input()
fonksiyonunda da parantez iine bir parametre yazyoruz. Bu fonksiyona verilen parametre,
kullancdan veri alnrken kullancya sorulacak soruyu gsteriyor. Gelin isterseniz bir rnek
daha yapalm elimizin almas iin:

110 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

ya = input("Yanz: ")

print("Demek", ya, "yandasn.")


print("Gen mi yoksa yal m olduuna karar veremedim.")

input() fonksiyonunun ne kadar kullanl bir ara olduu ortada. Bu fonksiyon sayesinde,
imdiye kadar tek sesli bir ekilde yrttmz programclk faaliyetlerimizi ok sesli bir
hale getirebileceiz. Mesela nceki blmlerden birinde yazdmz, daire alan hesaplayan
program hatrlarsnz. O zaman henz dosyalarmz kaydetmeyi ve input() fonksiyonunu
renmediimiz iin o program etkileimli kabukta u ekilde yazmtk:
>>> ap = 16
>>> yarap = ap / 2
>>> pi = 3.14159
>>> alan = pi * (yarap * yarap)
>>> alan

201.06176

Ama artk hem dosyalarmz kaydetmeyi biliyoruz, hem de input() fonksiyonunu rendik.
Dolaysyla yukardaki program u ekilde yazabiliriz:
#Kullancdan dairenin apn girmesini istiyoruz.
ap = input("Dairenin ap: ")

#Kullancnn verdii ap bilgisini kullanarak


#yarap hesaplayalm. Buradaki int() fonksiyonunu
#ilk kez gryoruz. Biraz sonra bunu aklayacaz
yarap = int(ap) / 2

#pi saymz sabit


pi = 3.14159

#Yukardaki bilgileri kullanarak artk


#dairenin alann hesaplayabiliriz
alan = pi * (yarap * yarap)

#Son olarak, hesapladmz alan yazdryoruz


print("ap", ap, "cm olan dairenin alan: ", alan, "cm2'dir")

Grdnz gibi, input() fonksiyonunu renmemiz sayesinde artk yava yava ie yarar
programlar yazabiliyoruz.
Ancak burada, daha nce renmediimiz bir fonksiyon dikkatinizi ekmi olmal. Bu
fonksiyonun ad int(). Bu yeni fonksiyon dnda, yukardaki btn kodlar anlayabilecek
kadar Python bilgisine sahibiz.
int() fonksiyonunun ne ie yaradn anlamak iin isterseniz ilgili satr yarap = ap / 2
eklinde yazarak altrmay deneyin bu program.
Dediim gibi, eer o satrdaki int() fonksiyonunu kaldrarak program altrdysanz una
benzer bir hata mesaj alm olmalsnz:
Traceback (most recent call last):
File "deneme.py", line 8, in <module>
yarap = ap / 2
TypeError: unsupported operand type(s) for /: 'str' and 'int'

11.1. input() Fonksiyonu 111


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi programmz blme ilemini yapamad. Buradan anlyoruz ki, bu int()
fonksiyonu programmzdaki aritmetik ilemin dzgn bir ekilde yaplabilmesini salyor.
Gelelim bu fonksiyonun bu ilevi nasl yerine getirdiini incelemeye.

11.2 Tip Dnmleri

Bir nceki blmn sonunda verdiimiz rnek programda int() adl bir fonksiyon grm,
bu fonksiyonu anlatmay o zaman ertelemitik. ok gecikmeden, bu nemli fonksiyonun ne
ie yaradn renmemiz gerekiyor. sterseniz bir rnek zerinden gidelim.
Diyelim ki kullancdan ald saynn karesini hesaplayan bir program yazmak istiyoruz.
ncelikle yle bir ey deneyelim:
say = input("Ltfen bir say girin: ")

#Girilen saynn karesini bulmak iin say deikeninin 2.


#kuvvetini alyoruz. Ayn eyi pow() fonksiyonu ile de
#yapabileceimizi biliyorsunuz. rn.: pow(say, 2)
print("Girdiiniz saynn karesi: ", say ** 2)

Bu kodlar altrdmz zaman, programmz kullancdan bir say girmesini isteyecek, ancak
kullanc bir say girip Enter tuuna bastnda yle bir hata mesajyla karlaacaktr:
Traceback (most recent call last):
File "test.py", line 5, in <module>
print("Girdiiniz saynn karesi: ", say ** 2)
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

Hata mesajna baktnzda, TypeError ifadesinden, bunun veri tipine ilikin bir hata
olduunu tahmin edebilirsiniz. Eer ngilizce biliyorsanz yukardaki hata mesajnn anlamn
rahatlkla karabilirsiniz. ngilizce bilmeseniz de en sondaki str ve int kelimeleri size
karakter dizisi ve say adl veri tiplerini hatrlatacaktr. Demek ki ortada veri tiplerini
ilgilendiren bir sorun var...
Peki burada tam olarak neler dnyor?
Hatrlayacaksnz, geen derslerden birinde len() fonksiyonunu anlatrken yle bir ey
sylemitik:
Biz henz kullancdan nasl veri alacamz bilmiyoruz. Ama imdilik unu
syleyebiliriz: Pythonda kullancdan herhangi bir veri aldmzda, bu veri bize
bir karakter dizisi olarak gelecektir.
Gelin isterseniz yukarda anlattmz durumu teyit eden bir program yazalm:
#Kullancdan herhangi bir veri girmesini istiyoruz
say = input("Herhangi bir veri girin: ")

#Kullancnn girdii verinin tipini bir


#deikene atyoruz
tip = type(say)

#Son olarak kullancnn girdii verinin tipini


#ekrana basyoruz.
print("Girdiiniz verinin tipi: ", tip)

112 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

Bu program altrdmzda ne tr bir veri girersek girelim, girdiimiz verinin tipi str, yani
karakter dizisi olacaktr. Demek ki gerekten de, kullancdan veri almak iin kullandmz
input() fonksiyonu bize her koulda bir karakter dizisi veriyormu.
Geen derslerde yle bir ey daha sylemitik:
Pythonda, o anda elinizde bulunan bir verinin hangi tipte olduunu bilmek son
derece nemlidir. nk bir verinin ait olduu tip, o veriyle neler yapp neler
yapamayacanz belirler.
u anda kar karya olduumuz durum da buna ok gzel bir rnektir. Eer o anda
elimizde bulunan verinin tipini bilmezsek tpk yukarda olduu gibi, o veriyi programmzda
kullanmaya alrken programmz hata verir ve ker.
Her zaman stne basa basa sylediimiz gibi, aritmetik ilemler yalnzca saylarla
yaplr. Karakter dizileri ile herhangi bir aritmetik ilem yaplamaz. Dolaysyla, input()
fonksiyonundan gelen veri bir karakter dizisi olduu iin ve biz de programmzda girilen
saynn karesini hesaplamak amacyla bu fonksiyondan gelen verinin 2. kuvvetini, yani
karesini hesaplamaya altmz iin programmz hata verecektir.
Yukardaki programda neler olup bittiini daha iyi anlayabilmek iin Pythonn etkileimli
kabuunda u ilemleri yapabiliriz:
>>> "23" ** 2

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'

Grdnz gibi, programmzdan aldmz hata ile yukardaki hata tamamen ayn (hata
mesajlarnda bizi ilgilendiren ksm en son satrdr). Tpk burada olduu gibi, hata
veren programda da Ltfen bir say girin: sorusuna rnein 23 cevabn verdiimizde
programmz aslnda "23" ** 2 gibi bir ilem yapmaya alyor. Bir karakter dizisinin
kuvvetini hesaplamak mmkn olmad, kuvvet alma ilemi yalnzca saylarla yaplabilecei
iin de hata vermekten baka aresi kalmyor.
Ancak bazen yle durumlarla karlarsnz ki, programnz hibir hata vermez, ama elde
edilen sonu aslnda tamamen beklentinizin dndadr. Mesela u basit rnei inceleyelim:
say1 = input("Toplama ilemi iin ilk sayy girin: ")
say2 = input("Toplama ilemi iin ikinci sayy girin: ")

print(say1, "+", say2, "=", say1 + say2)

Bu kodlar altrdmzda yle bir manzarayla karlarz:

11.2. Tip Dnmleri 113


Python 3 iin Trke Klavuz, Srm 3

input() fonksiyonunun alttan alta neler evirdiini bu rnek yardmyla ok daha iyi
anladnz zannediyorum. Grdnz gibi yukardaki program herhangi bir hata vermedi.
Ama beklediimiz kty da vermedi. Zira biz programmzn iki sayy toplamasn istiyorduk.
O ise kullancnn girdii saylar yan yana yazmakla yetindi. Yani bir aritmetik ilem
yapmak yerine, verileri birbiriyle bititirdi. nk, dediim gibi, input() fonksiyonunun
kullancdan ald ey bir karakter dizisidir. Dolaysyla bu fonksiyon yukardaki gibi bir
durumla karlat zaman karakter dizileri arasnda bir birletirme ilemi gerekletirir. Tpk
ilk derslerimizde etkileimli kabukta verdiimiz u rnekte olduu gibi:
>>> "23" + "23"

2323

Bu son rnekten ayrca unu karyoruz: Yazdnz bir programn herhangi bir hata
vermemesi o programn doru alt anlamna gelmeyebilir. Dolaysyla bu tr durumlara
kar her zaman uyank olmanzda fayda var.
Peki yukardaki gibi durumlarla karlamamak iin ne yapacaz?
te bu noktada devreye tip dntrc adn verdiimiz birtakm fonksiyonlar girecek.

11.2.1 int()

Dediimiz gibi, input() fonksiyonundan gelen veri her zaman bir karakter dizisidir.
Dolaysyla bu fonksiyondan gelen veriyle herhangi bir aritmetik ilem yapabilmek iin
ncelikle bu veriyi bir sayya dntrmemiz gerekir. Bu dntrme ilemi iin int()
adl zel bir dntrc fonksiyondan yararlanacaz. Gelin isterseniz Pythonn etkileimli
kabuunda bu fonksiyonla bir ka deneme yaparak bu fonksiyonun ne ie yaradn ve nasl
kullanldn anlamaya alalm. Zira etkileimli kabuk bu tr deneme ilemleri iin biilmi
kaftandr:

114 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

>>> karakter_dizisi = "23"


>>> say = int(karakter_dizisi)
>>> print(say)

23

Burada ncelikle 23 adl bir karakter dizisi tanmladk. Ardndan da int() fonksiyonunu
kullanarak bu karakter dizisini bir tamsayya (integer ) dntrdk. sminden de
anlayacanz gibi int() fonksiyonu ngilizce integer (tamsay) kelimesinin ksaltmasdr ve
bu fonksiyonun grevi bir veriyi tamsayya dntrmektir.
Ancak burada dikkat etmemiz gereken bir ey var. Herhangi bir verinin sayya
dntrlebilmesi iin o verinin say deerli bir veri olmas gerekir. rnein 23, say deerli
bir karakter dizisidir. Ama mesela elma say deerli bir karakter dizisi deildir. Bu yzden
elma karakter dizisi sayya dntrlemez:
>>> karakter_dizisi = "elma"
>>> say = int(karakter_dizisi)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'elma'

Grdnz gibi, say deerli olmayan bir veriyi sayya dntrmeye altrdmzda
Python bize bir hata mesaj gsteriyor. Yazdmz programlarda bu duruma zellikle dikkat
etmemiz gerekiyor.
imdi bu blmn banda yazdmz ve hata veren programmza dnelim yine:
say = input("Ltfen bir say girin: ")

print("Girdiiniz saynn karesi: ", say ** 2)

Bu kodlarn hata vereceini biliyoruz. Ama artk, rendiimiz int() dntrcsn


kullanarak programmz hata vermeyecek ekilde yeniden yazabiliriz:
veri = input("Ltfen bir say girin: ")

#input() fonksiyonundan gelen karakter dizisini


#sayya dntryoruz.
say = int(veri)

print("Girdiiniz saynn karesi: ", say ** 2)

Artk programmz hatasz bir ekilde alyor.


Bir de teki rneimizi ele alalm:
say1 = input("Toplama ilemi iin ilk sayy girin: ")
say2 = input("Toplama ilemi iin ikinci sayy girin: ")

print(say1, "+", say2, "=", say1 + say2)

Bu kodlarn beklediimiz kty vermeyeceini biliyoruz. Ama eer bu kodlar yle yazarsak
iler deiir:
v1 = input("Toplama ilemi iin ilk sayy girin: ")
v2 = input("Toplama ilemi iin ikinci sayy girin: ")

11.2. Tip Dnmleri 115


Python 3 iin Trke Klavuz, Srm 3

say1 = int(v1) #v1 adl karakter dizisini sayya dntryoruz.


say2 = int(v2) #v2 adl karakter dizisini sayya dntryoruz.

print(say1, "+", say2, "=", say1 + say2)

Grdnz gibi, input() fonksiyonundan gelen karakter dizilerini sayya dntrerek


istediimiz kty alabiliyoruz.

11.2.2 str()

Pythondaki tip dntrcleri elbette sadece int() fonksiyonuyla snrl deildir.


Grdnz gibi, int() fonksiyonu say deerli verileri (mesela karakter dizilerini) tam
sayya dntryor. Bunun bir de tersi mmkndr. Yani karakter dizisi olmayan verileri
karakter dizisine dntrmemiz de mmkndr. Bu ilem iin str() adl baka bir tip
dntrcden yararlanyoruz:
>>> say = 23
>>> kardiz = str(say)
>>> print(kardiz)

23

>>> print(type(kardiz))

<class 'str'>

Grdnz gibi, bir tam say olan 23 str() adl bir fonksiyondan yararlanarak karakter
dizisi olan 23 ifadesine dntrdk. Son satrda da, elde ettiimiz eyin bir karakter dizisi
olduundan emin olmak iin type() fonksiyonunu kullanarak verinin tipini denetledik.
Yukardaki rneklerden grdmz gibi, aritmetik ilemler yapmak istediimizde karakter
dizilerini sayya evirmemiz gerekiyor. Peki acaba hangi durumlarda bunun tersini yapmamz,
yani saylar karakter dizilerine evirmemiz gerekir? Python bilginiz ve tecrbeniz arttka
bunlarn hangi durumlar olduunu kendiniz de greceksiniz. Mesela biz daha imdiden,
saylar karakter dizisine evirmemiz gereken bir durumla karlatk. Hatrlarsanz, len()
fonksiyonunu anlatrken, bu fonksiyonun saylarla birlikte kullanlamayacan sylemitik:
>>> len(12343423432)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: object of type 'int' has no len()

Peki ya yazdnz programda bir saynn ka haneden olutuunu hesaplamanz gerekirse


ne yapacaksnz? Yani mesela yukardaki saynn 11 haneli olduunu bilmeniz gerekiyorsa ne
olacak?
te byle bir durumda str() fonksiyonundan yararlanabilirsiniz:
>>> say = 12343423432
>>> kardiz = str(say)
>>> len(kardiz)

11

116 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

Bildiiniz gibi, len() fonksiyonu, u ana kadar rendiimiz veri tipleri iinde sadece karakter
dizileri zerinde ilem yapabiliyor. Biz de bu yzden, saymzn ka haneli olduunu
renebilmek iin, ncelikle bu sayy bir karakter dizisine eviriyoruz. Daha sonra da elde
ettiimiz bu karakter dizisini len() fonksiyonuna parametre olarak veriyoruz. Bylece saynn
ka haneli olduu bilgisini elde etmi oluyoruz.
Bu arada elbette yukardaki ilemi tek satrda da halledebilirsiniz:
>>> len(str(12343423432))

11

Bu ekilde i ie gemi fonksiyonlar yazdmzda, Python fonksiyonlar iten da doru


tek tek deerlendirecektir. Mesela yukardaki rnekte Python nce str(12343423432)
ifadesini deerlendirecek ve kan sonucu len() fonksiyonuna gnderecektir. ie gemi
fonksiyonlar yazarken dikkat etmemiz gereken nemli bir nokta da, atmz her bir
parantezi tek tek kapatmay unutmamaktr.

11.2.3 oat()

Hatrlarsanz ilk blmlerde saylardan sz ederken tamsaylarn (integer ) dnda kayan


noktal saylarn (oat ) da olduundan sz etmitik. te eer bir tamsayy veya say
deerli bir karakter dizisini kayan noktal sayya dntrmek istersek float() adl baka
bir dntrcden yararlanacaz:
>>> a = 23
>>> type(a)

<class 'int'>

>>> float(a)

23.0

Grdnz gibi, 23 tamsays, float() fonksiyonu sayesinde 23.0 a yani bir kayan noktal
sayya dnt.
Ayn eyi, say deerli karakter dizileri zerine uygulamak da mmkndr:
>>> b = "23"
>>> type(b)

<class 'str'>

>>> float(b)

23.0

11.2.4 complex()

Saylardan sz ederken, eer matematikle ok fazla ili dl deilseniz pek


karlamayacanz, karmak say adl bir say trnden de bahsetmitik. Karmak
saylar Pythonda complex ifadesiyle gsteriliyor. Mesela unun bir karmak say olduunu
biliyoruz:

11.2. Tip Dnmleri 117


Python 3 iin Trke Klavuz, Srm 3

>>> 12+0j

Kontrol edelim:
>>> type(12+0j)

<class 'complex'>

te eer herhangi bir sayy karmak sayya dntrmeniz gerekirse complex() adl bir
fonksiyondan yararlanabilirsiniz. rnein:
>>> complex(15)

(15+0j)

Bylece Pythondaki btn say dntrcleri renmi olduk.


Gelin isterseniz, bu blmde anlattmz konular yle bir tekrar ederek bilgilerimizi
salamlatrmaya alalm.
>>> a = 56

Bu say bir tamsaydr. ngilizce olarak ifade etmek gerekirse, integer. Bunun bir tamsay
olduunu u ekilde teyit edebileceimizi gayet iyi biliyorsunuz:
>>> type(a)

<class 'int'>

Burada aldmz <class int> kts, bize a deikeninin tuttuu saynn bir tamsay olduunu
sylyor. int ifadesi, integer (tamsay) kelimesinin ksaltmasdr.
Bir de u sayya bakalm:
>>> b = 34.5
>>> type(b)

<class 'float'>

Bu kt ise bize 34.5 saysnn bir kayan noktal say olduunu sylyor. oat kelimesi Floats
veya Floating Point Number ifadesinin ksaltmasdr. Yani kayan noktal say demektir.
Bu arada, bu type() adl fonksiyonu sadece saylara deil, baka eylere de
uygulayabileceimizi biliyorsunuz. Mesela bir rnek vermek gerekirse:
>>> meyve = "karpuz"
>>> type(meyve)

<class 'str'>

Grdnz gibi, type() fonksiyonu bize meyve adl deikenin deerinin bir str yani string
yani karakter dizisi olduunu bildirdi.
Bu veri tipleri arasnda, baz zel fonksiyonlar kullanarak dntrme ilemi yapabileceimizi
rendik. Mesela:
>>> say = 45

say adl deikenin tuttuu verinin deeri bir tamsaydr. Biz bu tamsayy kayan noktal
sayya dntrmek istiyoruz. Yapacamz ilem ok basit:

118 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

>>> float(say)

45.0

Grdnz gibi, 45 adl tamsayy, 45.0 adl bir kayan noktal sayya dntrdk. imdi
type(45.0) komutu bize <class oat> ktsn verecektir.
Eer kayan noktal bir sayy tamsayya evirmek istersek u komutu veriyoruz. Mesela kayan
noktal saymz, 56.5 olsun:
>>> int(56.5)

56

Yukardaki rnei tabii ki yle de yazabiliriz:


>>> a = 56.5
>>> int(a)

56

Dntrme ilemini saylar arasnda yapabileceimiz gibi, saylar ve karakter dizileri


arasnda da yapabiliriz. rnein u bir karakter dizisidir:
>>> nesne = "45"

Yukardaki deeri trnak iinde belirttiimiz iin bu deer bir karakter dizisidir. imdi bunu bir
tamsayya evireceiz:
>>> int(nesne)

45

Dilersek, ayn karakter dizisini kayan noktal sayya da evirebiliriz:


>>> float(nesne)

45.0

Hatta bir sayy karakter dizisine de evirebiliriz. Bunun iin string (karakter dizisi) kelimesinin
ksaltmas olan str ifadesini kullanacaz:
>>> s = 6547
>>> str(s)

'6547'

Bir rnek de kayan noktal saylarla yapalm:


>>> s = 65.7
>>> str(s)

'65.7'

Yalnz unu unutmayn: Bir karakter dizisinin sayya dntrlebilmesi iin o karakter
dizisinin say deerli olmas lazm. Yani 45 deerini sayya dntrebiliriz. nk 45
deeri, trnaklardan tr bir karakter dizisi de olsa, neticede say deerli bir karakter
dizisidir. Ama mesela elma karakter dizisi byle deildir. Dolaysyla, yle bir maceraya
girimek bizi hsrana uratacaktr:

11.2. Tip Dnmleri 119


Python 3 iin Trke Klavuz, Srm 3

>>> nesne = "elma"


>>> int(nesne)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'elma'

Grdnz gibi, Python byle bir ilem denemesi karsnda hata veriyor...
Bu blmde pek ok yeni ey rendik. Bu blmn en nemli getirisi input() fonksiyonunu
renmemiz oldu. Bu fonksiyon sayesinde kullancyla iletiim kurmay baardk. Artk
kullancdan veri alp, bu verileri programlarmz iinde ileyebiliyoruz.
Yine bu blmde dikkatinizi ektiimiz baka bir konu da saylar ve karakter dizileri arasndaki
ilikiydi. input() fonksiyonuyla elde edilen ktnn bir karakter dizisi olduunu rendik.
Bildiimiz gibi, aritmetik ilemler ancak saylar arasnda yaplabilir. Dolaysyla input()
fonksiyonuyla gelen karakter dizisini bir sayyla arpmaya kalkarsak hata alyoruz. Burada
yapmamz gereken ey, elimizdeki verileri dntrmek. Yani input() fonksiyonundan gelen
karakter dizisini bir sayyla arpmak istiyorsak, ncelikle aldmz karakter dizisini sayya
dntrmemiz gerekiyor. Dntrme ilemleri iin kullandmz fonksiyonlar unlard:
int() Say deerli bir karakter dizisini veya kayan noktal sayy tamsayya
(integer ) evirir.
float() Say deerli bir karakter dizisini veya tamsayy kayan noktal sayya
(oat ) evirir.
str() Bir tamsay veya kayan noktal sayy karakter dizisine (string ) evirir.
complex() Herhangi bir sayy veya say deerli karakter dizisini karmak sayya
(complex ) evirir.
Ayrca bu blmde rendiklerimiz, yle nemli bir tespitte bulunmamza da olanak tand:
Her tamsay ve/veya kayan noktal say bir karakter dizisine dntrlebilir. Ama
her karakter dizisi tamsayya ve/veya kayan noktal sayya dntrlemez.
rnein, 5654 gibi bir tamsayy veya 543.34 gibi bir kayan noktal sayy str() fonksiyonu
yardmyla karakter dizisine dntrebiliriz:
>>> str(5654)
>>> str(543.34)

5654 veya 543.34 gibi bir karakter dizisini int() veya float() fonksiyonu yardmyla
tamsayya ya da kayan noktal sayya da dntrebiliriz:
>>> int("5654")
>>> int("543.34")

>>> float("5654")
>>> float("543.34")

Ama elma gibi bir karakter dizisini ne int() ne de float() fonksiyonuyla tamsayya veya
kayan noktal sayya dntrebiliriz! nk elma verisi say deerli deildir.
Bu blm kapatmadan nce, dilerseniz imdiye kadar rendiklerimizi de ieren rnek bir
program yazalm. Bu program, Python maceramz asndan bize yeni kaplar da aacak.

120 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

nceki derslerimizin birinde verdiimiz doalgaz faturas hesaplayan program hatrlarsnz.


te artk input() fonksiyonu sayesinde bu doalgaz faturas hesaplama programn da daha
ilgin bir hale getirebiliriz:
#Her bir ayn ka gn ektiini tanmlyoruz
ocak = mart = mays = temmuz = austos = ekim = aralk = 31
nisan = haziran = eyll = kasm = 30
ubat = 28

#Doalgazn vergiler dahil metrekp fiyat


birimFiyat = 0.79

#Kullanc ayda ne kadar doalgaz tketmi?


aylkSarfiyat = input("Aylk doalgaz sarfiyatnz metrekp olarak giriniz: ")

#Kullanc hangi aya ait faturasn renmek istiyor?


dnem = input("""Hangi aya ait faturay hesaplamak istersiniz?
(Ltfen ay adn tamam kk harf olacak ekilde giriniz)\n""")

#Yukardaki input() fonksiyonundan gelen veriyi


#Python'n anlayabilecei bir biime dntryoruz
ay = eval(dnem)

#Kullancnn gnlk doalgaz sarfiyat


gnlkSarfiyat = int(aylkSarfiyat) / ay

#Fatura tutar
fatura = birimFiyat * gnlkSarfiyat * ay

print("gnlk sarfiyatnz: \t", gnlkSarfiyat, " metrekp\n",


"tahmini fatura tutar: \t", fatura, " TL", sep="")

Burada yine bilmediimiz bir fonksiyonla daha karlatk. Bu fonksiyonun ad eval(). Biraz
sonra eval() fonksiyonunu derinlemesine inceleyeceiz. Ama bu fonksiyonu anlatmaya
gemeden nce dilerseniz yukardaki kodlar biraz didikleyelim.
lk satrlarn ne ie yaradn zaten biliyorsunuz. Bir yl iindeki btn aylarn ka gn ektiini
gsteren deikenlerimizi tanmladk. Burada her bir deikeni tek tek tanmlamak yerine
deikenleri topluca tanmladmza dikkat edin. steseydik tabii ki yukardaki kodlar yle
de yazabilirdik:
#Her bir ayn ka gn ektiini tanmlyoruz
ocak = 31
ubat = 28
mart = 31
nisan = 30
mays = 31
haziran = 30
temmuz = 31
austos = 31
eyll = 30
ekim = 31
kasm = 30
aralk = 31

#Doalgazn vergiler dahil m3 fiyat


birimFiyat = 0.79

11.2. Tip Dnmleri 121


Python 3 iin Trke Klavuz, Srm 3

#Kullanc ayda ne kadar doalgaz tketmi?


aylkSarfiyat = input("Aylk doalgaz sarfiyatnz m3 olarak giriniz: ")

#Kullanc hangi aya ait faturasn renmek istiyor?


dnem = input("""Hangi aya ait faturay hesaplamak istersiniz?
(Ltfen ay adn tamam kk harf olacak ekilde giriniz)\n""")

#Yukardaki input() fonksiyonundan gelen veriyi


#Python'n anlayabilecei bir biime dntryoruz
ay = eval(dnem)

#Kullancnn gnlk doalgaz sarfiyat


gnlkSarfiyat = int(aylkSarfiyat) / ay

#Fatura tutar
fatura = birimFiyat * gnlkSarfiyat * ay

print("gnlk sarfiyatnz: \t", gnlkSarfiyat, " metrekp\n",


"tahmini fatura tutar: \t", fatura, " TL", sep="")

Ama tabii ki, deikenleri tek tek tanmlamak yerine topluca tanmlamak, daha az kod
yazmanz salamasnn yansra, programnzn alma performans asndan da daha iyidir.
Yani deikenleri bu ekilde tanmladnzda programnz daha hzl alr.
Programmz incelemeye devam edelim...
Deikenleri tanmladktan sonra doalgazn vergiler dahil yaklak birim yatn da bir
deiken olarak tanmladk. 0.79 deerini zaten birka blm nce hesaplayp bulduumuz
iin, ayn ilemleri tekrar programmza eklememize gerek yok. Dorudan nihai deeri
programmza yazsak yeter...
Birim yat belirledikten sonra kullancya aylk doalgaz saryatn soruyoruz. Kullancnn bu
deeri m3 olarak girmesini bekliyoruz. Elbette bu veriyi kullancdan alabilmek iin input()
fonksiyonunu kullanyoruz.
Daha sonra kullancya hangi aya ait doalgaz faturasn demek istediini soruyoruz. Bu
bilgi, bir sonraki satrda gnlk doalgaz saryatn hesaplarken iimize yarayacak. nk
kullancnn girdii ayn ektii gn saysna bal olarak gnlk saryat deiecektir. Gnlk
saryat hesaplamak iin aylk saryat, ilgili ayn ektii gn saysna blyoruz. Bu arada
bir nceki satrda dnem deikenini eval() adl bir fonksiyonla birlikte kullandmz
gryorsunuz. Bunu biraz sonra inceleyeceiz. O yzden bu satrlar atlayp son satra
gelelim.
Son satrda print() fonksiyonunu kullanarak, kullancdan aldmz verileri dzgn bir
ekilde kendisine gsteriyoruz. Programmz kullancya gnlk doalgaz saryatn ve
ay sonunda karlaaca tahmini fatura tutarn bildiriyor. print() fonksiyonu iinde
kullandmz ka dizilerine zellikle dikkatinizi ekmek istiyorum. Burada dzgn bir kt
elde etmek iin \t ve \n adl ka dizilerinden nasl yararlandmz gryorsunuz. Bu ka
dizilerinin buradaki ilevini tam olarak anlayabilmek iin, bu kodlar bir de bu ka dizileri
olmadan yazmay deneyebilirsiniz.
Bu bilgileri, nemlerinden tr aklmzda tutmaya alalm. Buraya kadar anlatlan konular
hakknda zihnimizde belirsizlikler varsa veya baz noktalar tam olarak kavrayamadysak,
imdiye kadar rendiimiz konular tekrar gzden geirmemiz bizim iin epey faydal
olacaktr. Zira bundan sonraki blmlerde, yeni bilgilerin yansra, buraya kadar rendiimiz
eyleri de youn bir ekilde pratie dkeceiz. Bundan sonraki konular takip edebilmemiz

122 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

asndan, buraya kadar verdiimiz temel bilgileri iyice sindirmi olmak iimizi bir hayli
kolaylatracaktr.

11.3 eval() ve exec() Fonksiyonlar

Bir nceki blmn son rnek programnda eval() adl bir fonksiyonla karlamtk.
te imdi bu nemli fonksiyonun ne ie yaradn anlamaya alacaz. Ancak eval()
fonksiyonunu anlatmaya balamadan nce u uyary yapalm:
eval() EYTAN GLER OLAN BR FONKSYONDUR!
Bunun neden byle olduunu hem biz anlatacaz, hem de zaten bu fonksiyonu tandka
neden eval()e kar dikkatli olmanz gerektiini kendiniz de anlayacaksnz.
Dilerseniz ie basit bir eval() rnei vererek balayalm:
print("""
Basit bir hesap makinesi uygulamas.

leler:

+ toplama
- karma
* arpma
/ blme

Yapmak istediiniz ilemi yazp ENTER


tuuna basn. (rnein 23 ve 46 saylarn
arpmak iin 23 * 46 yazdktan sonra
ENTER tuuna basn.)
""")

veri = input("leminiz: ")


hesap = eval(veri)

print(hesap)

ngilizcede evaluate diye bir kelime bulunur. Bu kelime, deerlendirmeye tabi tutmak, ileme
sokmak, ilemek gibi anlamlar tar. te eval() fonksiyonundaki eval kelimesi bu evaluate
kelimesinin ksaltmasdr. Yani bu fonksiyonun grevi, kendisine verilen karakter dizilerini
deerlendirmeye tabi tutmak ya da ilemektir. Peki bu tam olarak ne anlama geliyor?
Aslnda yukardaki rnek program altrdmzda bu sorunun yantn kendi kendimize
verebiliyoruz. Bu program altrarak, leminiz: ifadesinden sonra, rnein, 45 * 76
yazp Enter tuuna basarsak programmz bize 3420 kts verecektir. Yani programmz
hesap makinesi ilevini yerine getirip 45 says ile 76 saysn arpacaktr. Dolaysyla,
yukardaki program kullanarak her trl aritmetik ilemi yapabilirsiniz. Hatta bu program,
son derece karmak aritmetik ilemlerin yaplmasna dahi msaade eder.
Peki programmz bu ilevi nasl yerine getiriyor? sterseniz kodlarn zerinden tek tek
geelim.
ncelikle programmzn en bana kullanm klavuzuna benzer bir metin yerletirdik ve bu
metni print() fonksiyonu yardmyla ekrana bastk.

11.3. eval() ve exec() Fonksiyonlar 123


Python 3 iin Trke Klavuz, Srm 3

Daha sonra kullancdan alacamz komutlar veri adl bir deikene atadk. Tabii ki
kullancyla iletiimi her zaman olduu gibi input() fonksiyonu yardmyla salyoruz.
Ardndan, kullancdan gelen veriyi eval() fonksiyonu yardmyla deerlendirmeye tabi
tutuyoruz. Yani kullancnn girdii komutlar ileme sokuyoruz. rnein, kullanc 46 / 2
gibi bir veri girdiyse, biz eval() fonksiyonu yardmyla bu 46 / 2 komutunu iletiyoruz. Bu
ilemin sonucunu da hesap adl baka bir deiken iinde depoluyoruz.
Eer burada eval() fonksiyonunu kullanmazsak, programmz, kullancnn girdii 45 * 76
komutunu hibir ileme sokmadan dmdz ekrana basacaktr. Yani:
print("""
Basit bir hesap makinesi uygulamas.

leler:

+ toplama
- karma
* arpma
/ blme

Yapmak istediiniz ilemi yazp ENTER


tuuna basn. (rnein 23 ve 46 saylarn
arpmak iin 23 * 46 yazdktan sonra
ENTER tuuna basn.)
""")

veri = input("leminiz: ")

print(veri)

Eer programmz yukardaki gibi, eval() fonksiyonu olmadan yazarsak, kullancmz 45 *


76 gibi bir komut girdiinde alaca cevap dmdz bir 45 * 76 kts olacaktr. te eval()
fonksiyonu, kullancnn girdii her veriyi bir Python komutu olarak alglar ve bu veriyi ileme
sokar. Yani 45 * 76 gibi bir ey grdnde, bu eyi dorudan ekrana yazdrmak yerine,
ilemin sonucu olan 3420 saysn verir.
eval() fonksiyonunun, yukarda anlattmz zelliklerini okuduktan sonra, Ne gzel bir
fonksiyon! Her iimi grr bu! dediinizi duyar gibiyim. Ama aslnda durum hi de yle
deil. Neden mi?
imdi yukardaki program tekrar altrn ve leminiz: ifadesinden sonra u cevab verin:
print("Merhaba Python!")

Bu komut yle bir kt vermi olmal:


Merhaba Python!
None

Not: Buradaki None deerini grmezden gelin. Bunu fonksiyonlar konusunu anlatrken
inceleyeceiz.

Grdnz gibi, yazdmz program, kullancnn girdii Python komutunun iletilmesine


sebep oldu. Bu noktada, Eee, ne olmu! demi olabilirsiniz. Gelin bir de una bakalm. imdi
program tekrar altrp u cevab verin:

124 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

open("deneme.txt", "w")

Bu cevap, bilgisayarnzda deneme.txt adl bir dosya oluturulmasna sebep oldu. Belki
farkndasnz, belki farknda deilsiniz, ama aslnda u anda kendi yazdnz program
sizin kontrolnzden tamamen kt. Siz aslnda bir hesap makinesi program yazmtnz.
Ama eval() fonksiyonu nedeniyle kullancya rastgele Python komutlarn altrma imkan
verdiiniz iin programnz sadece aritmetik ilemleri hesaplamak iin kullanlmayabilir. Byle
bir durumda kt niyetli (ve bilgili) bir kullanc size ok byk zarar verebilir. Mesela
kullancnn, yukardaki programa yle bir cevap verdiini dnn:
__import__("os").system("dir")

Burada anlamadnz eyleri imdilik bir kenara brakp, bu komutun sonularna odaklann.
Grdnz gibi, yukardaki programa bu cevab vererek mevcut dizin altndaki btn
dosyalar listeleyebildik. Yani programmz bir anda amacn at. Artk bu aamadan sonra
bu program eytani bir amaca ynelik olarak kullanmak tamamen program kullanan kiiye
kalm... Bu programn, bir web sunucusu zerinde alan bir uygulama olduunu ve
bu program kullananlarn yukardaki gibi masumane bir ekilde dizin iindeki dosyalar
listeleyen bir komut yerine, dizin iindeki dosyalar ve hatta sabit disk zerindeki her eyi
silen bir komut yazdn dnn... Yanl yazlm bir program yznden btn verilerinizi
kaybetmeniz iten bile deildir. (Bahsettiim o, btn sabit diski silen komutu kendi
sisteminizde vermemeniz gerektiini sylememe gerek yok, deil mi?)
Eer SQL Injection kavramn biliyorsanz, yukardaki kodlarn yol at gvenlik an gayet
iyi anlam olmalsnz. Zaten internet zerinde yaygn bir ekilde kullanlan ve web sitelerini
hedef alan SQL Injection tarz saldrlar da ayn mantk zerinden gerekletiriliyor. SQL
Injection metoduyla bir web sitesine saldran cracker lar, o web sitesini programlayan kiinin
(ounlukla farknda olmadan) kullancya verdii rastgele SQL komutu iletme yetkisini
ktye kullanarak gizli ve zel bilgileri ele geirebiliyorlar. rnein SQL Injection metodu
kullanlarak, bir web sitesine ait veritabannn ierii tamamen silinebilir. Ayn ekilde,
yukardaki eval() fonksiyonu da kullanclarnza rastgele Python komutlarn altrma
yetkisi verdii iin kt niyetli bir kullancnn programnza szmasna yol aabilecek
potansiyele sahiptir.
Peki eval() fonksiyonunu asla kullanmayacak myz? Elbette kullanacaz. Bu fonksiyonun
kullanmn gerektiren durumlarla da karlaabilirsiniz. Ama unu asla aklnzdan karmayn:
eval() fonksiyonu her ne kadar son derece yetenekli ve gl bir ara da olsa yanl ellerde
ykc sonular dourabilir. Program yazarken, eer eval() kullanmanz gerektiren bir
durumla kar karya olduunuzu dnyorsanz, bir kez daha dnn. eval() ile elde
edeceiniz etkiyi muhtemelen baka ve ok daha iyi yntemlerle de elde edebilirsiniz. stelik
performans asndan eval() pek iyi bir tercih deildir, nk bu fonksiyon (ou durumda
farketmeseniz de) aslnda yava alr. O yzden, eval() fonksiyonunu kullanacanz zaman,
bunun art ve eksilerini ok iyi tartn: Bu fonksiyonu kullanmak size ne kazandryor, ne
kaybettiriyor?
Ayrca eval() fonksiyonu kullanlaca zaman, kullancdan gelen veri bu fonksiyona
parametre olarak verilmeden nce sk bir kontrolden geirilir. Yani kullancnn girdii veri
eval() araclyla dorudan deerlendirmeye tabi tutulmaz. Araya bir kontrol mekanizmas
yerletirilir. rnein, yukardaki hesap makinesi programnda kullancnn girecei verileri
sadece saylar ve ilelerle snrlandrabilirsiniz. Yani kullancnzn, izin verilen deerler harici
bir deer girmesini engelleyebilirsiniz. Bu durumu somutlatrmak iin yle bir diyagram
izebiliriz:

11.3. eval() ve exec() Fonksiyonlar 125


Python 3 iin Trke Klavuz, Srm 3

Yukardaki diyagram eval() fonksiyonunun yanl uygulan biimini gsteriyor. Grdnz


gibi, veri dorudan eval() fonksiyonuna gidiyor ve kt olarak veriliyor. Byle bir durumda,
eval() fonksiyonu kullancdan gelen verinin ne olduuna bakmadan, veriyi dorudan komut
olarak deerlendirip iletecei iin programnz kullancnn insafna terketmi oluyorsunuz.
Aadaki diyagram ise eval() fonksiyonunun doru uygulan biimini gsteriyor:

Burada ise, veri eval() fonksiyonuna ulamadan nce kontrolden geiriliyor. Eer veri
ancak kontrol aamasndan geerse eval() fonksiyona ulaabilecek ve oradan da kt olarak
verilebilecektir. Bylece kullancdan gelen komutlar szme imkanna sahip oluyoruz.
Grdnz gibi, Python eval() gibi bir fonksiyon yardmyla karakter dizileri iinde
geen Python kodlarn ayklayp bunlar altrabiliyor. Bu sayede, mesela bize input()
fonksiyonu araclyla gelen bir karakter dizisi iindeki Python kodlarn iletme imkanna
sahip olabiliyoruz. Bu zellik, dikkatli kullanldnda, ilerinizi epey kolaylatrabilir.
Pythonda eval() fonksiyonuna ok benzeyen exec() adl baka bir fonksiyon daha bulunur.
eval() ile yapamadmz baz eyleri exec() ile yapabiliriz. Bu fonksiyon yardmyla, karakter
dizileri iindeki ok kapsaml Python kodlarn iletebilirsiniz.
rnein eval() fonksiyonu bir karakter dizisi iindeki deiken tanmlama ilemini yerine
getiremez. Yani eval() ile yle bir ey yapamazsnz:
>>> eval("a = 45")

Ama exec() ile byle bir ilem yapabilirsiniz:


>>> exec("a = 45")

Bylece a adl bir deiken tanmlam olduk. Kontrol edelim:


>>> print(a)

45

eval() ve exec() fonksiyonlar zellikle kullancdan alnan verilerle dorudan ilem


yapmak gereken durumlarda iinize yarar. rnein bir hesap makinesi yaparken eval()
fonksiyonundan yararlanabilirsiniz.
Ayn ekilde mesela insanlara Python programlama dilini reten bir program yazyorsanz
exec() fonksiyonunu yle kullanabilirsiniz:

126 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

d1 = """

Python'da ekrana kt verebilmek iin print() adl bir


fonksiyondan yararlanyoruz. Bu fonksiyonu yle kullanabilirsiniz:

>>> print("Merhaba Dnya")

imdi de ayn kodu siz yazn!

>>> """

girdi = input(d1)

exec(girdi)

d2 = """

Grdnz gibi print() fonksiyonu, kendisine


parametre olarak verilen deerleri ekrana basyor.

Bylece ilk dersimizi tamamlam olduk. imdi bir


sonraki dersimize geebiliriz."""

print(d2)

Burada exec() ile yaptmz ii eval() ile de yapabiliriz. Ama mesela eer bir sonraki
derste Pythonda deikenler konusunu retecekseniz, eval() yerine exec() fonksiyonunu
kullanmak durumunda kalabilirsiniz.
eval() fonksiyonunu anlatrken gvenlik ile ilgili olarak sylediimiz her ey exec()
fonksiyonu iin de geerlidir. Dolaysyla bu iki fonksiyonu ok dikkatli bir ekilde kullanmanz
ve bu fonksiyonlarn dourduu gvenlik ann bilincinde olmanz gerekiyor.
Henz Python bilgilerimiz ok kstl olduu iin eval() ve exec() fonksiyonlarn btn
ayrntlaryla inceleyemiyoruz. Ama bilgimiz arttka bu fonksiyonlarn ne kadar gl (ve
tehlikeli) aralar olduunu siz de greceksiniz.

11.4 format() Metodu

Python programlama dili iindeki ok temel baz aralar incelediimize gre, bu noktada
Pythondaki kk ama nemli bir konuya deinelim bu blm kapatmadan nce.
nternette dolarken mutlaka una benzer bir sayfayla karlam olmalsnz:

11.4. format() Metodu 127


Python 3 iin Trke Klavuz, Srm 3

Burada belli ki adres ubuuna fdkgd.com diye bir URL yazmz, ama byle bir internet adresi
olmad iin, kullandmz internet taraycs bize yle bir mesaj vermi:
Hata! Google Chrome fdkgd.com sitesini bulamad

imdi de dadasdaf.com adresini arayalm...


Yine byle bir adres olmad iin, bu defa taraycmz bize yle bir uyar gsterecek:
Hata! Google Chrome dadasdaf.com sitesini bulamad

Grdnz gibi, hata mesajlarnda deien tek yer, aradmz sitenin adresi. Yani internet
taraycmz bu hata iin yle bir taslaa sahip:
Hata! Google Chrome ... sitesini bulamad

Burada ... ile gsterdiimiz yere, bulunamayan URL yerletiriliyor. Peki byle bir eyi Python
programlama dili ile nasl yapabiliriz?
ok basit:

#ncelikle kullancdan bir internet adresi girmesini istiyoruz


url = input("Ltfen ulamak istediiniz sitenin adresini yazn: ")

#imdi de bu adresin bulunamad konusunda kullancy bilgilendiriyoruz


print("Hata! Google Chrome", url, "sitesini bulamad")

Grdnz gibi, imdiye kadar rendiimiz bilgileri kullanarak byle bir program rahatlkla
yazabiliyoruz.
Peki ya biz kullancnn girdii internet adresini mesela trnak iinde gstermek istersek ne
olacak? Yani rnein yle bir kt vermek istersek:
Hata! Google Chrome 'fdsfd.com' sitesini bulamad

Bunun iin yine karakter dizisi birletirme ynteminden yararlanabilirsiniz:

#ncelikle kullancdan bir internet adresi girmesini istiyoruz


url = input("Ltfen ulamak istediiniz sitenin adresini yazn: ")

#imdi de bu adresin bulunamad konusunda kullancy bilgilendiriyoruz


print("Hata! Google Chrome", "'" + url + "'", "sitesini bulamad")

Burada, + iaretlerini kullanarak, kullancnn girdii adresin sana ve soluna birer trnak
iaretini nasl yerletirdiimize dikkat edin.
Grdnz gibi bu yntem ie yaryor, ama ortaya kan karakter dizisi de olduka karmak
grnyor. te bu tr karakter dizisi biimlendirme ilemleri iin Python bize ok faydal bir
ara sunuyor. Bu aracn ad format().
Bu arac yle kullanyoruz:

#ncelikle kullancdan bir internet adresi girmesini istiyoruz


url = input("Ltfen ulamak istediiniz sitenin adresini yazn: ")

#imdi de bu adresin bulunamad konusunda kullancy bilgilendiriyoruz


print("Hata! Google Chrome {} sitesini bulamad".format(url))

Bir de bulunamayan internet adresini trnak iine alalm:

128 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

print("Hata! Google Chrome '{}' sitesini bulamad".format(url))

Gryorsunuz ya, biraz nce karakter dizisi birletirme yntemini kullanarak


gerekletirdiimiz ilemi, ok daha basit bir yolla gerekletirme imkan sunuyor bize
bu format() denen ara...
Peki format() nasl alyor?
Bunu anlamak iin u basit rneklere bir bakalm:
>>> print("{} ve {} iyi bir ikilidir".format("Python", "Django"))

'Python ve Django iyi bir ikilidir'

>>> print("{} {}'yi seviyor!".format("Ali", "Aye"))

'Ali Aye'yi seviyor!'

>>> print("{} {} yanda bir {}dur".format("Ahmet", "18", "futbolcu"))

'Ahmet 18 yanda bir futbolcudur'

Elbette bu rnekleri yle de yazabilirdik:


>>> metin = "{} ve {} iyi bir ikilidir"
>>> metin.format("Python", "Django")

'Python ve Django iyi bir ikilidir'

>>> metin = "{} {}'yi seviyor!"


>>> metin.format("Ali", "Aye")

'Ali Aye'yi seviyor!'

>>> metin = "{} {} yanda bir {}dur"


>>> metin.format("Ahmet", "18", "futbolcu")

'Ahmet 18 yanda bir futbolcudur'

Burada taslak metni dorudan format() metoduna parametre olarak vermeden nce bir
deikene atadk. Bylece bu metni daha kolay bir ekilde kullanabildik.
Bu rneklerin, format() denen arac anlamak konusunda size epey kir verdiini
zannediyorum. Ama isterseniz bu aracn ne olduunu ve nasl altn daha ayrntl olarak
incelemeye gemeden nce baka bir rnek daha verelim.
Varsayalm ki kullancdan ald bilgiler dorultusunda, zel bir konu zerine dileke
oluturan bir program yazmak istiyorsunuz.
Dileke taslamz u ekilde olsun:
tarih:

T.C.
... NVERSTES
... Fakltesi Dekanlna

11.4. format() Metodu 129


Python 3 iin Trke Klavuz, Srm 3

Faklteniz ..........Blm ......... numaral rencisiyim. Ekte sunduum


belgede belirtilen mazeretim gereince ....... Eitim-retim Yl .........
yarylnda renime ara izni (kayt dondurma) istiyorum.

Bilgilerinizi ve gereini arz ederim.

mza

Ad-Soyad :
T.C. Kimlik No. :
Adres :
Tel. :
Ekler :

Amacnz bu dilekedeki boluklara gelmesi gereken bilgileri kullancdan alp, eksiksiz bir
dileke ortaya karmak.
Kullancdan bilgi alma ksm kolay. input() fonksiyonunu kullanarak gerekli bilgileri
kullancdan alabileceimizi biliyorsunuz:
tarih = input("tarih: ")
niversite = input("niversite ad: ")
faklte = input("faklte ad: ")
blm = input("blm ad: ")
renci_no = input("renci no. :")
retim_yl = input("retim yl: ")
yaryl = input("yaryl: ")
ad = input("rencinin ad: ")
soyad = input("rencinin soyad: ")
tc_kimlik_no = input("TC Kimlik no. :")
adres = input("adres: ")
tel = input("telefon: ")
ekler = input("ekler: ")

Bilgileri kullancdan aldk. Peki ama bu bilgileri dileke tasla iindeki boluklara nasl
yerletireceiz?
u ana kadar rendiimiz print() fonksiyonunu ve \t ve \n gibi ka dizilerini kullanarak
istediiniz kty elde etmeyi deneyebilirsiniz. Ama denediinizde siz de greceksiniz ki,
bu tr yntemleri kullanarak yukardaki dileke taslan doldurmak inanlmaz zor ve vakit
alc olacaktr. Halbuki bunlarn hibirine gerek yok. nk Python bize bu tr durumlarda
kullanlmak zere ok pratik bir ara sunuyor. imdi ok dikkatlice inceleyin u kodlar:
dileke = """
tarih: {}

T.C.
{} NVERSTES
{} Fakltesi Dekanlna

Faklteniz {} Blm {} numaral rencisiyim. Ekte sunduum belgede


belirtilen mazeretim gereince {} Eitim-retim Yl {}.
yarylnda renime ara izni (kayt dondurma) istiyorum.

Bilgilerinizi ve gereini arz ederim.

130 Blm 11. Kullancdan Bilgi Almak


Python 3 iin Trke Klavuz, Srm 3

mza

Ad : {}
Soyad : {}
T.C. Kimlik No. : {}
Adres : {}
Tel. : {}
Ekler : {}
"""

tarih = input("tarih: ")


niversite = input("niversite ad: ")
faklte = input("faklte ad: ")
blm = input("blm ad: ")
renci_no = input("renci no. :")
retim_yl = input("retim yl: ")
yaryl = input("yaryl: ")
ad = input("rencinin ad: ")
soyad = input("rencinin soyad: ")
tc_kimlik_no = input("TC Kimlik no. :")
adres = input("adres: ")
tel = input("telefon: ")
ekler = input("ekler: ")

print(dileke.format(tarih, niversite, faklte, blm,


renci_no, retim_yl, yaryl,
ad, soyad, tc_kimlik_no,
adres, tel, ekler))

Bu kodlara (ve bundan nceki rneklere) bakarak birka tespitte bulunalm:


1. Taslak metinde kullancdan alnacak bilgilerin olduu yerlere birer {} iareti yerletirdik.
2. Taslaktaki eksiklikleri tamamlayacak verileri input() fonksiyonu yardmyla kullancdan
tek tek aldk.
3. Son olarak, print() fonksiyonu yardmyla metni tam bir ekilde ekrana kt olarak
verdik.
imdi son tespitimizi biraz aklayalm. Grdnz gibi, print() fonksiyonu iinde
dileke.format() gibi bir yap var. Burada dileke deikenine nokta iareti ile balanm
format() adl, fonksiyon benzeri bir ara gryoruz. Bu araca teknik dilde metot ad verilir.
format() metodunun parantezleri iinde ise, kullancdan alp birer deikene atadmz
veriler yer alyor.
Dilerseniz yukarda olan biteni daha net anlayabilmek iin bu konunun bana verdiimiz
rneklere geri dnelim.
lk olarak yle bir rnek vermitik:

#ncelikle kullancdan bir internet adresi girmesini istiyoruz


url = input("Ltfen ulamak istediiniz sitenin adresini yazn: ")

#imdi de bu adresin bulunamad konusunda kullancy bilgilendiriyoruz


print("Hata! Google Chrome {} sitesini bulamad".format(url))

Burada kullancnn girecei internet adresinin yerini tutmas iin {} iaretlerinden

11.4. format() Metodu 131


Python 3 iin Trke Klavuz, Srm 3

yararlanarak yle bir karakter dizisi oluturduk:


"Hata! Google Chrome {} sitesini bulamad"

Grdnz gibi, {} iareti karakter dizisi iinde URLnin gelecei yeri tutuyor. Bu {} iaretinin
yerine neyin geleceini format() metodunun parantezleri iinde belirtiyoruz. Dikkatlice
bakn:
print("Hata! Google Chrome {} sitesini bulamad".format(url))

Elbette eer istersek yukardaki rnei yle de yazabilirdik:


url = input("Ltfen ulamak istediiniz sitenin adresini yazn: ")

#Kullancya gsterilecek hata iin bir taslak metin oluturuyoruz


hata_tasla = "Hata! Google Chrome {} sitesini bulamad"

print(hata_tasla.format(url))

Burada hata metnini ieren karakter dizisini dorudan format() metoduna balamak yerine,
bunu bir deikene atayp, format() metodunu bu deikene baladk.
Bunun dnda u rnekleri de vermitik:
>>> metin = "{} ve {} iyi bir ikilidir"
>>> metin.format("Python", "Django")

'Python ve Django iyi bir ikilidir

>>> metin = "{} {}'yi seviyor!"


>>> metin.format("Ali", "Aye")

'Ali Aye'yi seviyor!'

>>> metin = "{} {} yanda bir {}dur"


>>> metin.format("Ahmet", "18", "futbolcu")

'Ahmet 18 yanda bir futbolcudur'

Burada da, grdz gibi, ncelikle bir karakter dizisi tanmlyoruz. Bu karakter dizisi
iindeki deiken deerleri ise {} iaretleri ile gsteriyoruz. Daha sonra format() metodunu
alp bu karakter dizisine balyoruz. Karakter dizisi iindeki {} iaretleri ile gsterdiimiz
yerlere gelecek deerleri de format() metodunun parantezleri iinde gsteriyoruz. Yalnz
burada una dikkat etmemiz lazm: Karakter dizisi iinde ka tane {} iareti varsa, format()
metodunun parantezleri iinde de o sayda deer olmas gerekiyor.
Bu yapnn, yazdmz programlarda iimizi ne kadar kolaylatracan tahmin edebilirsiniz.
Ksa karakter dizilerinde pek belli olmayabilir, ama zellikle ok uzun ve boluklu karakter
dizilerini biimlendirirken format() metodunun hayat kurtardna kendiniz de ahit
olacaksnz.
lerleyen derslerimizde format() metodunu ve karakter dizisi biimlendirme konusunu ok
daha ayrntl bir ekilde inceleyeceiz. Ancak yukarda verdiimiz bilgiler format() metodunu
verimli bir ekilde kullanabilmenizi salamaya yetecek dzeydedir.

132 Blm 11. Kullancdan Bilgi Almak


BLM 12

Koullu Durumlar

Artk Python programlama dilinde belli bir noktaya geldik saylr. Ama eer farkettiyseniz,
yine de elimizi kolumuzu balayan, istediimiz eyleri yapmamza engel olan bir eyler var.
te bu blmde, Python programlama dilinde hareket alanmz bir hayli geniletecek aralar
tanyacaz.
Aslnda sadece bu blmde deil, bu blm takip eden her blmde, hareket alanmz
kstlayan duvarlar tek tek yktmza ahit olacaksnz. zellikle bu blmde inceleyeceimiz
koullu durumlar konusu, tabir yerindeyse, Pythonda boyut atlamamz salayacak.
O halde hi vakit kaybetmeden yola koyulalm...
imdiye kadar rendiimiz Python bilgilerini kullanarak yle bir program yazabileceimizi
biliyorsunuz:
ya = 15

print("""Programa hogeldiniz!

Programmz kullanabilmek iin en az


13 yanda olmalsnz.""")

print("Yanz: ", ya)

Burada yaptmz ey ok basit. ncelikle, deeri 15 olan, ya adl bir deiken tanmladk.
Daha sonra, programmz altran kullanclar iin bir hogeldin mesaj hazrladk. Son
olarak da ya deikeninin deerini ekrana yazdrdk.
Bu programn zellii tek sesli bir uygulama olmasdr. Yani bu programda kullancyla
herhangi bir etkileim yok. Burada btn deerleri/deikenleri programc olarak kendimiz
belirliyoruz. Bu programn ne kadar yavan olduunu herhalde sylemeye gerek yok.
Ancak yine nceki derslerde rendiimiz input() fonksiyonu yardmyla yukardaki
programn zerindeki yavanl bir nebze de olsa atabilir, bu program rahatlkla ok sesli
bir hale getirebilir, yani kullancyla etkileim iine girebiliriz.
Yukardaki tek sesli uygulamay, input() fonksiyonunu kullanarak ok sesli bir hale nasl
getireceimizi gayet iyi bildiinize eminim:
print("""Programa hogeldiniz!

Programmz kullanabilmek iin en az


13 yanda olmalsnz.""")

133
Python 3 iin Trke Klavuz, Srm 3

print("Ltfen yanz girin.\n")

ya = input("Yanz: \t")

print("Yanz: ", ya)

Tpk bir nceki uygulamada olduu gibi, burada da yaptmz ey ok basit. lk rnekte
ya deikeninin deerini kendimiz elle yazmtk. kinci rnekte ise bu ya deikenini
kullancdan alyoruz ve tpk ilk rnekte olduu gibi, bu deikenin deerini ekrana
yazdryoruz.
Bu arada, yukardaki uygulamada yer verdiimiz \n ve \t adl ka dizileri de artk sizin
iin olduka tandk. \n ka dizisi yardmyla bir alt satra getiimizi, \t adl ka dizisi
yardmyla da bir sekmelik boluk braktmz biliyorsunuz.
Grdnz gibi, u ana kadar rendiklerimizle ancak kullancdan gelen ya bilgisini
ekrana yazdrabiliyoruz. rendiimiz input() fonksiyonu bize kullancdan bilgi alma imkan
salyor. Ama kullancdan gelen bu bilgiyi imdilik ancak olduu gibi kullanabiliyoruz. Yani
mesela yukardaki rnei dikkate alarak konuacak olursak, kullancnn ya eer 13n
zerindeyse onu programa kabul edecek, yok eer 13 yan altndaysa da programdan
atacak bir mekanizma retemiyoruz. Yapabildiimiz tek ey, kullancnn girdii veriyi ekrana
yazdrmak.
Yukarda verdiimiz rneklerle nereye varmaya altmz az ok tahmin etmisinizdir.
Dikkat ederseniz yukarda szn ettiimiz ey koullu bir durum. Yani aslnda yapmak
istediimiz ey, kullancnn yan denetleyip, onun programa kabul edilmesini 13 yandan
byk olma kouluna balamak.
sterseniz tam olarak neden bahsettiimizi anlayabilmek iin, birka vaka rnei verelim.
Diyelim ki Googlen Gmail hizmeti araclyla bir e.posta hesab aldnz. Bu hesaba gireceiniz
zaman Gmail size bir kullanc ad ve parola sorar. Siz de kendinize ait kullanc adn ve
parolay sayfadaki kutucuklara yazarsnz. Eer yazdnz kullanc ad ve parola doruysa
hesabnza eriebilirsiniz. Ama eer kullanc adnz ve parolanz doru deilse hesabnza
eriemezsiniz. Yani e.posta hesabnza erimeniz, kullanc ad ve parolay doru girme
kouluna baldr.
Ya da u vaka rneini dnelim: Diyelim ki Pardusta komut satr araclyla gncelleme
ilemi yapacaksnz. sudo pisi up komutunu verdiiniz zaman gncellemelerin listesi size
bildirilecek, bu gncellemeleri yapmak isteyip istemediiniz sorulacaktr. Eer evet cevab
verirseniz gncelleme ilemi balar. Ama eer hayr cevab verirseniz gncelleme ilemi
balamaz. Yani gncelleme ileminin balamas kullancnn evet cevab vermesi kouluna
baldr.
te bu blmde biz bu tr koullu durumlardan sz edeceiz.

12.1 Koul Deyimleri

Hi kukusuz, koula bal durumlar Pythondaki en nemli konulardan biridir. Giri


blmnde bahsettiimiz koullu ilemleri yapabilmek iin koul deyimleri ad verilen
birtakm aralardan yararlanacaz. Gelin imdi bu aralarn neler olduunu grelim.

134 Blm 12. Koullu Durumlar


Python 3 iin Trke Klavuz, Srm 3

12.1.1 if

Python programlama dilinde koullu durumlar belirtmek iin adet deyimden


yararlanyoruz:
if
elif
else
sterseniz nce if deyimi ile balayalm...
Eer daha nceden herhangi bir programlama dilini az da olsa kurcalama frsatnz olduysa,
bir programlama dilinde if deyimlerinin ne ie yaradn az ok biliyorsunuzdur. Daha
nceden hi programclk deneyiminiz olmamsa da ziyan yok. Zira bu blmde if
deyimlerinin ne ie yaradn ve nerelerde kullanldn enine boyuna tartacaz.
ngilizce bir kelime olan if , Trkede eer anlamna gelir. Anlamndan da karabileceimiz
gibi, bu kelime bir koul bildiriyor. Yani eer bir ey falanca ise... ya da eer bir ey lanca
ise... gibi... te biz Pythonda bir koula balamak istediimiz durumlar if deyimi araclyla
gstereceiz.
Gelin isterseniz bu deyimi nasl kullanacamza dair ufack bir rnek vererek ie balayalm:
ncelikle elimizde yle bir deiken olsun:
n = 255

Yukarda verdiimiz deikenin deerinin bir karakter dizisi deil, aksine bir say olduunu
gryoruz. imdi bu deikenin deerini sorgulayalm:
if n > 10:

Burada saynn 10dan byk olup olmadna bakyoruz.


Burada grdmz > iaretinin ne demek olduunu aklamaya gerek yok sanrm.
Hepimizin bildii byktr iareti Pythonda da aynen bildiimiz ekilde kullanlyor. Mesela
kktr demek isteseydik, < iaretini kullanacaktk. sterseniz hemen urada araya girip bu
iaretleri yeniden hatrlayalm:
le Anlam
> byktr
< kktr
>= byk eittir
<= kk eittir
== eittir
!= eit deildir
Grdnz gibi hibiri bize yabanc gelecek gibi deil. Yalnzca en sondaki eittir (== ) ve
eit deildir (!= ) iaretleri biraz deiik gelmi olabilir. Burada eittir iaretinin = olmadna
dikkat edin. Pythonda = iaretini deer atama ilemleri iin kullanyoruz. == iaretini ise iki
adet deerin birbirine eit olup olmadn denetlemek iin... Mesela:
>>> a = 26

Burada deeri 26 olan a adl bir deiken belirledik. Yani a deikenine deer olarak 26
saysn atadk. Ayrca burada, deer atama ileminin ardndan Enter tuuna bastktan sonra
Python hibir ey yapmadan bir alt satra geti. Bir de una bakalm:

12.1. Koul Deyimleri 135


Python 3 iin Trke Klavuz, Srm 3

>>> a == 26

True

Burada ise yaptmz ey a deikeninin deerinin 26 olup olmadn sorgulamak a == 26


komutunu verdikten sonra Python bize True diye bir kt verdi. Bu ktnn anlamn biraz
sonra reneceiz. Ama imdi isterseniz konuyu daha fazla datmayalm. Biz imdilik sadece
= ve == iaretlerinin birbirinden tamamen farkl anlamlara geldiini bilelim yeter.
Ne diyorduk?
if n > 10:

Bu ifadeyle Pythona yle bir ey demi oluyoruz:


Eer n saysnn deeri 10dan bykse...
Burada kullandmz iaretlere dikkat edin. En sonda bir adet : iaretinin olduunu gzden
karmyoruz. Bu tr iaretler Python iin ok nemlidir. Bunlar yazmay unutursak Python
gzmzn yana bakmayacaktr.
Dedik ki, if n > 10: ifadesi, eer n deikeninin deeri 10dan bykse... anlamna gelir. Bu
ifadenin eksik olduu apak ortada. Yani belli ki bu cmlenin bir de devam olmas gerekiyor.
O halde biz de devamn getirelim:
if n > 10:
print("say 10'dan byktr!")

Burada ok nemli bir durumla kar karyayz. Dikkat ederseniz, ikinci satr ilk satra
gre girintili yazdk. Elbette bunu irinlik olsun diye yapmadk. Python programlama
dilinde girintiler ok byk nem tar. Hatta ne kadarlk bir girinti verdiiniz bile
nemlidir. Eer Python kodlarna duyarl bir metin dzenleyici kullanyorsanz, kullandnz
metin dzenleyici ou durumda sizin yerinize uygun bir ekilde girintilemeyi yapacaktr.
Mesela IDLE adl gelitirme ortamn kullananlar, ilk satrdaki : iaretini koyup Enter
tuuna bastklarnda otomatik olarak girinti verildiini farkedeceklerdir. Eer kullandnz
metin dzenleyici, satrlar otomatik olarak girintilemiyorsa sizin bu girintileme ilemini
elle yapmanz gerekecektir. Yalnz elle girintilerken, ne kadar girinti vereceimize dikkat
etmeliyiz. Genel kural olarak 4 bolukluk bir girintileme uygun olacaktr. Girintileme
ilemini klavyedeki sekme (Tab ) tuuna basarak da yapabilirsiniz. Ama ayn program iinde
sekmelerle boluklar kartrmayn. Yani eer girintileme ilemini klavyedeki boluk (Space )
tuuna basarak yapyorsanz, program boyunca ayn ekilde yapn. (Ben size girinti verirken
Tab tuu yerine Space tuunu kullanmanz tavsiye ederim). Ksaca sylemek gerekirse;
Pythonda girintileme ve girintilemede tutarllk ok nemlidir. zellikle byk programlarda,
girintilemeler asndan tutarszlk gsterilmesi programn almamasna sebep olabilir.

Not: Pythonda girintileme konusuyla ilgili daha ayrntl bilgi iin:


http://www.istihza.com/blog/python-ve-metin-duzenleyiciler.html/

Eer yukardaki if blounu bir metin dzenleyici iine deil de dorudan etkileimli kabua
yazmsanz baz eyler dikkatinizi ekmi olmal. Etkileimli kabukta if say > 10: satrn
yazp Enter tuuna bastnzda yle bir grntyle karlam olmalsnz:
>>> if n > 10:
...

136 Blm 12. Koullu Durumlar


Python 3 iin Trke Klavuz, Srm 3

Dikkat ederseniz, >>> iareti, ... iaretine dnt. Eer bu noktada herhangi bir ey
yazmadan Enter tuuna basacak olursanz Python size yle bir hata mesaj verecektir:
File "<stdin>", line 2
^
IndentationError: expected an indented block

Hata mesajnda da sylendii gibi, Python bizden girintilenmi bir blok beklerken, biz onun bu
beklentisini karlamamz. Dolaysyla bize yukardaki hata mesajn gstermi. ... iaretini
grdkten sonra yapmamz gereken ey, drt kez boluk (Space ) tuuna basarak girinti
oluturmak ve if blounun devamn yazmak olmalyd. Yani yle:
>>> if n > 10:
... print("say 10'dan byktr!")
...

Grdnz gibi, print() fonksiyonunu yazp Enter tuuna bastktan sonra yine ... iaretini
grdk. Python burada bizden yeni bir satr daha bekliyor. Ama bizim yazacak baka bir
kodumuz olmad iin tekrar Enter tuuna basyoruz ve nihai olarak yle bir grnt elde
ediyoruz:
>>> if n > 10:
... print("say 10'dan byktr!")
...
say 10'dan byktr!
>>>

Demek ki 250 says 10 dan bykm! Ne byk bir bulu! Merak etmeyin, daha ok ey
rendike daha mantkl programlar yazacaz. Burada amacmz iin temelini kavramak.
Bunu da en iyi, (ok mantkl olmasa bile) basit programlar yazarak yapabiliriz.
imdi metin dzenleyicimizi aarak daha mantkl eyler yazmaya alalm. Zira yukardaki
rnekte deikeni kendimiz belirlediimiz iin, bu deikenin deerini if deyimleri yardmyla
denetlemek pek akla yatkn grnmyor. Ne de olsa deikenin deerinin ne olduunu
biliyoruz. Dolaysyla bu deikenin 10 saysndan byk olduunu da biliyoruz! Bunu if
deyimiyle kontrol etmek ok gerekli deil. Ama imdi daha makul bir i yapacaz. Deikeni
biz belirlemek yerine kullancya belirleteceiz:
say = int(input("Bir say giriniz: "))

if say > 10:


print("Girdiiniz say 10'dan byktr!")

if say < 10:


print("Girdiiniz say 10'dan kktr!")

if say == 10:
print("Girdiiniz say 10'dur!")

Grdnz gibi, art arda adet if blou kullandk. Bu kodlara gre, eer kullancnn
girdii say 10 dan bykse, ilk if blou iletilecek; eer say 10 dan kkse ikinci if blou
iletilecek; eer say 10a eit ise nc if blou iletilecektir. Peki ya kullanc muziplik
yapp say yerine harf yazarsa ne olacak? Byle bir ihtimal iin programmza herhangi bir
denetleyici yerletirmedik. Dolaysyla eer kullanc say yerine harf girerse programmz
hata verecek, yani kecektir. Bu tr durumlara kar nasl nlem alacamz ilerleyen
derslerimizde greceiz. Biz imdilik bildiimiz yolda yryelim.

12.1. Koul Deyimleri 137


Python 3 iin Trke Klavuz, Srm 3

Yukardaki rnekte input() ile gelen karakter dizisini, int() fonksiyonu yardmyla bir sayya
dntrdmze dikkat edin. Kullancdan gelen veriyi byklk-kklk ltne gre
inceleyeceimiz iin, gelen veriyi bir sayya dntrmemiz gerekiyor. Bunu da int()
fonksiyonu ile yapabileceimizi biliyorsunuz.
Elbette yukardaki dntrme ilemini yle de yapabilirdik:
say = input("Bir say giriniz: ")
say = int(say)

Burada nce input() fonksiyonuyla veriyi aldk, daha sonra bu veriyi ayr bir yerde sayya
dntrp tekrar say adl deikene atadk.
if deyimlerini kullanc ad veya parola denetlerken de kullanabiliriz. Mesela yle bir
program tasla yazabiliriz:
print("""
Dnyann en gelimi e.posta hizmetine
hogeldiniz. Yalnz hizmetimizden
yararlanmak iin nce sisteme giri
yapmalsnz.
""")

parola = input("Parola: ")

if parola == "12345678":
print("Sisteme Hogeldiniz!")

Grdnz gibi, programn banda trnak iaretlerinden yararlanarak uzun bir metni
kullancya gsterdik. Bu blm, kendiniz gze ho gelecek bir ekilde ssleyebilirsiniz de.
Eer kullanc, kendisine parola sorulduunda cevap olarak 12345678 yazarsa kullancy
sisteme alyoruz.
Yukardaki rnekte, kullancnn girdii parola 12345678 ise kendisine Sisteme
Hogeldiniz! mesajn gsteriyoruz. Mantk olarak bunun tersini yapmak da mmkndr.
Yani:
if parola != "12345678":
print("Ne yazk ki yanl parola girdiniz!")

Burada ise bir nceki rnein mantn ters evirdik. nceki rnekte parola deikeni
12345678 adl karakter dizisine eitse (if parola == "12345678") bir ilem yapyorduk.
Yukardaki rnekte ise parola deikeni 12345678 adl karakter dizisine eit deilse (if
parola != "12345678") bir ilem yapyoruz.
Bu iki rnein de aslnda ayn kapya ktn gryorsunuz. Tek deiiklik, kullancya
gsterilen mesajlardadr.
Bylece Pythondaki koullu durumlar zerindeki incelememizin ilk ve en nemli aamasn
geride brakm olduk. Dikkat ettiyseniz if deyimi sayesinde programlarmza karar vermeyi
rettik. Bu deyim yardmyla, kullancdan aldmz herhangi bir verinin nitelii zerinde
kapsaml bir karar verme ilemi yrtebiliyoruz. Yani artk programlarmz kullancdan alnan
veriyi olduu gibi kabul etmekle yetinmiyor. Kullancnn girdii verinin ne olduuna bal
olarak programlarmzn farkl ilemler yapmasn da salayabiliyoruz.
Daha nce de sylediimiz gibi, if deyimi dnda Pythonda koullu durumlar ifade etmek
iin kullandmz, elif ve else adl iki deyim daha vardr. Bunlar if ile birlikte kullanlrlar.
Gelin isterseniz bu iki deyimden, ad elif olana bakalm.

138 Blm 12. Koullu Durumlar


Python 3 iin Trke Klavuz, Srm 3

12.1.2 elif

Pythonda, if deyimleriyle birlikte kullanlan ve yine koul belirten bir baka deyim de elif
deyimidir. Buna yle bir rnek verebiliriz:
ya = int(input("Yanz: "))

if ya == 18:
print("18 iyidir!")

elif ya < 0:
print("Yok canm, daha neler!...")

elif ya < 18:


print("Gen bir kardeimizsin!")

elif ya > 18:


print("Eh, artk ya yava yava kemale eriyor!")

Yukardaki rnei yle yazmay da deneyebilirsiniz:


ya = int(input("Yanz: "))

if ya == 18:
print("18 iyidir!")

if ya < 0:
print("Yok canm, daha neler!...")

if ya < 18:
print("Gen bir kardeimizsin!")

if ya > 18:
print("Eh, artk ya yava yava kemale eriyor!")

Bu iki programn da ayn ilevi grdn dnebilirsiniz. Ancak ilk bakta pek belli olmasa
da, aslnda yukardaki iki program birbirinden farkl davranacaktr. rnein ikinci programda
eer kullanc eksi deerli bir say girerse hem if ya < 0 blou, hem de if ya < 18 blou
alacaktr. sterseniz yukardaki program altrp, cevap olarak eksi deerli bir say verin.
Ne demek istediimiz gayet net anlalacaktr.
Bu durum if ile elif arasndaki ok nemli bir farktan kaynaklanr. Buna gre if bize olas
btn sonular listeler, elif ise sadece doru olan ilk sonucu verir. Bu soyut tanmlamay
biraz daha somutlatralm:
a = int(input("Bir say giriniz: "))

if a < 100:
print("verdiiniz say 100'den kktr.")

if a < 50:
print("verdiiniz say 50'den kktr.")

if a == 100:
print("verdiiniz say 100'dr.")

if a > 100:

12.1. Koul Deyimleri 139


Python 3 iin Trke Klavuz, Srm 3

print("verdiiniz say 100'den byktr.")

if a > 150:
print("verdiiniz say 150'den byktr.")

Yukardaki kodlar altrdmzda, doru olan btn sonular listelenecektir. Yani mesela
kullanc 40 saysn girmise, ekrana verilecek kt yle olacaktr:
verdiiniz say 100'den kktr.
verdiiniz say 50'den kktr.

Burada 40 says hem 100 den, hem de 50 den kk olduu iin iki sonu da kt olarak
verilecektir. Ama eer yukardaki kodlar yle yazarsak:
a = int(input("Bir say giriniz: "))

if a < 100:
print("verdiiniz say 100'den kktr.")

elif a < 50:


print("verdiiniz say 50'den kktr.")

elif a == 100:
print("verdiiniz say 100'dr.")

elif a > 150:


print("verdiiniz say 150'den byktr.")

elif a > 100:


print("verdiiniz say 100'den byktr.")

Kullancnn 40 saysn girdiini varsaydmzda, bu defa programmmz yalnzca u kty


verecektir:
verdiiniz say 100'den kktr.

Grdnz gibi, elif deyimlerini kullandmz zaman, ekrana yalnzca doru olan ilk sonu
veriliyor. Yukarda 40 says hem 100 den hem de 50 den kk olduu halde, Python bu
saynn 100 den kk olduunu grr grmez sonucu ekrana basp, teki koul bloklarn
incelemeyi brakyor. if deyimlerini arka arkaya sraladmzda ise, Python btn olaslklar
tek tek deerlendirip, geerli olan btn sonular ekrana dkyor.
Bir sonraki blmde else deyimini rendiimiz zaman, elifin tam olarak ne ie yaradn
ok daha iyi anlamanz salayacak bir rnek vereceiz.

Not: imdiye kadar verdiimiz rneklerden de rahatlkla anlayabileceiniz gibi, ilk koul
blounda asla elif deyimi kullanlamaz. Bu deyimin kullanlabilmesi iin kendisinden nce
en az bir adet if blou olmaldr. Yani Pythonda koullu durumlar ifade ederken ilk koul
bloumuz her zaman if deyimi ile balamaldr.

elifi de incelediimize gre, koul bildiren deyimlerin sonuncusuna gz atabiliriz: else

140 Blm 12. Koullu Durumlar


Python 3 iin Trke Klavuz, Srm 3

12.1.3 else

imdiye kadar Pythonda koul bildiren iki deyimi rendik. Bunlar if ve elif idi. Bu blmde
ise koul deyimlerinin sonuncusu olan else deyimini greceiz. rendiimiz eyleri yle bir
gzden geirecek olursak, temel olarak yle bir durumla kar karya olduumuzu grrz:
if falanca:
bu ilemi yap

if filanca:
u ilemi yap

Veya yle bir durum:


if falanca:
bu ilemi yap

elif filanca:
u ilemi yap

if ile elif arasndaki fark biliyoruz. Eer if deyimlerini art arda sralayacak olursak, Python
doru olan btn sonular listeleyecektir. Ama eer if deyiminden sonra elif deyimini
kullanrsak, Python doru olan ilk sonucu listelemekle yetinecektir.
Bu blmde greceimiz else deyimi, yukardaki tabloya bambaka bir boyut kazandryor.
Dikkat ederseniz imdiye kadar rendiimiz deyimleri kullanabilmek iin ilgili btn
durumlar tanmlamamz gerekiyordu. Yani:
eer byle bir durum varsa:
bunu yap

eer yle bir durum varsa:


unu yap

eer filancaysa:
yle git

eer falancaysa:
byle gel

gibi...
Ancak her durum iin bir if blou yazmak bir sre sonra yorucu ve skc olacaktr. te bu
noktada devreye else deyimi girecek. elsein anlam kabaca udur:
Eer yukardaki koullarn hibiri gereklemezse...
Gelin isterseniz bununla ilgili yle bir rnek verelim:
soru = input("Bir meyve ad syleyin bana:")

if soru == "elma":
print("evet, elma bir meyvedir...")

elif soru == "karpuz":


print("evet, karpuz bir meyvedir...")

elif soru == "armut":

12.1. Koul Deyimleri 141


Python 3 iin Trke Klavuz, Srm 3

print("evet, armut bir meyvedir...")

else:
print(soru, "gerekten bir meyve midir?")

Eer kullanc soruya elma, karpuz veya armut cevab verirse, evet, ... bir meyvedir kts
verilecektir. Ama eer kullanc bu dnda bir cevap verirse, ... gerekten bir meyve
midir? ktsn grrz. Burada else deyimi, programmza u anlam katyor:
Eer kullanc yukarda belirlenen meyve adlarndan hi birini girmez, bunlarn
yerine bambaka bir ey yazarsa, o zaman else blou iinde belirtilen ilemi
gerekletir.
Dikkat ederseniz yukardaki kodlarda if deyimlerini art arda sralamak yerine ilk iften sonra
elif ile devam ettik. Peki yle bir ey yazarsak ne olur?
soru = input("Bir meyve ad syleyin bana:")

if soru == "elma":
print("evet, elma bir meyvedir...")

if soru == "karpuz":
print("evet, karpuz bir meyvedir...")

if soru == "armut":
print("evet, armut bir meyvedir...")

else:
print(soru, "gerekten bir meyve midir?")

Bu kodlar beklediiniz sonucu vermeyecektir. sterseniz yukardaki kodlar altrp ne demek


istediimizi daha iyi anlayabilirsiniz. Eer yukarda olduu gibi if deyimlerini art arda sralar
ve son olarak da bir else blou tanmlarsak, ekrana ilk bakta anlamsz gibi grnen bir kt
verilecektir:
evet, elma bir meyvedir...
elma gerekten bir meyve midir?

Burada olan ey u:
Soruya elma cevabn verdiimizi dnelim. Bu durumda, Python ilk olarak ilk if blounu
deerlendirecek ve soruya verdiimiz cevap elma olduu iin evet, elma bir meyvedir...
ktsn verecektir.
if ile elif arasndaki fark anlatrken, hatrlarsanz art arda gelen if bloklarnda Pythonn
olas btn sonular deerlendireceini sylemitik. te burada da byle bir durum sz
konusu. Grdnz gibi, ilk if bloundan sonra yine bir if blou geliyor. Bu nedenle Python
olas btn sonular deerlendirebilmek iin bloklar okumaya devam edecek ve sorunun
cevab karpuz olmad iin ikinci if blounu atlayacaktr.
Sonraki blok yine bir if blou olduu iin Python kodlar okumaya devam ediyor. Ancak
sorunun cevab armut da olmad iin, Python sonraki if blounu da geiyor ve bylece
else blouna ulayor.
Yukarda verdiimiz rnekteki gibi art arda if deyimlerinin sralanp en sona else deyiminin
yerletirildii durumlarda else deyimi sadece bir nceki if deyimini dikkate alarak ilem
yapar. Yani yukardaki rnekte kullancnn verdii cevap armut olmad iin else deyiminin

142 Blm 12. Koullu Durumlar


Python 3 iin Trke Klavuz, Srm 3

olduu blok almaya balar. Yukardaki rnee armut cevabn verirseniz ne demek
istediimi biraz daha iyi anlayabilirsiniz. armut cevab verilmesi durumunda sadece if
soru == "armut" ifadesinin olduu blok alr, else blou ise almaz. nk dediim gibi,
eer else bloundan nce art arda gelen if bloklar varsa, else deyimi yalnzca kendisinden
nceki son if blounu dikkate alr ve sanki yukardaki rnek yleymi gibi davranr:
if soru == "armut":
print("evet, armut bir meyvedir...")

else:
print(soru, "gerekten bir meyve midir?")

Bu tr durumlarda else deyimi bir nceki if bloundan nce gelen btn if bloklarn
grmezden gelir ve bylece u anlamsz grnen kt elde edilir:
evet, elma bir meyvedir...
elma gerekten bir meyve midir?

Szn z, kullancnn cevab elma olduu iin, yukardaki ktda yer alan ilk cmle ilk if
blounun almas sonucu ekrana baslyor. kinci cmle ise else bloundan bir nceki if
blou kullancnn cevabyla uyumad iin ekrana baslyor.
Yalnz bu dediimizden, else ifadesi if ile birlikte kullanlmaz, anlam karlmamal. Mesela
yle bir rnek yaplabilir:
soru = input("Programdan kmak istediinize emin misiniz? \
Eminseniz 'e' harfine basn : ")

if soru == "e":
print("Gle gle!")

else:
print("Peki, biraz daha sohbet edelim!")

Burada eer kullancnn cevab e ise if blou iletilecek, eer cevap e dnda herhangi bir
ey ise else blou alacaktr. Gayet mantkl bir sre. Ama eer yukardaki rnee bir if
blou daha eklerseniz iler beklediiniz gibi gitmez:
soru = input("Programdan kmak istediinize emin misiniz? \
Eminseniz 'e' harfine basn : ")

if soru == "e":
print("Gle gle!")

if soru == "b":
print("Kararsz kaldm imdi!")

else:
print("Peki, biraz daha sohbet edelim!")

Bu soruya e cevab verdiimizi dnelim. Bu cevap ilk if blouyla uyuuyor ve bylece


ekrana Gle gle! kts veriliyor. lk if bloundan sonra tekrar bir if blou daha geldii iin
Python btn olaslklar deerlendirmek amacyla bloklar okumaya devam ediyor ve cevap
b olmad iin ikinci if blounu atlyor ve bylece else blouna ulayor. Bir nceki rnekte
de sylediimiz gibi, else blou art arda gelen if bloklar grdnde sadece bir nceki if
blounu dikkate ald ve kullancnn cevab da b olmad iin ekrana Peki, biraz daha sohbet
edelim! ktsn veriyor ve ilk bakta tuhaf grnen yle bir kt retiyor:

12.1. Koul Deyimleri 143


Python 3 iin Trke Klavuz, Srm 3

Gle gle!
Peki, biraz daha sohbet edelim!

Dolaysyla, eer programnzda bir else blouna yer verecekseniz, ondan nce gelen koullu
durumlarn ilkini if ile sonrakileri ise elif ile balayn. Yani:
if koul_1:
sonu_1

elif koul_2:
sonu_2

elif koul_3:
sonu_3

else:
sonu_4

Ama eer else bloundan nce sadece tek bir koul blou yer alacaksa bunu if ile balayn.
Yani:
if koul_1:
sonu_1

else:
sonu_2

Programlarmzn doru almas ve istediimiz sonucu verebilmesi iin bu tr ayrntlara


olabildiince dikkat etmemiz gerekiyor. Neticede koullu durumlar mantkla ilgilidir.
Dolaysyla koullu durumlarla muhatap olurken mantnz hibir zaman devre d
brakmamalsnz.
Bir nceki blmde elif deyiminin tam olarak ne ie yaradn anlamamz salayacak bir
rnek vereceimizi sylemitik. imdi bu rnee bakalm:
boy = int(input("boyunuz ka cm?"))

if boy < 170:


print("boyunuz ksa")

elif boy < 180:


print("boyunuz normal")

else:
print("boyunuz uzun")

Yukarda yedi satrla hallettiimiz ii sadece if deyimleriyle yapmaya alrsanz bunun


ne kadar zor olduunu greceksiniz. Diyelim ki kullanc 165 cevabn verdi. Python
bu 165 saysnn 170 ten kk olduunu grnce boyunuz ksa cevabn verecek, teki
satrlar deerlendirmeyecektir. 165 says, elif ile gsterdiimiz koullu duruma da uygun
olduu halde (165 < 180), koul ilk blokta karland iin ikinci blok deerlendirmeye
alnmayacaktr.
Kullancnn 175 cevabn verdiini varsayalm: Python 175 saysn grnce nce ilk koula
bakacak, verilen 175 saysnn ilk koulu karlamadn grecektir (175 > 170). Bunun
zerine Python kodlar incelemeye devam edecek ve elif blounu deerlendirmeye alacaktr.

144 Blm 12. Koullu Durumlar


Python 3 iin Trke Klavuz, Srm 3

175 saysnn 180 den kk olduunu grnce de kt olarak boyunuz normal cevabn
verecektir.
Peki ya kullanc 190 cevabn verirse ne olacak? Python yine nce ilk if blouna
bakacak ve 190 cevabnn bu bloa uymadn grecektir. Dolaysyla ilk blou brakp
ikinci bloa bakacaktr. 190 cevabnn bu bloa da uymadn grnce, bir sonraki blou
deerlendirmeye alacaktr. Bir sonraki blokta ise else deyimimiz var. Bu blmde
rendiimiz gibi, else deyimi, eer kullancnn cevab yukardaki koullarn hibirine
uymazsa bu blou altr, anlamna geliyor. Kullancnn girdii 190 cevab ne birinci ne
de ikinci bloktaki koula uyduu iin, normal bir ekilde else blou iletilecek, dolaysyla da
ekrana boyunuz uzun kts verilecektir.
Bylece Pythonda if, elif ve else deyimlerini incelemi olduk. Ancak tabii ki bu deyimlerle
iimiz henz bitmedi. Elimizdeki bilgiler imdilik bu deyimleri ancak bu kadar incelememize
yetiyor, ama ilerleyen sayfalarda baz baka aralar da bilgi daarcmza kattktan sonra bu
deyimlerin daha farkl ynlerini renme imkanna kavuacaz.

12.2 rnek Uygulama

nceki derslerimizde len() fonksiyonunu anlatrken yle bir program tasarsndan


bahsetmitik hatrlarsanz:
Diyelim ki sisteme kayt iin kullanc ad ve parola belirlenmesini isteyen bir
program yazyorsunuz. Yazacanz bu programda, belirlenebilecek kullanc ad
ve parolann toplam uzunluu 40 karakteri gemeyecek.
O zaman henz koullu durumlar renmemi olduumuz iin, yukarda bahsettiimiz
programn ancak u kadarlk ksmn yazabilmitik:
kullanc_ad = input("Kullanc adnz: ")
parola = input("Parolanz : ")

toplam_uzunluk = len(kullanc_ad) + len(parola)

Burada yapabildiimiz tek ey, kullancdan kullanc ad ve parola bilgilerini alp, bu bilgilerin
karakter uzunluunu lebilmekti. Ama artk koullu durumlar rendiimize gre bu
program eksiksiz olarak yazabiliriz. u kodlar dikkatlice inceleyin:
kullanc_ad = input("Kullanc adnz: ")
parola = input("Parolanz : ")

toplam_uzunluk = len(kullanc_ad) + len(parola)

mesaj = "Kullanc ad ve parolanz toplam {} karakterden oluuyor!"

print(mesaj.format(toplam_uzunluk))

if toplam_uzunluk > 40:


print("Kullanc adnz ile parolanzn ",
"toplam uzunluu 40 karakteri gememeli!")
else:
print("Sisteme hogeldiniz!")

Burada ncelikle kullancdan kullanc ad ve parola bilgilerini alyoruz. Daha sonra da


kullancdan gelen bu bilgilerin toplam karakter uzunluunu hesaplyoruz. Bunun iin len()

12.2. rnek Uygulama 145


Python 3 iin Trke Klavuz, Srm 3

fonksiyonundan yararlanmamz gerektiini hatrlyor olmalsnz.


Eer toplam uzunluk 40 karakterden fazla ise, if blounda verilen mesaj gsteriyoruz. Bunun
dndaki btn durumlarda ise else blounu devreye sokuyoruz.

146 Blm 12. Koullu Durumlar


BLM 13

leler

Bu blmde, aslnda pek de yabancs olmadmz ve hatta nceki derslerimizde stnkr


de olsa deindiimiz bir konuyu ok daha ayrntl bir ekilde ele alacaz. Burada
anlatacamz konu size yer yer skc gelebilir. Ancak bu konuyu hakkyla renmenizin,
programclk maceranz asndan hayati nemde olduunu rahatlkla syleyebilirim.
Gelelim konumuza...
Bu blmn konusu ileler. Peki nedir bu ile denen ey?
ngilizcede operator ad verilen ileler, sanda ve solunda bulunan deerler arasnda
bir iliki kuran iaretlerdir. Bir ilecin sanda ve solunda bulunan deerlere ise ilenen
(operand ) ad veriyoruz.

Not: Trkede ile yerine operatr, ilenen yerine de operant dendiine tank olabilirsiniz.

Biz bu blmde ileleri alt balk altnda inceleyeceiz:


1. Aritmetik leler
2. Karlatrma leleri
3. Bool leleri
4. Deer Atama leleri
5. Aitlik leleri
6. Kimlik leleri
Grdnz gibi, ilememiz gereken konu ok, gitmemiz gereken yol uzun. O halde hi vakit
kaybetmeden, aritmetik ilelerle yolculuumuza balayalm.

13.1 Aritmetik leler

Dedik ki, sanda ve solunda bulunan deerler arasnda bir iliki kuran iaretlere ile
(operator ) ad verilir. nceki derslerimizde temel ilelerin bazlarn renmitik. sterseniz
bunlar yle bir hatrlayalm:

147
Python 3 iin Trke Klavuz, Srm 3

+ toplama
- karma
* arpma
/ blme
** kuvvet
Bu ilelere aritmetik ileler ad verilir. Aritmetik ileler; matematikte kullanlan ve saylarla
aritmetik ilemler yapmamz salayan yardmc aralardr.
Dilerseniz bu tanm bir rnekle somutlatralm:
>>> 45 + 33

78

Burada 45 ve 33 deerlerine ilenen (operand ) ad verilir. Bu iki deer arasnda yer alan +
iareti ise bir iletir (operator ). Dikkat ederseniz + ileci 45 ve 33 adl ilenenler arasnda bir
toplama ilikisi kuruyor.
Bir rnek daha verelim:
>>> 23 * 46

1058

Burada da 23 ve 46 deerleri birer ilenendir. Bu iki deer arasnda yer alan * iareti ise,
ilenenler arasnda bir arpma ilikisi kuran bir iletir.
Ancak bir noktaya zellikle dikkatinizi ekmek istiyorum. Daha nceki derslerimizde de
deindiimiz gibi, + ve * ileleri Pythonda birden fazla anlama gelir. rnein yukardaki
rnekte + ileci, ilenenler arasnda bir toplama ilikisi kuruyor. Ama aadaki durum biraz
farkldr:
>>> "istihza" + ".com"

'istihza.com'

Burada + ileci ilenenler (istihza ve .com ) arasnda bir birletirme ilikisi kuruyor.
Tpk + ilecinde olduu gibi, * ileci de Pythonda birden fazla anlama gelir. Bu ilecin,
arpma ilikisi kurma ilevi dnda tekrar etme ilikisi kurma ilevi de vardr. Yani:
>>> "hzl " * 2

'hzl hzl '

...veya:
>>> "-" * 30

'------------------------------'

Burada * ilecinin, saylar arasnda arpma ilemi yapmak dnda bir grev stlendiini
gryoruz.
Pythonda bu tr farklar, yazacanz programn salkl alabilmesi asndan byk nem
tar. O yzden bu tr farklara kar her zaman uyank olmamz gerekiyor.
+ ve * ilelerinin aksine / ve - ileleri ise ilenenler arasnda sadece blme ve karma
ilikisi kurar. Bu ileler tek ilevlidir:

148 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

>>> 25 / 4

6.25

>>> 10 - 5

nceki derslerde grdmz ve yukarda da tekrar ettiimiz drt adet temel aritmetik ilece
u iki aritmetik ileci de ekleyelim:
% modls
// taban blme

lk nce modlsn ne olduunu ve ne ie yaradn anlamaya alalm.


u blme ilemine bir bakn:

Burada 02 says blme ileminin kalandr. te modls denen ile de blme ileminden
kalan bu deeri gsterir. Yani:
>>> 30 % 4

Grdnz gibi modls ileci (% ) gerekten de blme ileminden kalan sayy gsteriyor...
Peki bu bilgi ne iimize yarar?
Mesela bu bilgiyi kullanarak bir saynn tek mi yoksa ift mi olduunu tespit edebiliriz:
say = int(input("Bir say girin: "))

if say % 2 == 0:
print("Girdiiniz say bir ift saydr.")
else:
print("Girdiiniz say bir tek saydr.")

Eer bir say 2 ye blndnde kalan deer 0 ise o say ifttir. Aksi halde o say tektir.
Mesela:
>>> 14 % 2

Grdnz gibi, bir ift say olan 14 2 ye bldmzde kalan say 0 oluyor. nk ift
saylar 2 ye tam blnrler.
Bir de una bakalm:
>>> 15 % 2

13.1. Aritmetik leler 149


Python 3 iin Trke Klavuz, Srm 3

Bir tek say olan 15 ise 2 ye blndnde kalan say 1 oluyor. Yani 15 says 2 ye tam
blnmyor. Bu bilgiden yola karak 15 saysnn bir tek say olduunu syleyebiliyoruz.
Bir saynn tek mi yoksa ift mi olduunu tespit etme ilemini kmsememenizi tavsiye
ederim. Bir saynn tek mi yoksa ift mi olduu bilgisinin, arayz gelitirirken dahi iinize
yarayacandan emin olabilirsiniz.
Elbette modls ilecini bir saynn yalnzca 2 ye tam blnp blnmediini denetlemek
iin kullanmyoruz. Bu ileci kullanarak herhangi bir saynn herhangi bir sayya tam blnp
blnmediini de denetleyebilirsiniz. rnein:
>>> 45 % 4

>>> 36 % 9

Bu bilgiyi kullanarak mesela yle bir program yazabilirsiniz:


blnen = int(input("Bir say girin: "))
blen = int(input("Bir say daha girin: "))

ablon = "{} says {} saysna tam".format(blnen, blen)

if blnen % blen == 0:
print(ablon, "blnyor!")
else:
print(ablon, "blnmyor!")

Programmz, kullancnn girdii ilk saynn ikinci sayya tam blnp blnmediini
hesaplyor ve sonuca gre kullancy bilgilendiriyor. Bu kodlarda zellikle u satra dikkat
edin:
if blnen % blen == 0:
...

Programmzn temelini bu kod oluturuyor. nk bir saynn bir sayya tam blnp
blnmediini bu kodla belirliyoruz. Eer bir say baka bir sayya blndnde kalan deer,
yani modls 0 ise, o say br sayya tam blnyor demektir.
Ayrca bir saynn son basaman elde etmek iin de modlsten yararlanabilirsiniz. Herhangi
bir tamsay 10 a blndnde kalan (yani modls), blnen saynn son basama
olacaktr:
>>> 65 % 10

>>> 543 % 10

Programlama tecrbeniz arttka, aslnda modlsn ne kadar faydal bir ara olduunu
kendi gzlerinizle greceksiniz.
Modls ilecini rnekler eliinde ayrntl bir ekilde incelediimize gre sra geldi taban
blme ilecini aklamaya...

150 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

ncelikle u rnei inceleyelim:


>>> 5 / 2

2.5

Burada, bildiimiz blme ilecini (/ ) kullanarak basit bir blme ilemi yaptk. Elde ettiimiz
sonu doal olarak 2.5.
Matematikte blme ileminin sonucunun kesirli olmas durumuna kesirli blme ad verilir.
Bunun tersi ise tamsayl blme veya taban blmedir. Eer herhangi bir sebeple kesirli blme
ilemi deil de taban blme ilemi yapmanz gerekirse // ilecinden yararlanabilirsiniz:
>>> 5 // 2

Grdnz gibi, // ileci sayesinde blme ileminin sonucu kesirli deil, tamsay olarak elde
ediliyor.
Yukarda yaptmz taban blme ilemi ununla ayn anlama gelir:
>>> int(5 / 2)

Daha ak ifade etmemiz gerekirse:


>>> a = 5 / 2
>>> a

2.5

>>> int(a)

Burada olan u: 5 / 2 ileminin sonucu bir kayan noktal saydr (2.5 ). Bunu u ekilde teyit
edebiliriz:
>>> a = 5 / 2
>>> type(a)

<class 'float'>

Buradaki oat ktsnn oating point number, yani kayan noktal say anlamna geldiini
biliyorsunuz.
Bu kayan noktal saynn sadece tabann elde etmek iin bu sayy tamsayya (integer )
evirmemiz yeterli olacaktr. Yani:
>>> int(a)

Bu arada yeri gelmiken round() adl bir gml fonksiyondan bahsetmeden gemeyelim.
Eer bir saynn deerini yuvarlamanz gerekirse round() fonksiyonundan yararlanabilirsiniz.
Bu fonksiyon yle kullanlr:

13.1. Aritmetik leler 151


Python 3 iin Trke Klavuz, Srm 3

>>> round(2.55)

Grdnz gibi, round() fonksiyonuna parametre olarak bir say veriyoruz. Bu fonksiyon da
bize o saynn yuvarlanm halini dndryor. Bu fonksiyonu kullanarak yuvarlanacak saynn
noktadan sonraki hassasiyetini de belirleyebilirsiniz. rnein:
>>> round(2.55, 1)

2.5

Burada ikinci parametre olarak 1 saysn verdiimiz iin, noktadan sonraki bir basamak
grntleniyor. Bir de una bakalm:
>>> round(2.68, 1)

2.7

Burada da yuvarlama ilemi yaplrken noktadan sonra bir basamak korunuyor. Eer 1 says
yerine 2 saysn kullanrsanz, yukardaki rnek u kty verir:
>>> round(2.68, 2)

2.68

round() fonksiyonunun alma prensibini anlamak iin kendi kendinize rnekler


yapabilirsiniz.
imdiye kadar rendiimiz ve yukardaki tabloda andmz bir baka aritmetik ile de
kuvvet ileci (** ) idi. Mesela bu ileci kullanarak bir saynn karesini hesaplayabileceimizi
biliyorsunuz:
>>> 25 ** 2

625

Bir saynn 2. kuvveti o saynn karesidir. Bir saynn 0.5. kuvveti ise o saynn karekkdr:
>>> 625 ** 0.5

25.0

Bu arada, eer karekkn kayan noktal say cinsinden olmas hounuza gitmediyse, bu sayy
int() fonksiyonu ile tam sayya evirebileceinizi biliyorsunuz:
>>> int(625 ** 0.5)

25

Kuvvet hesaplamalar iin ** ilecinin yansra pow() adl bir fonksiyondan da


yararlanabileceimizi renmitik:
>>> pow(25, 2)

625

Bildiiniz gibi pow() fonksiyonu aslnda toplam parametre alabiliyor:

152 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

>>> pow(25, 2, 5)

Bu ilemin ununla ayn anlama geliyor:


>>> (25 ** 2) % 5

Yani pow(25, 2, 5) gibi bir komut verdiimizde, 25 saysnn 2. kuvvetini alp, elde ettiimiz
saynn 5 e blnmesinden kalan sayy hesaplam oluyoruz.
Bylece aritmetik ileleri tamamlam olduk. Artk karlatrma ilelerini inceleyebiliriz.

13.2 Karlatrma leleri

Adndan da anlalaca gibi, karlatrma ileleri, ilenenler (operands ) arasnda bir


karlatrma ilikisi kuran ilelerdir. Bu ileleri yle sralayabiliriz:
== eittir
!= eit deildir
> byktr
< kktr
>= byk eittir
<= kk eittir
Bu ilelerin hibiri size yabanc deil, zira bunlarn hepsini aslnda daha nceki derslerde
verdiimiz rneklerde kullanmtk. Burada da bunlarla ilgili basit bir rnek vererek yolumuza
devam edelim:
parola = "xyz05"

soru = input("parolanz: ")

if soru == parola:
print("doru parola!")

elif soru != parola:


print("yanl parola!")

Burada soru deikeniyle kullancdan alnan verinin, programn banda tanmladmz


parola deikeninin deerine eit olup olmadn sorguluyoruz. Buna gre, eer kullancdan
gelen veri parolayla eleiyorsa (if soru == parola), kullancy parolann doru olduu
konusunda bilgilendiriyoruz (print("doru parola!")). Ama eer kullancdan gelen veri
parolayla elemiyorsa (elif soru != parola), o zaman da kullancya parolann yanl
olduunu bildiriyoruz (print("yanl parola!")).
Yukardaki rnekte == (eittir) ve != (eit deildir) ilelerinin kullanmn rneklendirdik. teki
karlatrma ilelerinin de nasl kullanldn biliyorsunuz. Basit bir rnek verelim:
say = input("say: ")

if int(say) <= 100:


print("say 100 veya 100'den kk")

13.2. Karlatrma leleri 153


Python 3 iin Trke Klavuz, Srm 3

elif int(say) >= 100:


print("say 100 veya 100'den byk")

Bylece karlatrma ilelerini de incelemi olduk. O halde gelelim bool ilelerine...

13.3 Bool leleri

Bu blmde bool ilelerinden sz edeceiz, ancak bool ilelerine gemeden nce biraz bool
kavramndan bahsetmemiz yerinde olacaktr.
Nedir bu bool denen ey?
Bilgisayar bilimi iki adet deer zerine kuruludur: 1 ve 0. Yani srasyla True ve False.
Bilgisayar biliminde herhangi bir eyin deeri ya True, ya da False tur. te bu True ve False
olarak ifade edilen deerlere bool deerleri ad verilir (George Boole adl ngiliz matematiki
ve lozofun adndan). Trke olarak sylemek gerekirse, True deerinin karl Doru, False
deerinin karl ise Yanl tr.
rnein:
>>> a = 1

Burada a adl bir deiken tanmladk. Bu deikenin deeri 1. imdi bu deikenin deerini
sorgulayalm:
>>> a == 1 #a deeri 1'e eit mi?

True

Grdnz gibi, a == 1 sorgusu True (Doru) kts veriyor. nk a deikeninin deeri


gerekten de 1. Bir de unu deneyelim:
>>> a == 2

False

Burada da a deikeninin deerinin 2 saysna edeer olup olmadn sorguladk. a


deikeninin deeri 2 olmad iin de Python bize False (Yanl) kts verdi.
Grdnz gibi, bool ileleri herhangi bir ifadenin doruluunu veya yanlln
sorgulamak iin kullanlabiliyor. Buna gre, eer bir sorgulamann sonucu doru ise True,
eer yanl ise False kts alyoruz.
Bool ileleri sadece yukarda verdiimiz rneklerdeki gibi, salt bir doruluk-yanllk
sorgulamaya yarayan aralar deildir. Bilgisayar biliminde her eyin bir bool deeri vardr.
Bununla ilgili genel kuralmz u: 0 deeri ve bo veri tipleri False tur. Bunlar dnda kalan
her ey ise True dur.
Bu durumu bool() adl zel bir fonksiyondan yararlanarak teyit edebiliriz:
>>> bool(3)

True

>>> bool("elma")

154 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

True

>>> bool(" ")

True

>>> bool(" ")

True

>>> bool("fdsdfsdg")

True

>>> bool("0")

True

>>> bool(0)

False

>>> bool("")

False

Grdnz gibi, gerekten de 0 saysnn ve bo karakter dizilerinin bool deeri False tur.
Geri kalan her ey ise True dur.

Not: 0 n bir say, 0 n ise bir karakter dizisi olduunu unutmayn. Say olan 0 n bool deeri
False tur, ama karakter dizisi olan 0 n deeri True dur.

Yukardaki rneklere gre, iinde herhangi bir deer barndran karakter dizileri (0 hari) True
kts veriyor. Burada sylediimiz ey btn veri tipleri iin geerlidir. Eer herhangi bir veri
tipi herhangi bir deer iermiyorsa o veri tipi False kts verir.
Peki bu bilgi bizim ne iimize yarar? Yani mesela bo veri tiplerinin False, iinde bir veri
barndran veri tiplerinin ise True olmas bizim iin neden bu kadar nemli? Bunu birazdan
aklayacaz. Ama nce isterseniz, bool deerleri ile ilgili ok nemli bir konuya deinelim.
Belki kendiniz de farketmisinizdir; bool deerleri Pythonda koul belirten if, elif ve else
deyimlerinin de temelini oluturur. u rnei ele alalm mesela:
isim = input("sminiz: ")

if isim == "Ferhat":
print("Ne gzel bir isim bu!")
else:
print(isim, "ismini pek sevmem!")

Burada if isim == "Ferhat" dediimizde, aslnda Pythona u emri vermi oluyoruz:


Eer isim == "Ferhat" ifadesi True ise...
Bunu teyit etmek iin yle bir kod yazabilirsiniz:

13.3. Bool leleri 155


Python 3 iin Trke Klavuz, Srm 3

isim = input("sminiz: ")

print(isim == "Ferhat")

Eer burada kullanc Ferhat ismini girecek olursa programmz True kts verir. Ama eer
kullanc baka bir isim girerse bu kez False ktsn alrz. te koul bildiren deyimler,
karar verme grevini, kendilerine verilen ifadelerin bool deerlerine bakarak yerine getirir.
Dolaysyla yukardaki rnei u ekilde Trkeye evirebiliriz:
Eer isim == "Ferhat" ifadesinin bool deeri True ise, Ne gzel bir isim bu! kts
ver! Ama eer isim == "Ferhat" ifadesinin bool deeri True dnda herhangi bir
ey ise (yani False ise), ... ismini pek sevmem! kts ver!
Koul bildiren deyimlerle bool deerleri arasndaki ilikiyi daha iyi anlamak iin bir rnek daha
verelim:
Hatrlarsanz ii bo veri tiplerinin bool deerinin her zaman False olacan sylemitik. Yani:
>>> a = ""

>>> bool(a)

False

Herhangi bir deere sahip veri tiplerinin bool deeri ise her zaman True olur (0 hari):
>>> a = "gdfg"

>>> bool(a)

True

i bo veri tiplerinin bool deerinin her zaman False olaca bilgisini kullanarak yle bir
uygulama yazabiliriz:
kullanc = input("Kullanc adnz: ")

if bool(kullanc) == True:
print("Teekkrler!")
else:
print("Kullanc ad alan bo braklamaz!")

Burada yle bir emir verdik:


Eer kullanc deikeninin bool deeri True ise Teekkrler! kts ver! Deilse
Kullanc ad alan bo braklamaz! uyarsn gster!
Eer kullanc, kullanc adna herhangi bir ey yazdktan sonra Enter tuuna basarsa kullanc
deikeni, kullancnn girdii deeri gsterecek ve bylece bool(kullanc) komutu True
kts verecektir. Bu sayede de kodlarmzn iindeki if blou almaya balayacaktr.
Ama eer kullanc, kullanc adn yazmadan Enter tuuna basarsa, kullanc deikeni bo
kalaca iin (yani kullanc = "" gibi bir durum ortaya kaca iin) bool(kullanc)
komutu False kts verecek ve bylece else blou alacaktr.
Yalnz bu noktada yle bir uyar yapalm. Yukardaki komutlar szdizimi asndan tamamen
doru olsa da, etrafta yukardakine benzer bir kullanm pek grmezsiniz. Ayn i iin
genellikle yle bir eyler yazlr:

156 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

kullanc = input("Kullanc adnz: ")

if kullanc:
print("Teekkrler!")

Grdnz gibi, if bool(kullanc) == True: kodunu if kullanc: eklinde


ksaltabiliyoruz. Bu ikisi tamamen ayn anlama gelir. Yani ikisi de kullanc deikeninin bool
deeri True ise... demektir.
Bool kavramna ainalk kazandmza gre imdi bool ilelerini incelemeye balayabiliriz.
Bool ileleri, bool deerlerinden birini elde etmemizi salayan ilelerdir. Bu ileler
unlardr:
and
or
not
Eer mantk dersleri aldysanz bu ileler size hi yabanc gelmeyecektir. Eer lisede mantk
dersleri almadysanz veya aldnz derslerden hibir ey hatrlamyorsanz, yine de ziyan
yok. Biz burada bu ileleri btn ayrntlaryla inceleyeceiz.
nce and ile balayalm...
Trke sylemek gerekirse and ve anlamna gelir. Peki bu and ne iimize yarar? ok basit
bir rnek verelim:
Hatrlarsanz geen blmde koullu durumlara rnek verirken yle bir durumdan
bahsetmitik:
Diyelim ki Googlen Gmail hizmeti araclyla bir e.posta hesab aldnz. Bu
hesaba gireceiniz zaman Gmail size bir kullanc ad ve parola sorar. Siz de
kendinize ait kullanc adn ve parolay sayfadaki kutucuklara yazarsnz. Eer
yazdnz kullanc ad ve parola doruysa hesabnza eriebilirsiniz. Ama eer
kullanc adnz ve parolanz doru deilse hesabnza eriemezsiniz. Yani e.posta
hesabnza erimeniz, kullanc ad ve parolay doru girme kouluna baldr.
Burada ok nemli bir nokta var. Kullancnn Gmail sistemine girebilmesi iin hem kullanc
adn hem de parolay doru yazmas gerekiyor. Yani kullanc ad veya paroladan herhangi
biri yanl ise sisteme giri mmkn olmayacaktr.
Yukardaki durumu taklit eden bir program, u ana kadar olan bilgilerimizi kullanarak yle
yazabiliyoruz:
kullanc_ad = input("Kullanc adnz: ")
parola = input("Parolanz: ")

if kullanc_ad == "aliveli":
if parola == "12345678":
print("Programa hogeldiniz")
else:
print("Yanl kullanc ad veya parola!")

else:
print("Yanl kullanc ad veya parola!")

13.3. Bool leleri 157


Python 3 iin Trke Klavuz, Srm 3

Burada yeni bir bilgiyle daha karlayoruz. Grdnz gibi, burada if deyimlerini i
ie kullandk. Pythonda istediiniz kadar i ie gemi if deyimi kullanabilirsiniz. Ancak
yazdnz bir programda eer ten fazla i ie if deyimi kullandysanz, benimsediiniz
yntemi yeniden gzden geirmenizi tavsiye ederim. nk i ie gemi if deyimleri bir
sre sonra anlalmas g bir kod yaps ortaya karabilir. Neyse... Biz konumuza dnelim.
Yukardaki yazdmz programda kullancnn sisteme giri yapabilmesi iin hem kullanc
adn hem de parolay doru girmesi gerekiyor. Kullanc ad ve paroladan herhangi biri
yanlsa sisteme girie izin verilmiyor. Ancak yukardaki yntem dolambaldr. Halbuki ayn
ilevi yerine getirmenin, Pythonda ok daha kolay bir yolu var. Bakalm:
kullanc_ad = input("Kullanc adnz: ")
parola = input("Parolanz: ")

if kullanc_ad == "aliveli" and parola == "12345678":


print("Programa hogeldiniz")

else:
print("Yanl kullanc ad veya parola!")

Burada and ilecini nasl kullandmz gryorsunuz. Bu ileci kullanarak iki farkl ifadeyi
birbirine baladk. Bylece kullancnn sisteme giriini hem kullanc adnn hem de parolann
doru olmas kouluna dayandrdk.
Peki and ilecinin alma mant nedir? Dediim gibi, and Trkede ve anlamna geliyor.
Bu ileci daha iyi anlayabilmek iin u cmleler arasndaki fark dnn:
1. Toplantya Ali ve Veli katlacak.
2. Toplantya Ali veya Veli katlacak.
lk cmlede ve balac kullanld iin, bu cmlenin gereinin yerine getirilebilmesi, hem
Alinin hem de Velinin toplantya katlmasna baldr. Sadece Ali veya sadece Velinin
toplantya katlmas durumunda bu cmlenin gerei yerine getirilememi olacaktr.
kinci cmlede ise toplantya Ali ve Veliden herhangi birisinin katlmas yeterlidir. Toplantya
sadece Alinin katlmas, sadece Velinin katlmas veya her ikisinin birden katlmas, bu
cmlenin gereinin yerine getirilebilmesi asndan yeterlidir.
te Pythondaki and ileci de ayn bu ekilde iler. u rneklere bir bakalm:
>>> a = 23
>>> b = 10
>>> a == 23

True

>>> b == 10

True

>>> a == 23 and b == 10

True

Burada deeri 23 olan bir adet a deikeni ve deeri 10 olan bir adet b deikeni tanmladk.
Daha sonra bu iki deikenin deerini tek tek sorguladk ve bunlarn gerekten de srasyla 23
ve 10 saysna eit olduunu grdk. Son olarak da bunlar and ileci ile birbirine balayarak

158 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

sorguladk. a deikeninin deeri 23, b deikeninin deeri de 10 olduu iin, yani and ile
balanan her iki nerme de True kts verdii iin a == 23 and b == 10 ifadesi True deeri
verdi.
Bir de una bakalm:
>>> a = 23
>>> b = 10
>>> a == 23

True

>>> b == 54

False

>>> a == 23 and b == 54

False

Burada ise a deikenin deeri 23 tr. Dolaysyla a == 23 ifadesi True kts verir. Ancak b
deikeninin deeri 54 deildir. O yzden de b == 54 komutu False kts verir. Grdnz
gibi, and ileci ile balanan nermelerden herhangi biri False olduunda ktmz da False
oluyor. Unutmayn: and ilecinin True kts verebilmesi iin bu ile tarafndan balanan
her iki nermenin de True olmas gerekir. Eer nermelerden biri bile True deilse kt da
True olmayacaktr.
Tahmin edebileceiniz gibi, and ileci en yaygn if deyimleriyle birlikte kullanlr. Mesela
yukarda kullancdan kullanc ad ve parola alrken de bu and ilecinden yararlanmtk.
Gelelim or ilecine...
Tpk and gibi bir bool ileci olan or un Trkede karl veyadr. Yukarda Toplantya Ali
veya Veli katlacak. cmlesini tartrken aslnda bu or kelimesinin anlamn aklamtk.
Hatrlarsanz and ilecinin True kts verebilmesi iin bu ilele balanan btn nermelerin
True deerine sahip olmas gerekiyordu. or ilecinin True kts verebilmesi iin ise
or ileciyle balanan nermelerden herhangi birinin True kts vermesi yeterli olacaktr.
Sylediimiz bu eyleri birka rnek zerinde somutlatralm:
>>> a = 23
>>> b = 10
>>> a == 23

True

>>> b == 10

True

>>> a == 11

False

>>> a == 11 or b == 10

True

Grdnz gibi, a == 11 ifadesinin bool deeri False olduu halde, b == 10 ifadesinin bool

13.3. Bool leleri 159


Python 3 iin Trke Klavuz, Srm 3

deeri True olduu iin a == 11 or b == 10 ifadesi True deerini veriyor.


and ve or ilelerini rendiimize gre, bir snavdan alnan notlarn harf karlklarn
gsteren bir uygulama yazabiliriz:
x = int(input("Notunuz: "))

if x > 100 or x < 0:


print("Byle bir not yok")

elif x >= 90 and x <= 100:


print("A aldnz.")

elif x >= 80 and x <= 89:


print("B aldnz.")

elif x >= 70 and x <= 79:


print("C aldnz.")

elif x >= 60 and x <= 69:


print("D aldnz.")

elif x >= 0 and x <= 59:


print("F aldnz.")

Bu programda eer kullanc 100 den byk ya da 0 dan kk bir say girerse Byle bir
not yok uyars alacaktr. 0-100 aras notlarda ise, her bir not aralna karlk gelen harf
grntlecektir. Eer isterseniz yukardaki kodlar u ekilde de ksaltabilirsiniz:
x = int(input("Notunuz: "))

if x > 100 or x < 0:


print("Byle bir not yok")

elif x >= 90 <= 100:


print("A aldnz.")

elif x >= 80 <= 89:


print("B aldnz.")

elif x >= 70 <= 79:


print("C aldnz.")

elif x >= 60 <= 69:


print("D aldnz.")

elif x >= 0 <= 59:


print("F aldnz.")

Grdnz gibi, and x ksmlarn kardmzda da bir nceki kodlarla ayn anlam
yakalayabiliyoruz.
Hatta yukardaki kodlar yle de yazabilirsiniz:
x = int(input("Notunuz: "))

if x > 100 or x < 0:


print("Byle bir not yok")

160 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

#90 says x'ten kk veya x'e eit,


#x says 100'den kk veya 100'e eit ise,
#Yani x, 90 ile 100 arasnda bir say ise
elif 90 <= x <= 100:
print("A aldnz.")

#80 says x'ten kk veya x'e eit,


#x says 89'dan kk veya 89'a eit ise,
#Yani x, 80 ile 89 arasnda bir say ise
elif 80 <= x <= 89:
print("B aldnz.")

elif 70 <= x <= 79:


print("C aldnz.")

elif 60 <= x <= 69:


print("D aldnz.")

elif 0 <= x <= 59:


print("F aldnz.")

Bu kodlar bir ncekiyle ayn ii yapar. Yorumlardan da greceiniz gibi, bu iki kod arasnda
sadece mantk fark var.
Son bool ilecimiz not. Bu kelimenin ngilizcedeki anlam deildir. Bu ileci yle
kullanyoruz:
>>> a = 23
>>> not a

False

>>> a = ""
>>> not a

True

Bu ile, zellikle kullanc tarafndan bir deikene veri girilip girilmediini denetlemek iin
kullanlabilir. rnein:
parola = input("parola: ")

if not parola:
print("Parola bo braklamaz!")

Eer kullanc herhangi bir parola belirlemeden dorudan Enter tuuna basacak olursa
parola deikeninin deeri bo bir karakter dizisi olacaktr. Yani parola = "". Bo veri
tiplerinin bool deerinin False olacan biliyoruz. Dolaysyla, yukardaki gibi bir rnekte,
kullanc parolay bo getiinde not parola kodu True verecek ve bylece ekrana Parola bo
braklamaz! karakter dizisi yazdrlacaktr. Eer yukardaki rnein mantn kavramakta
zorluk ekiyorsanz u rnekleri incelemenizi neririm:
>>> parola = ""
>>> bool(parola)

False

13.3. Bool leleri 161


Python 3 iin Trke Klavuz, Srm 3

>>> bool(not parola)

True

>>> parola = "1243"


>>> bool(parola)

True

>>> bool(not parola)

False

Aslnda yukardaki rneklerde una benzer sorular sormu gibi oluyoruz:


>>> parola = ""
>>> bool(parola) #parola bo braklmam, deil mi?

>>> False #Hayr, parola bo braklm.

>>> bool(not parola) #parola bo braklm, deil mi?

>>> True #Evet, parola bo braklm

Kendi kendinize pratik yaparak bu ilecin grevini daha iyi anlayabilirsiniz.


Bylece ksmen etrelli bir konu olan bool ilelerini de geride brakm olduk. Srada deer
atama ileleri var.

13.4 Deer Atama leleri

Bu noktaya kadar yaptmz almalarda sadece tek bir deer atama ileci grdk. Bu ile =
ilecidir. Adndan da anlalaca gibi, bu ilecin grevi bir deikene deer atamaktr. Mesela:
>>> a = 23

Burada = ileci a deikenine 23 deerini atama ilevi gryor.


Pythondaki tek deer atama ileci elbette = deildir. Bunun dnda baka deer atama
ileleri de bulunur. Tek tek inceleyelim:
+= ileci
Bu ilecin ne ie yaradn anlamak iin yle bir rnek dnn:
>>> a = 23

a deerine mesela 5 ekleyip bu deeri 28 e eitlemek iin ne yapmamz lazm? Tabii ki unu:
>>> a = a + 5
>>> print(a)

28

Burada yaptmz ey ok basit: a deikeninin tad deere 5 ilave ediyoruz ve daha sonra
bu deeri tekrar a deikenine atyoruz. Ayn ilemi ok daha kolay bir ekilde de yapabiliriz:

162 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

>>> a += 5
>>> print(a)

28

Bu kod, yukardakiyle tamamen ayn anlama gelir. Ama bir nceki koda gre ok daha
verimlidir. nk a += 5 kodunda Python a deikeninin deerini sadece bir kez kontrol
ettii iin, ilemi a = a + 5 koduna gre daha hzl yapacaktr.
-= ileci
Bir nceki += ileci toplama ilemi yapp, ortaya kan deeri tekrar ayn deikene atyordu.
-= ileci de buna benzer bir ilem gerekletirir:
>>> a = 23
>>> a -= 5
>>> print(a)

18

Yukardaki kullanm ununla tamamen ayndr:


>>> a = 23
>>> a = a - 5
>>> print(a)

18

Ancak tpk += ilecinde olduu gibi, -= ileci de alternatine gre daha hzl alan bir aratr.
/= ileci
Bu ilecin alma mant da yukardaki ilelerle ayndr:
>>> a = 30
>>> a /= 3
>>> print(a)

10

Yukardaki ilem de ununla tamamen ayndr:


>>> a = 30
>>> a = a / 3
>>> print(a)

10

*= ileci
Bu da tekiler gibi, arpma ilemi yapp, bu ilemin sonucunu ayn deikene atar:
>>> a = 20
>>> a *= 2
>>> print(a)

40

Bu ilecin edeeri de udur:

13.4. Deer Atama leleri 163


Python 3 iin Trke Klavuz, Srm 3

>>> a = 20
>>> a = a * 2
>>> print(a)

40

%= ileci
Bu ilecimiz ise blme ileminden kalan sayy ayn deikene atar:
>>> a = 40
>>> a %= 3
>>> print(a)

Bu ile de una edeerdir:


>>> a = 40
>>> a = a % 3
>>> print(a)

**= ileci
Bu ilecin ne yaptn tahmin etmek zor deil. Bu ilecimiz, bir saynn kuvvetini
hesapladktan sonra kan deeri ayn deikene atyor:
>>> a = 12
>>> a **= 2
>>> print(a)

144

Edeeri:
>>> a = 12
>>> a = a ** 2
>>> print(a)

144

//= ileci
Deer atama ilelerinin sonuncusu olan //= ilecinin grevi ise taban blme ileminin
sonucunu ayn deikene atamaktr:
>>> a = 5
>>> a //= 2
>>> print(a)

Edeeri:
>>> a = 5
>>> a = a // 2
>>> print(a)

164 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

Bu ileler arasndan, zellikle += ve -= ileleri iinize bir hayli yarayacak.


Bu arada eer bu ileleri kullanrken mesela += mi yoksa =+ m yazacanz kartryorsanz,
yle dnebilirsiniz:
>>> a = 5
>>> a += 5
>>> print(a)

10

Burada, deeri 5 olan bir a deikenine 5 daha ekleyip, kan sonucu tekrar a deikenine
atadk. Bylece deeri 10 olan bir a deikeni elde ettik. += ilecinin doru kullanm
yukardaki gibidir. Bir de yukardaki rnei yle yazmay deneyelim:
>>> a = 5
>>> a =+ 5
>>> print(a)

Burada + ileci ile = ilecinin yerini deitirdik.


a =+ 5 satrna dikkatlice bakn. Aslnda burada yaptmz eyin a = +5 ilemi olduunu,
yani a deikenine +5 gibi bir deer verdiimizi greceksiniz. Durum u rnekte daha net
grnecektir:
>>> a = 5
>>> a =- 5
>>> print(a)
>>> -5

Grdnz gibi, a =- 5 yazdmzda, aslnda yaptmz ey a deikenine -5 deerini


vermekten ibarettir. Yani a = -5.

13.5 Aitlik leleri

Aitlik ileleri, bir karakter dizisi ya da saynn, herhangi bir veri tipi iinde bulunup
bulunmadn sorgulamamz salayan ilelerdir.
Pythonda bir tane aitlik ileci bulunur. Bu ile de in ilecidir. Bu ileci yle kullanyoruz:
>>> a = "abcd"
>>> "a" in a

True

>>> "f" in a

False

Grdnz gibi, in adl bu ile, bir enin, veri tipi iinde bulunup bulunmadn
sorguluyor. Eer bahsedilen e, veri tipi iinde geiyorsa True kts, eer gemiyorsa False
kts alyoruz.

13.5. Aitlik leleri 165


Python 3 iin Trke Klavuz, Srm 3

Henz bu in ilecini verimli bir ekilde kullanmamz salayacak aralardan yoksunuz. Ancak
birka sayfa sonra reneceimiz yeni aralarla birlikte bu ileci ok daha dzgn ve verimli
bir ekilde kullanabilecek duruma geleceiz.

13.6 Kimlik leleri

Pythonda her eyin (ya da baka bir deyile her nesnenin) bir kimlik numaras (identity )
vardr. Kabaca sylemek gerekirse, bu kimlik numaras denen ey esasnda o nesnenin
bellekteki adresini gsterir.
Peki bir nesnenin kimlik numarasna nasl ularz?
Pythonda bu ii yapmamz salayacak id() adl bir fonksiyon bulunur (ngilizcedeki identity
(kimlik) kelimesinin ksaltmas). imdi bir rnek zerinde bu id() fonksiyonunu nasl
kullanacamza bakalm:
>>> a = 100
>>> id(a)

137990748

ktda grdmz 137990748 says a deikeninin tuttuu 100 saysnn kimlik numarasn
gsteriyor.
Bir de u rneklere bakalm:
>>> a = 50
>>> id(a)

505494576

>>> kardiz = "Elveda Zalim Dnya!"


>>> id(kardiz)

14461728

Grdnz gibi, Pythondaki her nesnenin kimlii eiz, tek ve benzersizdir.


Yukarda verdiimiz ilk rnekte bir a deikeni tanmlayp bunun deerini 100 olarak
belirlemi ve id(a) komutuyla da bu nesnenin kimlik numarasna ulamtk. Yani:
>>> a = 100
>>> id(a)
137990748

Bir de u rnee bakalm:


>>> b = 100
>>> id(b)

137990748

Grdnz gibi, Python a ve b deikenlerinin deeri iin ayn kimlik numarasn gsterdi.
Bu demek oluyor ki, Python iki adet 100 says iin bellekte iki farkl nesne oluturmuyor. lk
kullanmda nbelleine ald sayy, ikinci kez ihtiya olduunda bellekten alp kullanyor. Bu
tr bir nbellekleme mekanizmasnn gerekesi performans artrmaktr.

166 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

Ama bir de u rneklere bakalm:


>>> a = 1000
>>> id(a)

15163440

>>> b = 1000
>>> id(b)

14447040

>>> id(1000)

15163632

Bu defa Python a deikeninin tuttuu 1000 says, b deikeninin tuttuu 1000 says ve
tek bana yazdmz 1000 says iin farkl kimlik numaralar gsterdi. Bu demek oluyor ki,
Python a deikeninin tuttuu 1000 says iin, b deikeninin tuttuu 1000 says iin ve
dorudan girdiimiz 1000 says iin bellekte farkl nesne oluturuyor. Yani bu adet
1000 says Python asndan birbirinden farkl...
Yukardaki durumu grebileceimiz baka bir yntem de Pythondaki is adl kimlik ilecini
kullanmaktr. Deneyelim:
>>> a is 1000

False

>>> b is 1000

False

Grdnz gibi, Python False (Yanl) ktsn suratmza bir tokat gibi arpt... Peki bu ne
anlama geliyor?
Bu u anlama geliyor: Demek ki grnte ayn olan iki nesne aslnda birbirinin ayn
olmayabiliyor. Bunun neden bu kadar nemli olduunu ilerleyen derslerde ok daha iyi
anlayacaz.
Yukardaki durumun bir baka yansmas daha vardr. zellikle Pythona yeni balayp da
bu dilde yer alan is ilecini renenler, bu ilecin == ileciyle ayn ileve sahip olduu
yanlgsna kaplabiliyor ve is ilecini kullanarak iki nesne arasnda karlatrma ilemi
yapmaya kalkabiliyor.
Ancak Pythonda is ilecini kullanarak iki nesne arasnda karlatrma yapmak gvenli
deildir. Yani is ve == ileleri birbirleriyle ayn ilevi grmez. Bu iki ile nesnelerin farkl
ynlerini sorgular: is ileci nesnelerin kimliklerine bakp o nesnelerin ayn nesneler olup
olmadn kontrol ederken, == ileci nesnelerin ieriine bakarak o nesnelerin ayn deere
sahip olup olmadklarn sorgular. Bu iki tanm arasndaki ince farka dikkat edin.
Yani:
>>> a is 1000

False

Ama:

13.6. Kimlik leleri 167


Python 3 iin Trke Klavuz, Srm 3

>>> a == 1000

True

Burada is ileci a deikeninin tuttuu veri ile 1000 saysnn ayn kimlik numarasna sahip
olup olmadn sorgularken, == ileci a deikeninin tuttuu verinin 1000 olup olmadn
denetliyor. Yani is ilecinin yapt ey kabaca u oluyor:
>>> id(a) == id(1000)

False

imdiye kadar denediimiz rnekler hep sayyd. imdi isterseniz bir de karakter dizilerinin
durumuna bakalm:
>>> a = "python"
>>> a is "python"

True

Burada True ktsn aldk. Bir de == ileci ile bir karlatrma yapalm:
>>> a == "python"

True

Bu da normal olarak True kts veriyor. Ama u rnee bakarsak:


>>> a = "python gl ve kolay bir programlama dilidir"
>>> a is "python gl ve kolay bir programlama dilidir"

False

Ama:
>>> a == "python gl ve kolay bir programlama dilidir"

True

is ve == ilelerinin nasl da farkl sonular verdiini gryorsunuz. nk bunlardan


biri nesnelerin kimliini sorgularken, br nesnelerin ieriini sorguluyor. Ayrca burada
dikkatimizi ekmesi gereken baka bir nokta da python karakter dizisinin nbellee alnp
gerektiinde tekrar tekrar kullanlyorken, python gl ve kolay bir programlama dilidir
karakter dizisinin ise nbellee alnmyor olmasdr. Ayn karakter dizisinin tekrar kullanlmas
gerektiinde Python bunun iin bellekte yeni bir nesne daha oluturuyor.
Peki neden Python, rnein, 100 saysn ve python karakter dizisini nbelleklerken 1000
saysn ve python gl ve kolay bir programlama dilidir karakter dizisini nbellee almyor.
Sebebi u: Python kendi i mekanizmasnn ileyii gereince ufak nesneleri nbellee
alrken byk nesneler iin her defasnda yeni bir depolama ilemi yapyor. Peki ufak ve
byk kavramlarnn lt nedir? sterseniz Python asndan ufak kavramnn snrnn ne
olabileceini yle bir kod yardmyla sorgulayabiliriz:
>>> for k in range(-1000, 1000):
... for v in range(-1000, 1000):
... if k is v:
... print(k)

168 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

Not: Burada henz renmediimiz eyler var. Bunlar birka blm sonra ayrntl bir
ekilde inceleyeceiz.

Bu kod -1000 ve 1000 aralndaki iki say grubunu karlatrp, kimlikleri ayn olan saylar
ekrana dkyor. Yani bir bakma Pythonun hangi sayya kadar nbellekleme yaptn
gsteriyor. Buna gre -5 ile 257 arasnda kalan saylar Python tarafndan ufak olarak
deerlendiriliyor ve nbellee alnyor. Bu araln dnda kalan saylar iin ise bellekte her
defasnda ayr bir nesne oluturuluyor.
Burada aldmz sonuca gre yle bir denetleme ilemi yapalm:
>>> a = 256
>>> a is 256

True

>>> a = 257
>>> a is 257

False

>>> a = -5
>>> a is -5

True

>>> a = -6
>>> a is -6

False

Bylece Pythondaki kimlik ilelerini de incelemi olduk. Belki programclk maceranz


boyunca id() fonksiyonunu hi kullanmayacaksnz, ancak bu fonksiyonun arkasndaki
mant anlamak, Pythonn kimi yerlerde alttan alta neler evirdiini ok daha kolay
kavramanz salayacaktr.

Not: http://forum.ceviz.net/showthread.php?t=87565 adresindeki tartmaya baknz.

Bylece Pythondaki btn ileleri ayrntl bir ekilde incelemi olduk. Dilerseniz imdi bu
konuyla ilgili birka uygulama rnei yapalm.

13.7 Uygulama rnekleri

13.7.1 Basit Bir Hesap Makinesi

u ana kadar Pythonda pek ok ey rendik. Bu rendiimiz eylerle artk ksmen yararl
baz programlar yazabiliriz. Elbette henz yazacamz programlar pek yetenekli olamayacak
olsa da, en azndan bize rendiklerimizle pratik yapma imkan salayacak. Bu blmde,
if, elif, else yaplarn ve rendiimiz temel aritmetik ileleri kullanarak ok basit bir
hesap makinesi yapmay deneyeceiz. Bu arada, bu derste yeni eyler renerek ufkumuzu
ve bilgimizi geniletmeyi de ihmal etmeyeceiz.
sterseniz nce kullancya baz seenekler sunarak ie balayalm:

13.7. Uygulama rnekleri 169


Python 3 iin Trke Klavuz, Srm 3

giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) kare kk hesapla
"""

print(giri)

Burada kullancya baz seenekler sunduk. Bu seenekleri ekrana yazdrmak iin trnak
iaretlerinden yararlandmza dikkat edin. Birden fazla satra yaylm bu tr ifadeleri en
kolay trnak iaretleri yardmyla yazdrabileceimizi biliyorsunuz artk.
Biz burada btn seenekleri tek bir deiken iine yerletirdik. Esasnda her bir seenek
iin ayr bir deiken tanmlamak da mmkndr. Yani aslnda yukardaki kodlar yle de
yazabiliriz:
seenek1 = "(1) topla"
seenek2 = "(2) kar"
seenek3 = "(3) arp"
seenek4 = "(4) bl"
seenek5 = "(5) karesini hesapla"
seenek6 = "(6) karekk hesapla"

print(seenek1, seenek2, seenek3, seenek4, seenek5)

Yalnz burada dikkat ederseniz, seenekler hep yan yana diziliyor. Eer programnzda
yukardaki ekli kullanmak isterseniz, bu seeneklerin yan yana deil de, alt alta grnmesini
salamak iin, nceki derslerimizde rendiimiz sep parametresini kullanabilirsiniz:
seenek1 = "(1) topla"
seenek2 = "(2) kar"
seenek3 = "(3) arp"
seenek4 = "(4) bl"
seenek5 = "(5) karesini hesapla"
seenek6 = "(6) karekk hesapla"

print(seenek1, seenek2, seenek3, seenek4, seenek5, seenek6, sep="\n")

Burada sep parametresinin deeri olarak \n ka dizisini belirlediimize dikkat edin. \n ka


dizisinin ne ie yaradn hatrlyorsunuz. Bu dizi, satr bana gememizi salyordu. Burada,
ayra olarak satr ba ka dizisini belirlediimiz iin her bir seenek yan yana deil, alt alta
grnecektir. Elbette sep parametresi iin istediiniz deeri belirleyebilirsiniz. Mesela her
bir seenei satr ba iaretiyle ayrmak yerine, ift tire gibi bir iaretle ayrmay da tercih
edebilirsiniz:
print(seenek1, seenek2, seenek3, seenek4, seenek5, sep="--")

Programnzda nasl bir giri paragraf belirleyeceiniz konusunda zgrsnz. Gelin


isterseniz biz birinci ekille yolumuza devam edelim:
giri = """
(1) topla
(2) kar
(3) arp

170 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""

print(giri)

Burada giri adl bir deiken oluturduk. Bu deikenin iinde barndrd deeri
kullanclarn grebilmesi iin print() fonksiyonu yardmyla bu deikeni ekrana
yazdryoruz. Devam edelim:
soru = input("Yapmak istediiniz ilemin numarasn girin: ")

Bu kod yardmyla kullancya bir soru soruyoruz. Kullancdan yapmasn istediimiz ey,
yukarda belirlediimiz giri seenekleri iinden bir say semesi. Kullanc 1, 2, 3, 4, 5
veya 6 seeneklerinden herhangi birini seebilir. Kullancy, setii numarann karsnda
yazan ileme ynlendireceiz. Yani mesela eer kullanc klavyedeki 1 tuuna basarsa hesap
makinemiz toplama ilemi yapacaktr. 2 tuu ise kullancy karma ilemine ynlendirir...
input() fonksiyonunu ilediimiz blmde, bu fonksiyonun deer olarak her zaman bir
karakter dizisi (string ) verdiini sylemitik. Yukardaki kodun kts da doal olarak bir
karakter dizisi olacaktr. Bizim u aamada kullancdan karakter dizisi almamzn bir sakncas
yok. nk kullancnn girecei 1, 2, 3, 4, 5 veya 6 deerleriyle herhangi bir aritmetik ilem
yapmayacaz. Kullancnn girecei bu deerler, yalnzca bize onun hangi ilemi yapmak
istediini belirtecek. Dolaysyla input() fonksiyonunu yukardaki ekilde kullanyoruz.
sterseniz imdiye kadar grdmz ksma topluca bakalm:
giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""

print(giri)

soru = input("Yapmak istediiniz ilemin numarasn girin: ")

Bu kodlar altrdmzda, ekranda giri paragrafmz grnecek ve kullancya, yapmak


istedii ilemin ne olduu sorulacaktr. Henz kodlarmz eksik olduu iin, kullanc hangi
sayy girerse girsin, programmz hi bir i yapmadan kapanacaktr. O halde yolumuza devam
edelim:
if soru == "1":

Bylece ilk if deyimimizi tanmlam olduk. Buradaki yazm ekline ok dikkat edin. Bu
kodlarla Pythona u emri vermi oluyoruz:
Eer soru adl deikenin deeri 1 ise, yani eer kullanc klavyede 1 tuuna
basarsa...
if deyimlerinin en sonuna : iaretini koymay unutmuyoruz. Pythona yeni balayanlarn
en ok yapt hatalardan birisi, sondaki bu : iaretini koymay unutmalardr. Bu iaret
bize ok ufak bir ayrntym gibi grnse de Python iin manevi deeri ok byktr!

13.7. Uygulama rnekleri 171


Python 3 iin Trke Klavuz, Srm 3

Pythonun bize fkeli mesajlar gstermesini istemiyorsak bu iareti koymay unutmayacaz.


Bu arada, burada == iaretini kullandmza da dikkat edin. Bunun ne anlama geldiini
nceki derslerimizde renmitik. Bu iaret, iki eyin ayn deere sahip olup olmadn
sorgulamamz salyor. Biz burada soru adl deikenin deerinin 1 olup olmadn
sorguladk. soru deikeninin deeri kullanc tarafndan belirlenecei iin henz bu
deikenin deerinin ne olduunu bilmiyoruz. Bizim programmzda kullanc klavyeden 1,
2, 3, 4, 5 veya 6 deerlerinden herhangi birini seebilir. Biz yukardaki kod yardmyla, eer
kullanc klavyede 1 tuuna basarsa ne yaplacan belirleyeceiz. O halde devam edelim:
if soru == "1":
say1 = int(input("Toplama ilemi iin ilk sayy girin: "))
say2 = int(input("Toplama ilemi iin ikinci sayy girin: "))
print(say1, "+", say2, "=", say1 + say2)

Bylece ilk if bloumuzu tanmlam olduk.


if deyimimizi yazdktan sonra ne yaptmz ok nemli. Buradaki girintileri, programmz
gzel grnsn diye yapmyoruz. Bu girintilerin Python iin bir anlam var. Eer bu
girintileri vermezsek programmz almayacaktr. Eer Python kodlarna duyarl bir metin
dzenleyici kullanyorsanz, : iaretini koyup Enter tuuna bastktan sonra otomatik olarak
girinti verilecektir. Eer kullandnz metin dzenleyici size byle bir kolaylk sunmuyorsa
Enter tuuna bastktan sonra klavyedeki boluk (SPACE ) tuunu kullanarak drt vuruluk
bir girinti oluturabilirsiniz. Bu girintiler, ilk satrda belirlediimiz if deyimiyle gsterilecek
ilemlere iaret ediyor. Dolaysyla burada yazlan kodlar Pythoncadan Trkeye evirecek
olursak yle bir ey elde ederiz:
eer sorunun deeri '1' ise:
Toplama ilemi iin ilk say girilsin. Bu deere 'say1' diyelim.
Sonra ikinci say girilsin. Bu deere de 'say2' diyelim.
En son, 'say1', '+' ileci, 'say2', '=' ileci ve 'say1 + say2'
ekrana yazdrlsn...

Gelin isterseniz buraya kadar olan blm yine topluca grelim:


giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""

print(giri)

soru = input("Yapmak istediiniz ilemin numarasn girin: ")

if soru == "1":
say1 = int(input("Toplama ilemi iin ilk sayy girin: "))
say2 = int(input("Toplama ilemi iin ikinci sayy girin: "))
print(say1, "+", say2, "=", say1 + say2)

Bu kodlar altrp, klavyede 1 tuuna bastmzda, bizden bir say girmemiz istenecektir.
lk saymz girdikten sonra bize tekrar bir say girmemiz sylenecek. Bu emre de uyup Enter
tuuna basnca, girdiimiz bu iki saynn toplandn greceiz. Fena saylmaz, deil mi?
imdi programmzn geri kalan ksmn yazyoruz. in temelini kavradmza gre birden

172 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

fazla kod blounu ayn anda yazabiliriz:


elif soru == "2":
say3 = int(input("karma ilemi iin ilk sayy girin: "))
say4 = int(input("karma ilemi iin ikinci sayy girin: "))
print(say3, "-", say4, "=", say3 - say4)

elif soru == "3":


say5 = int(input("arpma ilemi iin ilk sayy girin: "))
say6 = int(input("arpma ilemi iin ikinci sayy girin: "))
print(say5, "x", say6, "=", say5 * say6)

elif soru == "4":


say7 = int(input("Blme ilemi iin ilk sayy girin: "))
say8 = int(input("Blme ilemi iin ikinci sayy girin: "))
print(say7, "/", say8, "=", say7 / say8)

elif soru == "5":


say9 = int(input("Karesini hesaplamak istediiniz sayy girin: "))
print(say9, "saysnn karesi =", say9 ** 2)

elif soru == "6":


say10 = int(input("Karekkn hesaplamak istediiniz sayy girin: "))
print(say10, "saysnn karekk = ", say10 ** 0.5)

Bunlarla birlikte kodlarmzn byk blmn tamamlam oluyoruz. Bu blmdeki tek fark,
ilk if blounun aksine, burada elif bloklarn kullanm olmamz. Eer burada btn bloklar
if kullanarak yazarsanz, biraz sonra kullanacamz else blou her koulda alaca iin
beklentinizin dnda sonular elde edersiniz.
Yukardaki kodlarda az da olsa farkllk gsteren tek yer son iki elif bloumuz. Esasnda
buradaki fark da pek byk bir fark saylmaz. Neticede tek bir saynn karesini ve karekkn
hesaplayacamz iin, kullancdan yalnzca tek bir giri istiyoruz.
imdi de son bloumuzu yazalm. Az evvel tlattmz gibi, bu son blok bir else blou olacak:
else:
print("Yanl giri.")
print("Aadaki seeneklerden birini giriniz:", giri)

ok basit bir else blou ile iimizi bitirdik. Bu bloun ne ie yaradn biliyorsunuz:
Eer kullancnn girdii deer yukardaki bloklardan hi birine uymuyorsa bu else
blounu ilet!
gibi bir emir vermi oluyoruz bu else blou yardmyla. Mesela kullancmz 1, 2, 3, 4, 5 veya
6 seeneklerini girmek yerine 7 yazarsa, bu blok iletilecek.
Gelin isterseniz son kez kodlarmz topluca bir grelim:
giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""

13.7. Uygulama rnekleri 173


Python 3 iin Trke Klavuz, Srm 3

print(giri)

soru = input("Yapmak istediiniz ilemin numarasn girin: ")

if soru == "1":
say1 = int(input("Toplama ilemi iin ilk sayy girin: "))
say2 = int(input("Toplama ilemi iin ikinci sayy girin: "))
print(say1, "+", say2, "=", say1 + say2)

elif soru == "2":


say3 = int(input("karma ilemi iin ilk sayy girin: "))
say4 = int(input("karma ilemi iin ikinci sayy girin: "))
print(say3, "-", say4, "=", say3 - say4)

elif soru == "3":


say5 = int(input("arpma ilemi iin ilk sayy girin: "))
say6 = int(input("arpma ilemi iin ikinci sayy girin: "))
print(say5, "x", say6, "=", say5 * say6)

elif soru == "4":


say7 = int(input("Blme ilemi iin ilk sayy girin: "))
say8 = int(input("Blme ilemi iin ikinci sayy girin: "))
print(say7, "/", say8, "=", say7 / say8)

elif soru == "5":


say9 = int(input("Karesini hesaplamak istediiniz sayy girin: "))
print(say9, "saysnn karesi =", say9 ** 2)

elif soru == "6":


say10 = int(input("Karekkn hesaplamak istediiniz sayy girin: "))
print(say10, "saysnn karekk = ", say10 ** 0.5)

else:
print("Yanl giri.")
print("Aadaki seeneklerden birini giriniz:", giri)

Genel olarak baktmzda, btn programn aslnda basit bir if, elif, else yapsndan
ibaret olduunu gryoruz. Ayrca bu kodlardaki simetriye de dikkatinizi ekmek isterim.
Grdnz gibi her paragraf bir if, elif veya else bloundan oluuyor ve her blok kendi
iinde girintili bir yap sergiliyor. Temel olarak yle bir eyle kar karyayz:
Eer byle bir durum varsa:
yle bir ilem yap

Yok eer yle bir durum varsa:


byle bir ilem yap

Eer bambaka bir durum varsa:


yle bir ey yap

Bylelikle irin bir hesap makinesine sahip olmu olduk! Hesap makinemiz pek yetenekli
deil, ama olsun... Henz bildiklerimiz bunu yapmamza msaade ediyor. Yine de
balangtan bu noktaya kadar epey yol katettiimizi gryorsunuz.
imdi bu program altrn ve neler yapabildiine gz atn. Bu arada kodlar da iyice
inceleyin. Program yeterince anladktan sonra, program zerinde kendinize gre baz
deiiklikler yapn, yeni zellikler ekleyin. Eksikliklerini, zayf ynlerini bulmaya aln.

174 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

Bylece bu dersten azami fayday salam olacaksnz.

13.7.2 Srme Gre lem Yapan Program

Bildiiniz gibi, u anda piyasada iki farkl Python serisi bulunuyor: Python2 ve Python3. Daha
nce de sylediimiz gibi, Pythonn 2.x serisi ile alan bir program Pythonn 3.x serisi ile
muhtemelen almayacaktr. Ayn ekilde bunun tersi de geerlidir. Yani 3.x ile alan bir
program 2.x ile byk ihtimalle almayacaktr.
Bu durum, yazdnz programlarn farkl Python srmleri ile altrlma ihtimaline kar
baz nlemler almanz gerektirebilir. rnein yazdnz bir programda kullanclarnzdan
beklentiniz, programnz Pythonn 3.x srmlerinden biri ile altrmalar olabilir. Eer
programnz Pythonn 2.x srmlerinden biri ile altrlrsa kullancya bir uyar mesaj
gstermek isteyebilirsiniz.
Hatta yazdnz bir program, ayn serinin farkl srmlerinde dahi almay engelleyecek
zellikler ieriyor olabilir. rnein print() fonksiyonunun ush adl parametresi dile 3.3
srm ile birlikte eklendi. Dolaysyla bu parametreyi kullanan bir program, kullancnn
3.3 veya daha yksek bir Python srm kullanmasn gerektirir. Byle bir durumda,
programnz altran Python srmnn en dk 3.3 olmasn temin etmeniz gerekir.
Peki bunu nasl yapacaksnz?
Burada aklnzda ilk olarak, kodlarnza #!/usr/bin/env python3.3 veya #! python3.3 gibi
bir satr eklemek gelmi olabilir. Ama unutmayn, bu zm ancak kstl bir ilevsellik
sunabilir. Programmza byle bir satr eklediimizde, programmzn Pythonn 3.3 srm
ile altrlmas gerektiini belirtiyoruz. Ama 3.3 d bir srmle altrldnda ne olacan
belirtmiyoruz. Byle bir durumda, eer programmz 3.3 d bir srmle altrlrsa
kecektir. Bizim burada daha kapsaml ve esnek bir zm bulmamz gerekiyor.
Hatrlarsanz nceki derslerden birinde sys adl bir modlden sz etmitik. Bildiiniz gibi,
bu modl iinde pek ok yararl deiken ve fonksiyon bulunuyor. nceki derslerimizde, bu
modl iinde bulunan exit() fonksiyonu ile stdout ve version deikenlerini grdmz
hatrlyor olmalsnz. sys modl iinde bulunan exit() fonksiyonunun programdan
kmamz saladn, stdout deikeninin standart kt konumu bilgisini tuttuunu ve
version deikeninin de kullandmz Python srm hakknda bilgi verdiini biliyoruz. te
yukarda bahsettiimiz programda da bu sys modlnden yararlanacaz.
Bu i iin, version deikenine ok benzeyen version_info adl bir deikeni kullanacaz.
Bu deikenin nasl kullanldna etkileimli kabukta beraberce bakalm...
sys modl iindeki aralar kullanabilmek iin ncelikle bu modl ie aktarmamz
gerektiini biliyorsunuz:
>>> import sys

imdi de bu modl iindeki version_info adl deikene erielim:


>>> sys.version_info

Bu komut bize yle bir kt verir:


sys.version_info(major=|major3|, minor=|minor3|, micro=|micro3|, releaselevel='final', serial
Grdnz gibi, bu deiken de bize tpk version adl deiken gibi, kullandmz Python
srm hakknda bilgi veriyor.

13.7. Uygulama rnekleri 175


Python 3 iin Trke Klavuz, Srm 3

Ben yukardaki komutu Python3te verdiinizi varsaydm. Eer yukardaki komutu Python3
yerine Python2de verseydik yle bir kt alacaktk:
sys.version_info(major=|major2|, minor=|minor2|, micro=|micro2|, releaselevel='final', serial
version_info ve version deikenlerinin verdikleri ktnn birbirlerinden farkl yapda
olduuna dikkat edin. version deikeni, version_info deikeninden farkl olarak yle bir
kt verir:
`3.5.1 (default, 20.04.2016, 12:24:55)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
version_info deikeninin verdii kt bizim u anda yazmak istediimiz programa daha
uygun. Bunun neden byle olduunu biraz sonra siz de anlayacaksnz.
Grdnz gibi, version_info deikeninin ktsnda major ve minor gibi baz deerler var.
ktdan da rahatlkla anlayabileceiniz gibi, major, kullanlan Python serisinin ana srm
numarasn; minor ise alt srm numarasn verir. ktda bir de micro adl bir deer var. Bu
da kullanlan Python serisinin en alt srm numarasn verir.
Bu deere u ekilde eriiyoruz:
>>> sys.version_info.major

teki deerlere de ayn ekilde ulayoruz:


>>> sys.version_info.minor
>>> sys.version_info.micro

te bu ktlardaki major (ve yerine gre bununla birlikte minor ve micro ) deerini
kullanarak, programmzn hangi Python srm ile altrlmas gerektiini kontrol
edebiliriz. imdi programmz yazalm:
import sys

_2x_metni = """
Python'n 2.x srmlerinden birini kullanyorsunuz.
Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal."""

_3x_metni = "Programa hogeldiniz."

if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)

Gelin isterseniz ncelikle bu kodlar biraz inceleyelim.


lk olarak modlmz ie aktaryoruz. Bu modl iindeki aralar kullanabilmemiz iin bunu
yapmamz art:
import sys

Ardndan Pythonn 2.x srmlerinden herhangi birini kullananlar iin bir uyar metni
oluturuyoruz:
_2x_metni = """
Python'n 2.x srmlerinden birini kullanyorsunuz.

176 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

Program altrabilmek iin sisteminizde Python'n


3.x srmlerinden biri kurulu olmal."""

Bildiiniz gibi Pythonda deiken adlar bir sayyla balamaz. O yzden deiken isminin
bana bir tane alt izgi iareti koyduumuza dikkat edin.
Bu da Python3 kullanclar iin:
_3x_metni = "Programa hogeldiniz."

Artk srm kontrol ksmna geebiliriz. Eer major parametresinin deeri 3ten kkse
_2x_metnini yazdryoruz. Bunun dndaki btn durumlar iin ise _3x_metnini basyoruz:
if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)

Grdnz gibi, kullanlan Python srmn kontrol etmek ve eer program istenmeyen
bir Python srmyle altrlyorsa ne yaplacan belirlemek son derece kolay.
Yukardaki ok basit bir kod paras olsa da bize Python programlama diline ve bu dilin farkl
srmlerine dair son derece nemli baz bilgiler veriyor.
Eer bu program Pythonn 3.x srmlerinden biri ile altrdysanz u kty alacaksnz:
Programa hogeldiniz.

Ama eer bu program Pythonn 2.x srmlerinden biri ile altrdysanz, beklentinizin
aksine, yle bir hata mesaj alacaksnz:
File "test.py", line 5
SyntaxError: Non-ASCII character '\xc4' in file test.py on line 6, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details

Biz _2x_metni adl deikenin ekrana baslmasn beklerken Python bize bir hata mesaj
gsterdi. Aslnda siz bu hata mesajna hi yabanc deilsiniz. Bunu daha nce de
grmtnz. Hatrlarsanz nceki derslerimizde karakter kodlamalarndan bahsederken,
Pythonn 2.x srmlerinde ntanml karakter kodlamasnn ASCII olduundan sz etmitik.
Bu yzden programlarmzda Trke karakterleri kullanrken baz ilave ilemler yapmamz
gerekiyordu.
Burada ilk olarak karakter kodlamasn UTF-8 olarak deitirmemiz gerekiyor. Bunun nasl
yaplacan biliyorsunuz. Programmzn ilk satrna u kodu ekliyoruz:
# -*- coding: utf-8 -*-

Bu satr Python3 iin gerekli deil. nk Python3te ntanml karakter kodlamas zaten
UTF-8. Ama Python2de ntanml karakter kodlamas ASCII. O yzden Python2 kullanclarn
da dnerek UTF-8 kodlamasn aka belirtiyoruz. Bylece programmzn Pythonn 2.x
srmlerinde Trke karakterler yznden kmesini nlyoruz.
Ama burada bir problem daha var. Programmz Trke karakterler yznden kmyor
kmemesine ama, bu defa da Trke karakterleri dzgn gstermiyor:

Python'n 2.x srmlerinden birini kullanyorsunuz.


Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal.

13.7. Uygulama rnekleri 177


Python 3 iin Trke Klavuz, Srm 3

Programmz Pythonn 2.x srmlerinden biri ile altranlarn uyar mesajn dzgn bir
ekilde grntleyebilmesini istiyorsanz, Trke karakterler ieren karakter dizilerinin en
bana bir u har eklemelisiniz. Yani _2x_metni adl deikeni yle yazmalsnz:
_2x_metni = u"""
Python'n 2.x srmlerinden birini kullanyorsunuz.
Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal."""

Bu karakter dizisinin en bana bir u har ekleyerek bu karakter dizisini unicode olarak
tanmlam olduk. Eer unicode kavramn bilmiyorsanz endie etmeyin. lerde bu
kavramdan bolca sz edeceiz. Biz imdilik, iinde Trke karakterler geen karakter
dizilerinin Python2 kullanclar tarafndan dzgn grntlenebilmesi iin balarna bir u
har eklenmesi gerektiini bilelim yeter.
Eer siz bir Windows kullancsysanz ve btn bu ilemlerden sonra bile Trke karakterleri
dzgn grntleyemiyorsanz, bu durum muhtemelen MS-DOS komut satrnn kulland
yaz tipinin Trke karakterleri gsterememesinden kaynaklanyordur. Bu problemi zmek
iin MS-DOS komut satrnn balk ubuuna sa tklayp zellikler seeneini seerek yaz
tipini Lucida Console olarak deitirin. Bu ilemin ardndan da komut satrnda u komutu
verin:
chcp 1254

Bylece Trke karakterleri dzgn grntleyebilirsiniz.

Not: MS-DOStaki Trke karakter problemi hakknda daha ayrntl bilgi iin
http://goo.gl/eRY1P adresindeki makalemizi inceleyebilirsiniz.

imdiye kadar anlattklarmzdan rendiiniz gibi, sys modl iinde srm denetlemeye
yarayan iki farkl deiken var. Bunlardan biri version, br ise version_info.
Python3te bu deikenlerin u ktlar verdiiniz biliyoruz:
version:
`3.5.1 (default, 20.04.2016, 12:24:55)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
version_info:
sys.version_info(major=|major3|, minor=|minor3|, micro=|micro3|, releaselevel='final', serial
Grdnz gibi, ktlarn hem yaplar birbirinden farkl, hem de verdikleri bilgiler arasnda
baz farklar da var. Mesela version deikeni, kullandmz Python srmnn hangi tarih ve
saatte, hangi iletim sistemi zerinde derlendii bilgisini de veriyor. Ancak kullanlan Python
srmnn ne olduunu tespit etmek konusunda version_info biraz daha pratik grnyor.
Bu deikenin bize major, minor ve micro gibi parametreler araclyla sunduu say deerli
verileri ilelerle birlikte kullanarak bu saylar zerinde aritmetik ilemler yapp, kullanlan
Python srmn kontrol edebiliyoruz.
version deikeni bize bir karakter dizisi verdii iin, bu deikenin deerini kullanarak
herhangi bir aritmetik ilem yapamyoruz. Mesela version_info deikeniyle yukarda
yaptmz byktr-kktr sorgulamasn version deikeniyle tabii ki yapamayz.
Yukardaki rnekte seriler aras srm kontroln nasl yapacamz grdk. Bunun iin
kullandmz kod uydu:

178 Blm 13. leler


Python 3 iin Trke Klavuz, Srm 3

if sys.version_info.major < 3:
...

Burada kullanlan Python serisinin 3.x ten dk olduu durumlar sorguladk. Peki ayn
serinin farkl srmlerini denetlemek istersek ne yapacaz? Mesela Pythonn 3.2 srmn
sorgulamak istersek nasl bir kod kullanacaz?
Bunun iin yle bir ey yazabiliriz:
if sys.version_info.major == 3 and sys.version_info.minor == 2:
...

Grdnz gibi burada version_info deikeninin hem major hem de minor


parametrelerini kullandk. Ayrca hem ana srm, hem de alt srm iin belli bir koul talep
ettiimizden tr and adl Bool ilecinden de yararlandk. nk koulun gereklemesi,
ana srmn 3 ve alt srmn 2 olmasna bal.
Yukardaki ilem iin version deikenini de kullanabilirdik. Dikkatlice bakn:
if "3.2" in sys.version:
...

Bildiiniz gibi, version deikeni Pythonn 3.x srmlerinde una benzer bir kt veriyor:
`3.5.1 (default, 20.04.2016, 12:24:55)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
te biz burada in ilecini kullanarak, version deikeninin verdii karakter dizisi iinde 3.2
diye bir ifade aradk.
Bu konuyu daha iyi anlamak iin kendi kendinize baz denemeler yapmanz tavsiye ederim.
Ne kadar ok rnek kod yazarsanz, o kadar ok tecrbe kazanrsnz.

13.7. Uygulama rnekleri 179


BLM 14

Dngler (Loops)

imdiye kadar rendiklerimiz sayesinde Pythonla ufak tefek programlar yazabilecek dzeye
geldik. Mesela rendiimiz bilgiler yardmyla bir nceki blmde ok basit bir hesap
makinesi yazabilmitik. Yalnz o hesap makinesinde farkettiyseniz ok nemli bir eksiklik
vard. Hesap makinemizle hesap yaptktan sonra programmz kapanyor, yeni hesap
yapabilmek iin program yeniden balatmamz gerekiyordu.
Hesap makinesi programndaki sorun, rnein, aadaki program iin de geerlidir:
tuttuum_say = 23

bilbakalm = int(input("Aklmdan bir say tuttum. Bil bakalm ka tuttum? "))

if bilbakalm == tuttuum_say:
print("Tebrikler! Bildiniz...")

else:
print("Ne yazk ki tuttuum say bu deildi...")

Burada tuttuum_say adl bir deiken belirledik. Bu deikenin deeri 23. Kullancdan
tuttuumuz sayy tahmin etmesini istiyoruz. Eer kullancnn verdii cevap tuttuum_say
deikeninin deeriyle aynysa (yani 23 ise), ekrana Tebrikler!... yazs dklecektir. Aksi
halde Ne yazk ki... cmlesi ekrana dklecektir.
Bu program iyi, ho, ama ok nemli bir eksii var. Bu program yalnzca bir kez
kullanabiliyoruz. Yani kullanc yalnzca bir kez tahminde bulunabiliyor. Eer kullanc bir
kez daha tahminde bulunmak isterse program yeniden altrmas gerekecek. Bunun hi
iyi bir yntem olmad ortada. Halbuki yazdmz bir program, ilk almann ardndan
kapanmasa, biz bu program tekrar tekrar altrabilsek, programmz srekli olarak baa
dnse ve program ancak biz istediimizde kapansa ne iyi olurdu deil mi? Yani mesela
yukardaki rnekte kullanc bir say tahmin ettikten sonra, eer bu say bizim tuttuumuz
sayyla ayn deilse, kullancya tekrar tahmin etme frsat verebilsek ok ho olurdu...
Yukarda aklamaya altmz sre, yani bir srecin tekrar tekrar devam etmesi Pythonda
dng (loop ) olarak adlandrlr.
te bu blmde, programlarmzn srekli olarak almasn nasl salayabileceimizi, yani
programlarmz bir dng iine nasl sokabileceimizi reneceiz.
Pythonda programlarmz tekrar tekrar altrabilmek iin dng ad verilen baz ifadelerden
yararlanacaz.
Pythonda iki tane dng bulunur: while ve for

180
Python 3 iin Trke Klavuz, Srm 3

Dilerseniz ie while dngs ile balayalm.

14.1 while Dngs

ngilizce bir kelime olan while, Trkede ... iken, ... olduu srece gibi anlamlara gelir.
Pythonda while bir dngdr. Bir nceki blmde sylediimiz gibi, dngler sayesinde
programlarmzn srekli olarak almasn salayabiliriz.
Bu blmde Pythonda while dngsnn ne olduunu ve ne ie yaradn anlamaya
alacaz. ncelikle while dngsnn temellerini kavrayarak ie balayalm.
Basit bir while dngs kabaca una benzer:
a = 1

while a == 1:

Burada a adl bir deiken oluturduk. Bu deikenin deeri 1. Bir sonraki satrda ise while
a == 1: gibi bir ifade yazdk. En bata da sylediimiz gibi while kelimesi, ... iken, olduu
srece gibi anlamlar tayor. Python programlama dilindeki anlam da buna olduka yakndr.
Burada while a == 1 ifadesi programmza yle bir anlam katyor:
a deikeninin deeri 1 olduu srece...
Grdnz gibi cmlemiz henz eksik. Yani belli ki bunun bir de devam olacak. Ayrca
while ifadesinin sonundaki : iaretinden anladmz gibi, bundan sonra gelecek satr girintili
yazlacak. Devam edelim:
a = 1

while a == 1:
print("bilgisayar ldrd!")

Burada Pythona u emri vermi olduk:


a deikeninin deeri 1 olduu srece, ekrana bilgisayar ldrd! yazsn dk!
Bu program altrdmzda Python verdiimiz emre sadakatle uyacak ve a deikeninin
deeri 1 olduu mddete de bilgisayarmzn ekranna bilgisayar ldrd! yazsn
dkecektir. Programmzn iinde a deikeninin deeri 1 olduu ve bu deikenin deerini
deitirecek herhangi bir ey bulunmad iin Python hi sklmadan ekrana bilgisayar
ldrd! yazsn basmaya devam edecektir. Eer siz durdurmazsanz bu durum sonsuza
kadar devam edebilir. Bu lgnla bir son vermek iin klavyenizde Ctrl+C veya Ctrl+Z
tularna basarak program durmaya zorlayabilirsiniz.
Burada programmz sonsuz bir dngye sokmu olduk (innite loop ). Esasnda sonsuz
dngler genellikle bir program hatasna iaret eder. Yani ou durumda programcnn
arzu ettii ey bu deildir. O yzden doru yaklam, dngye soktuumuz programlarmz
durduracak bir lt belirlemektir. Yani yle bir kod yazmalyz ki, a deikeninin 1 olan
deeri bir noktadan sonra artk 1 olmasn ve bylece o noktaya ulaldnda programmz
dursun. Kullancnn Ctrl+C tularna basarak program durdurmak zorunda kalmas pek ho
olmuyor. Gelin isterseniz bu soyut ifadeleri biraz somutlatralm.
ncelikle u satr yazarak ie balyoruz:

14.1. while Dngs 181


Python 3 iin Trke Klavuz, Srm 3

a = 1

Burada normal bir ekilde a deikenine 1 deerini atadk. imdi devam ediyoruz:
a = 1

while a < 10:

while ile verdiimiz ilk rnekte while a == 1 gibi bir ifade kullanmtk. Bu ifade;
a nn deeri 1 olduu mddete...
gibi bir anlama geliyordu.
while a < 10 ifadesi ise;
a nn deeri 10 dan kk olduu mddete...
anlamna gelir. te burada programmzn sonsuz dngye girmesini engelleyecek bir lt
koymu olduk. Buna gre, a deikeninin imdiki deeri 1 dir. Biz, a nn deeri 10 dan kk
olduu mddete bir ilem yapacaz. Devam edelim:
a = 1

while a < 10:


print("bilgisayar yine ldrd!")

Ne oldu? stediimizi elde edemedik, deil mi? Programmz yine sonsuz dngye girdi. Bu
sonsuz dngy krmak iin Ctrl+C (veya Ctrl+Z )ye basmamz gerekecek yine...
Sizce buradaki hata nereden kaynakland? Yani neyi eksik yaptk da programmz sonsuz
dngye girmekten kurtulamad? Aslnda bunun cevab ok basit. Biz yukardaki kodlar
yazarak Pythona u emri vermi olduk:
a nn deeri 10 dan kk olduu mddete ekrana bilgisayar yine ldrd!
yazsn bas!
a deikeninin deeri 1. Yani 10 dan kk. Dolaysyla Pythonn ekrana o kty basmasn
engelleyecek herhangi bir ey yok...
imdi bu problemi nasl aacamz grelim:
a = 1

while a < 10:


a += 1
print("bilgisayar yine ldrd!")

Burada a += 1 satrn ekledik kodlarmzn arasna. += ilecini anlatrken sylediimiz gibi,


bu satr, a deikeninin deerine her defasnda 1 ekliyor ve elde edilen sonucu tekrar a
deikenine atyor. En sonunda a nn deeri 10 a ulanca da, Python ekrana bilgisayar
yine ldrd! cmlesini yazmay brakyor. nk while dngs iinde belirttiimiz lte
gre, programmzn devam edebilmesi iin a deikeninin deerinin 10 dan kk olmas
gerekiyor. a nn deeri 10 a ulat anda bu lt bozulacaktr. Gelin isterseniz bu kodlar
Pythonn nasl algladna bir bakalm:
1. Python ncelikle a = 1 satrn gryor ve a nn deerini 1 yapyor.
2. Daha sonra a nn deeri 10 dan kk olduu mddete... (while a < 10) satrn
gryor.

182 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

3. Ardndan a nn deerini, 1 artryor (a += 1) ve a nn deeri 2 oluyor.


4. a nn deeri (yani 2 ) 10 dan kk olduu iin Python ekrana ilgili kty veriyor.
5. lk dngy bitiren Python baa dnyor ve a nn deerinin 2 olduunu gryor.
6. a nn deerini yine 1 artryor ve a y 3 yapyor.
7. a nn deeri hl 10 dan kk olduu iin ekrana yine ilgili kty veriyor.
8. kinci dngy de bitiren Python yine baa dnyor ve a nn deerinin 3 olduunu
gryor.
9. Yukardaki admlar tekrar eden Python, a nn deeri 9 olana kadar ilerlemeye devam
ediyor.
10. a nn deeri 9 a ulatnda Python a nn deerini bir kez daha artrnca bu deer 10 a
ulayor.
11. Python a nn deerinin artk 10 dan kk olmadn gryor ve programdan kyor.
Yukardaki kodlar yle yazarsak belki durum daha anlalr olabilir:
a = 1

while a < 10:


a += 1
print(a)

Burada Pythonun arkada ne iler evirdiini daha net grebiliyoruz. Kodlarmz iine
eklediimiz while dngs sayesinde Python her defasnda a deikeninin deerini kontrol
ediyor ve bu deer 10 dan kk olduu mddete a deikeninin deerini 1 artrp, yeni
deeri ekrana basyor. Bu deikenin deeri 10 a ulatnda ise, bu deerin artk 10 dan
kk olmadn anlayp btn ilemleri durduruyor.
Gelin isterseniz bu while dngsn daha nce yazdmz hesap makinemize uygulayalm:
giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""

print(giri)

anahtar = 1

while anahtar == 1:
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")

if soru == "q":
print("klyor...")
anahtar = 0

elif soru == "1":


say1 = int(input("Toplama ilemi iin ilk sayy girin: "))
say2 = int(input("Toplama ilemi iin ikinci sayy girin: "))

14.1. while Dngs 183


Python 3 iin Trke Klavuz, Srm 3

print(say1, "+", say2, "=", say1 + say2)

elif soru == "2":


say3 = int(input("karma ilemi iin ilk sayy girin: "))
say4 = int(input("karma ilemi iin ikinci sayy girin: "))
print(say3, "-", say4, "=", say3 - say4)

elif soru == "3":


say5 = int(input("arpma ilemi iin ilk sayy girin: "))
say6 = int(input("arpma ilemi iin ikinci sayy girin: "))
print(say5, "x", say6, "=", say5 * say6)

elif soru == "4":


say7 = int(input("Blme ilemi iin ilk sayy girin: "))
say8 = int(input("Blme ilemi iin ikinci sayy girin: "))
print(say7, "/", say8, "=", say7 / say8)

elif soru == "5":


say9 = int(input("Karesini hesaplamak istediiniz sayy girin: "))
print(say9, "saysnn karesi =", say9 ** 2)

elif soru == "6":


say10 = int(input("Karekkn hesaplamak istediiniz sayy girin: "))
print(say10, "saysnn karekk = ", say10 ** 0.5)

else:
print("Yanl giri.")
print("Aadaki seeneklerden birini giriniz:", giri)

Burada ilave olarak u satrlar gryorsunuz:


anahtar = 1

while anahtar == 1:
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")

if soru == "q":
print("klyor...")
anahtar = 0

Bu kodlarda yaptmz ey aslnda ok basit. ncelikle deeri 1 olan anahtar adl bir deiken
tanmladk. Bir alt satrda ise, programmzn srekli olarak almasn salayacak olan
while dngmz yazyoruz. Programmz, anahtar deikeninin deeri 1 olduu mddete
almaya devam edecek. Daha nce de dediimiz gibi, eer bu anahtar deikeninin deerini
programn bir noktasnda deitirmezsek programmz sonsuza kadar almaya devam
edecektir. nk biz programmz anahtar deikeninin deeri 1 olduu srece almaya
ayarladk. te programmzn bu tr bir sonsuz dngye girmesini nlemek iin bir if
blou oluturuyoruz. Buna gre, eer kullanc klavyede q tuuna basarsa programmz nce
klyor... kts verecek, ardndan da anahtar deikeninin 1 olan deerini 0 yapacaktr.
Bylece artk anahtar n deeri 1 olmayaca iin programmz almaya son verecektir.
Buradaki mantn ne kadar basit olduunu grmenizi isterim. nce bir deiken
tanmlyoruz, ardndan bu deikenin deeri ayn kald mddete programmz almaya
ayarlyoruz. Bu dngy krmak iin de bata tanmladmz o deikene baka bir deer
atyoruz. Burada anahtar deikenine atadmz 1 ve 0 deerleri tamamen tesaddir.
Yani siz bu deerleri istediiniz gibi deitirebilirsiniz. Mesela yukardaki kodlar yle de

184 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

yazabilirsiniz:
anahtar = "hoyda bre!"

#anahtar'n deeri 'hoyda bre!' olduu mddete aadaki blou


#altrmaya devam et.
while anahtar == "hoyda bre!":
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")

if soru == "q":
print("klyor...")
anahtar = "dur yolcu!"
#anahtar'n deeri artk 'hoyda bre!' deil, 'dur yolcu'
#olduu iin dngden k ve bylece program sona erdirmi ol.

Grdnz gibi, ama herhangi bir deikene herhangi bir deer atamak ve o deer ayn
kald mddete programn almaya devam etmesini salamak. Kurduumuz bu dngy
krmak iin de o deikene herhangi baka bir deer atamak...
Yukarda verdiimiz son rnekte nce anahtar adl bir deiken atayp, while dngsnn
ileyiini bu deikenin deerine gre yaplandrdk. Ama aslnda yukardaki kodlar ok daha
basit bir ekilde de yazabiliriz. Dikkatlice bakn:
while True:
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")

if soru == "q":
print("klyor...")
break

Bu yapy hesap makinemize uygulayalm:


giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla
(6) karekk hesapla
"""

print(giri)

while True:
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")

if soru == "q":
print("klyor...")
break

elif soru == "1":


say1 = int(input("Toplama ilemi iin ilk sayy girin: "))
say2 = int(input("Toplama ilemi iin ikinci sayy girin: "))
print(say1, "+", say2, "=", say1 + say2)

elif soru == "2":


say3 = int(input("karma ilemi iin ilk sayy girin: "))
say4 = int(input("karma ilemi iin ikinci sayy girin: "))

14.1. while Dngs 185


Python 3 iin Trke Klavuz, Srm 3

print(say3, "-", say4, "=", say3 - say4)

elif soru == "3":


say5 = int(input("arpma ilemi iin ilk sayy girin: "))
say6 = int(input("arpma ilemi iin ikinci sayy girin: "))
print(say5, "x", say6, "=", say5 * say6)

elif soru == "4":


say7 = int(input("Blme ilemi iin ilk sayy girin: "))
say8 = int(input("Blme ilemi iin ikinci sayy girin: "))
print(say7, "/", say8, "=", say7 / say8)

elif soru == "5":


say9 = int(input("Karesini hesaplamak istediiniz sayy girin: "))
print(say9, "saysnn karesi =", say9 ** 2)

elif soru == "6":


say10 = int(input("Karekkn hesaplamak istediiniz sayy girin: "))
print(say10, "saysnn karekk = ", say10 ** 0.5)

else:
print("Yanl giri.")
print("Aadaki seeneklerden birini giriniz:", giri)

Bu yap sayesinde anahtar gibi bir deiken atama zorunluluundan kurtulmu olduk.
Yukardaki kodlarn nasl altn aklayalm:
while True ifadesi yle bir anlama gelir:
True olduu mddete...
Peki ne True olduu mddete? Burada neyin True olmas gerektiini belirtmediimiz iin,
aslnda bu kod paras u anlama geliyor:
Aksi belirtilmedii srece almaya devam et!
Eer yukardaki aklamay biraz bulank bulduysanz u rnei inceleyebilirsiniz:
while True:
print("Bilgisayar ldrd!")

Bu kodlar altrdnzda ekrana srekli olarak Bilgisayar ldrd! kts verilecektir. Bu


dngden kabilmek iin Ctrl+C tularna basmanz gerekiyor. Yukardaki kodlarn sonsuz
dngye girmesinin sorumlusu while True satrdr. nk burada biz Pythona;
Aksi belirtilmedii srece almaya devam et!
emri veriyoruz. Python da bu emrimizi sadakatle yerine getiriyor. Byle bir durumda
sonsuz dngy engellemek iin programmzn bir yerinde Pythona bu dngden kmasn
salayacak bir emir vermemiz gerekiyor. Biz hesap makinesi programmzda bu dngy u
ekilde krdk:
if soru == "q":
print("klyor...")
break

Dikkat ederseniz burada break adl yeni bir ara gryoruz. Bu aracn tam olarak ne ie
yaradn ilerleyen sayfalarda inceleyeceiz. imdilik yalnzca unu bilelim: break kelimesi
ngilizcede krmak, koparmak, bozmak gibi anlamlara gelir. Bu aracn yukardaki grevi

186 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

dngy krmaktr. Dolaysyla kullanc klavyede q tuuna bastnda, while True ifadesi
ile almaya balayan dng krlacak ve programmz sona erecektir.
Bu yapy daha iyi anlayabilmek iin yle basit bir rnek daha verelim:
#Aksi belirtilmedii srece kullancya
#aadaki soruyu sormaya devam et!
while True:
soru = input("Naslsnz, iyi misiniz?")

#Eer kullanc 'q' tuuna basarsa...


if soru == "q":
break #dngy kr ve programdan k.

Gryorsunuz, aslnda mantk gayet basit:


Bir dng olutur ve bu dngden kmak istediinde, programn bir yerinde bu
dngy sona erdirecek bir koul meydan getir.
Bu mant yukardaki rnee u ekilde uyguladk:
while True: ifadesi yardmyla bir dng olutur ve kullanc bu dngden kmak
istediinde (yani q tuuna bastnda), dngy kr ve program sona erdir.
Gelin isterseniz bu konuyu daha net kavramak iin bir rnek daha verelim:
tekrar = 1

while tekrar <= 3:


tekrar += 1
input("Naslsnz, iyi misiniz?")

Burada programmz kullancya kez Naslsnz, iyi misiniz? sorusunu soracak ve ardndan
kapanacaktr. Bu kodlarda while dngsn nasl kullandmza dikkat edin. Aslnda
programn mant ok basit:
1. ncelikle deeri 1 olan tekrar adl bir deiken tanmlyoruz.
2. Bu deikenin deeri 3 e eit veya 3 ten kk olduu mddete (while tekrar <= 3)
deikenin deerine 1 ekliyoruz (tekrar += 1).
3. Baka bir deyile bool(tekrar <= 3) ifadesi True olduu mddete deikenin
deerine 1 ekliyoruz.
4. tekrar deikenine her 1 ekleyiimizde kullancya Naslsnz, iyi misiniz? sorusunu
soruyoruz (input("Naslsnz, iyi misiniz?")).
5. tekrar deikeninin deeri 3 atnda bool(tekrar <= 3) ifadesi artk False deeri
verdii iin programmz sona eriyor.
Yukardaki uygulamada Pythonn alttan alta neler evirdiini daha iyi grmek iin bu
uygulamay yle yazmay deneyin:
tekrar = 1

while tekrar <= 3:


print("tekrar: ", tekrar)
tekrar += 1
input("Naslsnz, iyi misiniz?")
print("bool deeri: ", bool(tekrar <= 3))

14.1. while Dngs 187


Python 3 iin Trke Klavuz, Srm 3

Daha nce de dediimiz gibi, bir Python programnn nasl altn anlamann en iyi yolu,
program iinde uygun yerlere print() fonksiyonlar yerletirerek arka planda hangi kodlarn
hangi ktlar verdiini izlemektir. te yukarda da bu yntemi kullandk. Yani tekrar
deikenininin deerini ve bool(tekrar <= 3) ifadesinin ktsn ekrana yazdrarak arka
tarafta neler olup bittiini canl canl grme imkanna kavutuk.
Yukardaki program altrdmzda una benzer ktlar gryoruz:
tekrar: 1
Naslsnz, iyi misiniz? evet
bool deeri: True
tekrar: 2
Naslsnz, iyi misiniz? evet
bool deeri: True
tekrar: 3
Naslsnz, iyi misiniz? evet
bool deeri: False

Grdnz gibi, tekrar deikeninin deeri her dngde 1 artyor. tekrar <= 3 ifadesinin
bool deeri, tekrar adl deikenin deeri 3 aana kadar hep True olacaktr. Bu deikenin
deeri 3 at anda tekrar <= 3 ifadesinin bool deeri False a dnyor ve bylece while
dngs sona eriyor.
Peki size yle bir soru sorsam: Acaba while dngsn kullanarak 1 den 100 e kadar olan
aralktaki ift saylar nasl bulursunuz?
ok basit:
a = 0

while a < 100:


a += 1
if a % 2 == 0:
print(a)

Grdnz gibi, while dngsnn iine bir adet if blou yerletirdik.


Yukardaki kodlar u ekilde Trkeye evirebiliriz:
a deikeninin deeri 100 den kk olduu mddete a deikeninin deerini
1 artr. Bu deikenin deerini her artrnda yeni deerin 2 ye tam blnp
blnmediini kontrol et. Eer a modls 2 deeri 0 ise (if a % 2 == 0), yani
a nn deeri bir ift say ise, bu deeri ekrana yazdr.
Grdnz gibi, while dngs son derece kullanl bir aratr. stelik kullanm da son
derece kolaydr. Bu dngyle bol bol pratik yaparak bu dngy rahata kullanabilecek
duruma gelebilirsiniz.
En bata da sylediimiz gibi, Pythonda while dnda bir de for dngs vardr. En az while
kadar nemli bir dng olan for dngsnn nasl kullanldn anlamaya alalm imdi
de.

14.2 for Dngs

Etrafta yazlm Python programlarnn kaynak kodlarn incelediinizde, iinde for dngs
gemeyen bir program kolay kolay bulamazsnz. Belki while dngsnn kullanlmad

188 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

programlar vardr. Ancak for dngs Pythonda o kadar yaygndr ve o kadar geni bir
kullanm alanna sahiptir ki, hemen hemen btn Python programlar bu for dngsnden
en az bir kez yararlanr.
Peki nedir bu for dngs denen ey?
for da tpk while gibi bir dngdr. Yani tpk while dngsnde olduu gibi,
programlarmzn birden fazla sayda almasn salar. Ancak for dngs while dngsne
gre biraz daha yeteneklidir. while dngs ile yapamayacanz veya yaparken ok
zorlanacanz eyleri for dngs yardmyla ok kolay bir ekilde halledebilirsiniz.
Yalnz, sylediimiz bu cmleden, for dngsnn while dngsne bir alternatif olduu
sonucunu karmayn. Evet, while ile yapabildiiniz bir ilemi for ile de yapabilirsiniz ou
zaman, ama bu dnglerin, belli vakalar iin tek seenek olduu durumlar da vardr. Zira bu
iki dngnn alma mant birbirinden farkldr.
imdi gelelim for dngsnn nasl kullanlacana...
Dikkatlice bakn:
tr_harfler = ""

for harf in tr_harfler:


print(harf)

Burada ncelikle tr_harer adl bir deiken tanmladk. Bu deiken Trkeye zg hareri
tutuyor. Daha sonra bir for dngs kurarak, tr_harer adl deikenin her bir esini tek
tek ekrana yazdrdk.
Peki bu for dngsn nasl kurduk?
for dnglerinin sz dizimi yledir:
for deiken_ad in deiken:
yaplacak_ilem

Bu sz dizimini Trke olarak yle ifade edebiliriz:


deiken iindeki herbir eyi deiken_ad olarak adlandr:
ve bu elerle bir ilem yap.

Bu soyut yaplar kendi rneimize uygulayarak durumu daha net anlamaya alalm:
tr_harfler adl deiken iindeki herbir eyi harf olarak adlandr:
ve harf olarak adlandrlan bu eleri ekrana yazdr.

Yukardaki rnekte bir for dngs yardmyla tr_harer adl deiken iindeki herbir eyi
ekrana yazdrdk. Esasnda for dngsnn yeteneklerini dndmzde bu rnek pek
heyecan verici deil. Zira ayn ii aslnda print() fonksiyonu ile de yapabilirdik:
tr_harfler = ""
print(*tr_harfler, sep="\n")

Aslnda bu ilemi while ile de yapmak mmkn (Bu kodlardaki, henz renmediimiz ksm
imdilik grmezden gelin):
tr_harfler = ""
a = 0

14.2. for Dngs 189


Python 3 iin Trke Klavuz, Srm 3

while a < len(tr_harfler):


print(tr_harfler[a], sep="\n")
a += 1

while dngs kullanldnda ii uzattmz gryorsunuz. Dediimiz gibi, for dngs


while dngsne gre biraz daha yeteneklidir ve while ile yapmas daha zor (veya uzun)
olan ilemleri for dngs ile ok daha kolay bir ekilde yapabiliriz. Ayrca for dngs ile
while dngsnn alma mantklar birbirinden farkldr. for dngs, zerinde dng
kurulabilecek veri tiplerinin herbir esinin zerinden tek tek geer ve bu elerin herbiri
zerinde bir ilem yapar. while dngs ise herhangi bir ifadenin bool deerini kontrol eder
ve bu deerin bool deeri False olana kadar, belirlenen ilemi yapmay srdrr.
Bu arada, biraz nce zerinde dng kurulabilecek veri tipleri diye bir kavramdan sz ettik.
rnein karakter dizileri, zerinde dng kurulabilecek bir veri tipidir. Ama saylar yle
deildir. Yani saylar zerinde dng kuramayz. Mesela:
>>> saylar = 123456789
>>> for say in saylar:
... print(say)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

Buradaki hata mesajndan da greceiniz gibi int (tam say) trndeki nesneler zerinde
dng kuramyoruz. Hata mesajnda grnen not iterable (zerinde dng kurulamaz)
ifadesiyle kastedilen de budur.
Gelin isterseniz for dngs ile bir rnek daha vererek durumu iyice anlamaya alalm:
saylar = "123456789"

for say in saylar:


print(int(say) * 2)

Burada saylar adl deikenin herbir esini say olarak adlandrdktan sonra, int()
fonksiyonu yardmyla bu eleri tek tek sayya evirdik ve herbir eyi 2 ile arptk.
for dngsnn mantn az ok anlam olmalsnz. Bu dng bir deiken iindeki herbir
eyi tek tek ele alp, iki nokta st ste iaretinden sonra yazdmz kod blounu bu elere
tek tek uyguluyor.
for kelimesi ngilizcede iin anlamna gelir. Dngnn yaps iinde geen in ifadesini de
tanyorsunuz. Biz bu ifadeyi Aitlik leleri konusunu ilerken de grmtk. Hatrlarsanz in
ileci bir enin bir veri tipi iinde bulunup bulunmadn sorguluyordu. Mesela:
>>> a = "istihza.com"
>>> "h" in a

True

h esi istihza.com adl karakter dizisi iinde getii iin "h" in a kodu True kts
veriyor. Bir de una bakn:
>>> "b" in a

False

190 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

b esi istihza.com karakter dizisi iinde bulunmuyor. Dolaysyla "b" in a sorgulamas


False kts veriyor.
in kelimesi ngilizcede iinde anlamna geliyor. Dolaysyla for falanca in filanca:
yazdmzda aslnda yle bir ey demi oluyoruz:
lanca iinde falanca adn verdiimiz herbir e iin...
Yani u kod:
for s in "istihza":
print(s)

u anlama geliyor:
istihza karakter dizisi iinde s adn verdiimiz herbir e iin: s esini
ekrana basma ilemi gerekletir!
Ya da u kod:
saylar = "123456789"

for i in saylar:
if int(i) > 3:
print(i)

u anlama geliyor:
saylar deikeni iinde i adn verdiimiz herbir e iin:
eer sayya dntrlm i deeri 3 ten bykse: i esini ekrana
basma ilemi gerekletir!
Yukardaki temsili kodlarn Trkesi bozuk olsa da for dngsnn alma mantn
anlamaya yardmc olacan zannediyorum. Ama yine de, eer bu dngnn mantn
henz kavrayamadysanz hi endie etmeyin. Zira bu dngy olduka sk bir biimde
kullanacamz iin, siz istemeseniz de bu dng kafanzda yer etmi olacak.
Bu for dngsn biraz daha iyi anlayabilmek iin son bir rnek yapalm:
tr_harfler = ""

parola = input("Parolanz: ")

for karakter in parola:


if karakter in tr_harfler:
print("parolada Trke karakter kullanlamaz")

Bu program, kullancya bir parola soruyor. Eer kullancnn girdii parola iinde Trke
karakterlerden herhangi biri varsa kullancy Trke karakter kullanmamas konusunda
uyaryor. Buradaki for dngsn nasl kurduumuzu gryorsunuz. Aslnda burada u
Trke cmleyi Pythoncaya evirmi olduk:
parola deikeni iinde karakter adn verdiimiz herbir e iin:
eer karakter deikeni tr_harer adl deiken iinde geiyorsa:
parolada Trke karakter kullanlamaz uyarsn gster!
Burada kullandmz for dngs sayesinde kullancnn girdii parola adl deiken iindeki
btn karakterlere tek tek bakp, eer baklan karakter tr_harer adl deiken iinde

14.2. for Dngs 191


Python 3 iin Trke Klavuz, Srm 3

geiyorsa kullancy uyaryoruz.


Aslnda for dngsyle ilgili syleyeceklerimiz bu kadar deil. Ama henz bu dngyle
kullanlan nemli aralar tanmyoruz. Geri zaten bu dngy bundan sonra sk sk
kullandmz greceksiniz.
Gelin isterseniz yeni bir konuya gemeden nce dnglerle ilgili ufak bir rnek verelim:
rnein kullancya bir parola belirletirken, belirlenecek parolann 8 karakterden uzun, 3
karakterden ksa olmamasn salayalm:
while True:
parola = input("Bir parola belirleyin: ")

if not parola:
print("parola blm bo geilemez!")

elif len(parola) > 8 or len(parola) < 3:


print("parola 8 karakterden uzun 3 karakterden ksa olmamal")

else:
print("Yeni parolanz", parola)
break

Burada ncelikle, programnzn srekli olarak almasn salamak iin bir while dngs
oluturduk. Buna gre, aksi belirtilmedike (while True) programmz almaya devam
edecek.
while dngsn kurduktan sonra kullancya bir parola soruyoruz (parola = input("Bir
parola belirleyin: "))
Eer kullanc herhangi bir parola belirlemeden dorudan Enter tuuna basarsa, yani parola
deikeninin bool deeri False olursa (if not parola), kullancya parola blm bo
geilemez! uyars veriyoruz.
Eer kullanc tarafndan belirlenen parolann uzunluu 8 karakterden fazlaysa ya da 3
karakterden ksaysa, parola 8 karakterden uzun 3 karakterden ksa olmamal uyars
veriyoruz.
Yukardaki koullar harici durumlar iin ise (else), belirlenen yeni parolay kullancya gsterip
dngden kyoruz (break).
Bu arada, hatrlarsanz eval() fonksiyonunu anlatrken yle bir rnek vermitik:
print("""
Basit bir hesap makinesi uygulamas.

leler:

+ toplama
- karma
* arpma
/ blme

Yapmak istediiniz ilemi yazp ENTER


tuuna basn. (rnein 23 ve 46 saylarn
arpmak iin 23 * 46 yazdktan sonra
ENTER tuuna basn.)
""")

192 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

veri = input("leminiz: ")


hesap = eval(veri)

print(hesap)

Bu programdaki eksiklikleri ve riskleri biliyorsunuz. Byle bir program yazdnzda, eval()


fonksiyonunu kontrolsz bir ekilde kullandnz iin nemli bir gvenlik ana sebep olmu
oluyorsunuz. Gelin isterseniz bu derste rendiimiz bilgileri de kullanarak yukardaki eval()
fonksiyonu iin basit bir kontrol mekanizmas kuralm:
izinli_karakterler = "0123456789+-/*= "

print("""
Basit bir hesap makinesi uygulamas.

leler:

+ toplama
- karma
* arpma
/ blme

Yapmak istediiniz ilemi yazp ENTER


tuuna basn. (rnein 23 ve 46 saylarn
arpmak iin 23 * 46 yazdktan sonra
ENTER tuuna basn.)
""")

while True:
veri = input("leminiz: ")
if veri == "q":
print("klyor...")
break

for s in veri:
if s not in izinli_karakterler:
print("Neyin peindesin?!")
quit()

hesap = eval(veri)

print(hesap)

Burada ncelikle programmz bir while dngs iine aldk. Bylece programmzn ne
zaman sona ereceini kendimiz belirleyebileceiz. Buna gre eer kullanc klavyede q
tuuna basarsa while dngs sona erecek.
Bu programda bizi zellikle ilgilendiren ksm u:
izinli_karakterler = "0123456789+-/*= "

for s in veri:
if s not in izinli_karakterler:
print("Neyin peindesin?!")
quit()

hesap = eval(veri)

14.2. for Dngs 193


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, ilk olarak izinli_karakterler adl bir deiken tanmladk. Program iinde
kullanlmasna izin verdiimiz karakterleri bu deiken iine yazyoruz. Buna gre kullanc
yalnzca 0, 1, 2, 3, 4, 5, 6, 7, 8 ve 9 saylarn, +, -, /, * ve = ilelerini, ayrca boluk karakterini
( ) kullanabilecek.
Kullancnn girdii veri zerinde bir for dngs kurarak, veri iindeki her bir karakterin
izinli_karakterler deikeni iinde yer alp almadn denetliyoruz. zin verilen karakterler
dnda herhangi bir karakterin girilmesi Neyin peindesin?! ktsnn verilip programdan
tamamen klmasna (quit()) yol aacaktr.
Eer kullanc izinli karakterleri kullanarak bir ilem gerekletirmise hesap = eval(veri)
kodu araclyla, kullancnn yapt ilemi eval() fonksiyonuna gnderiyoruz.
Bylece eval() fonksiyonunu daha gvenli bir hale getirebilmek iin basit bir kontrol
mekanizmasnn nasl kurulabileceini grm olduk. Kurduumuz kontrol mekanizmasnn
esas, kullancnn girebilecei veri trlerini snrlamaya dayanyor. Bylece kullanc mesela
yle tehlikeli bir komut giremiyor:
__import__("os").system("dir")

nk bu komutu yazabilmesi iin gereken karakterler izinli_karakterler deikeni iinde


tanml deil. Kullanc yalnzca basit bir hesap makinesinde kullanlabilecek olan saylar ve
ileleri girebiliyor.

14.3 lgili Aralar

Elbette dngler tek balarna bir ey ifade etmezler. Dnglerle ie yarar kodlar
yazabilmemiz iin baz aralara ihtiyacmz var. te bu blmde dngleri daha verimli
kullanmamz salayacak baz fonksiyon ve deyimlerden sz edeceiz. lk olarak range() adl
bir fonksiyondan bahsedelim.

14.3.1 range Fonksiyonu

range kelimesi ngilizcede aralk anlamna gelir. Biz Pythonda range() fonksiyonunu belli
bir aralkta bulunan saylar gstermek iin kullanyoruz. rnein:
>>> for i in range(0, 10):
... print(i)
...
0
1
2
3
4
5
6
7
8
9

Grdnz gibi, range(0, 10) kodu sayesinde ve for dngsn de kullanarak, 0 ile 10 (10
hari) aralndaki saylar ekrana yazdrdk.

194 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

Yukardaki kodda range() fonksiyonuna 0 ve 10 olmak zere iki adet parametre verdiimizi
gryorsunuz. Burada 0 says, aralktaki ilk sayy, 10 says ise aralktaki son sayy
gsteriyor. Yani range() fonksiyonunun forml yledir:
range(ilk_say, son_say)

Bu arada, range(ilk_say, son_say) kodunun verdii ktya ilk_saynn dahil olduuna,


ama son_saynn dahil olmadna dikkat edin.
Eer range() fonksiyonunun ilk parametresi 0 olacaksa, bu parametreyi belirtmesek de
olur. Yani mesela 0 dan 10 a kadar olan saylar listeleyeceksek range() fonksiyonunu yle
yazmamz yeterli olacaktr:
>>> for i in range(10):
... print(i)

range() fonksiyonunun ilk_say parametresi verilmediinde Python ilk parametreyi 0 olarak


alr. Yani range(10) gibi bir kodu Python range(0, 10) olarak alglar. Elbette, eer aralktaki
ilk say 0 dan farkl olacaksa bu sayy ak ak belirtmek gerekir:
>>> for i in range(3, 20):
... print(i)

Burada 3 ten itibaren 20 ye kadar olan saylar ekrana dklecektir.


Hatrlarsanz, biraz nce, kullancnn 3 karakterden ksa, 8 karakterden uzun parola
belirlemesini engelleyen bir uygulama yazmtk. O uygulamay range() fonksiyonunu
kullanarak da yazabiliriz:
while True:
parola = input("parola belirleyin: ")

if not parola:
print("parola blm bo geilemez!")

elif len(parola) in range(3, 8): #eer parolann uzunluu 3 ile 8 karakter


#aralnda ise...
print("Yeni parolanz", parola)
break

else:
print("parola 8 karakterden uzun 3 karakterden ksa olmamal")

Bu fonksiyonu kullanarak bir dngnn ka kez alacan da belirleyebilirsiniz. Aadaki


kodlar dikkatlice inceleyin:
for i in range(3):
parola = input("parola belirleyin: ")
if i == 2:
print("parolay 3 kez yanl girdiniz.",
"Ltfen 30 dakika sonra tekrar deneyin!")

elif not parola:


print("parola blm bo geilemez!")

elif len(parola) in range(3, 8):


print("Yeni parolanz", parola)
break

14.3. lgili Aralar 195


Python 3 iin Trke Klavuz, Srm 3

else:
print("parola 8 karakterden uzun 3 karakterden ksa olmamal")

Burada if i == 2 kodu sayesinde for dngs iinde belirttiimiz i adl deikenin deeri 2
olduu anda parolay 3 kez yanl girdiniz... uyars gsterilecektir. Daha nce de birka yerde
ifade ettiimiz gibi, eer yukardaki kodlarn alma mantn anlamakta zorlanyorsanz,
programn uygun yerlerine print() fonksiyonu yerletirerek arka planda Pythonn neler
evirdiini daha net grebilirsiniz. rnein:
for i in range(3):
print(i)
parola = input("parola belirleyin: ")
if i == 2:
print("parolay 3 kez yanl girdiniz.",
"Ltfen 30 dakika sonra tekrar deneyin!")

elif not parola:


print("parola blm bo geilemez!")

elif len(parola) in range(3, 8):


print("Yeni parolanz", parola)
break

else:
print("parola 8 karakterden uzun 3 karakterden ksa olmamal")

Grdnz gibi, i deikeninin balangtaki deeri 0. Bu deer her dngde 1 artyor ve


bu deikenin deeri 2 olduu anda if i == 2 blou devreye giriyor.
range() fonksiyonunun yetenekleri yukarda anlattklarmzla snrl deildir. Bu fonksiyonun
baz baka maharetleri de bulunur. Hatrlarsanz yukarda bu fonksiyonun formln yle
vermitik:
range(ilk_say, son_say)

Buna gre range() fonksiyonu iki parametre alyor. Ama aslnda bu fonksiyonun nc bir
parametresi daha vardr. Buna gre formlmz gncelleyelim:
range(ilk_say, son_say, atlama_deeri)

Formldeki son parametre olan atlama_deeri, aralktaki saylarn kaar kaar ilerleyeceini
gsterir. Yani:
>>> for i in range(0, 10, 2):
... print(i)
...

0
2
4
6
8

Grdnz gibi, son parametre olarak verdiimiz 2 says sayesinde 0 dan 10 a kadar olan
saylar ikier ikier atlayarak ekrana dklyor.
Bu arada, bir ey dikkatinizi ekmi olmal:

196 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

range() fonksiyonu farkl parametre alan bir fonksiyon. Eer ilk parametre 0 olacaksa bu
parametreyi belirtmek zorunda olmadmz biliyoruz. Yani:
>>> range(10)

Python bu kodu range(0, 10) olarak alglayp buna gre deerlendiriyor. Ancak eer
range() fonksiyonunda nc parametreyi de kullanacaksak, yani range(0, 10, 2) gibi
bir komut vereceksek, parametrenin tamamn da belirtmemiz gerekiyor. Eer burada
btn parametreleri belirtmezsek Python hangi saynn hangi parametreye karlk geldiini
anlayamaz. Yani mesela 0 dan 10 a kadar olan saylar ikier ikier atlayarak ekrana dkmek
iin yle bir ey yazmaya altmz dnn:
>>> for i in range(10, 2):
... print(i)

Burada Python ne yapmaya altnz anlayamaz. Parantez iinde ilk deer olarak 10, ikinci
deer olarak ise 2 yazdnz iin, Python bu 10 saysn balang deeri; 2 saysn ise biti
deeri olarak alglayacaktr. Dolaysyla da Python bu durumda sizin 10 dan 2 ye kadar olan
saylar listelemek istediinizi zannedecek, range() fonksiyonuyla bu ekilde geriye doru
sayamayacamz iin de bo bir kt verecektir. Bu yzden, Pythonun armamas iin
yukardaki rnei u ekilde yazmalyz:
>>> for i in range(0, 10, 2):
... print(i)

Ksacas, eer range() fonksiyonunun kaar kaar sayacan da belirtmek istiyorsak, parantez
iinde, gerekli btn parametreleri belirtmeliyiz.
Grdnz gibi, range() fonksiyonunu kullanarak belirli bir aralktaki saylar alabiliyoruz.
Peki bu saylar tersten alabilir miyiz? Elbette:
>>> for i in range(10, 0, -1):
... print(i)
...
10
9
8
7
6
5
4
3
2
1

Burada range() fonksiyonunu nasl yazdmza ok dikkat edin. Saylar tersten alacamz
iin, ilk parametre 10, ikinci parametre ise 0. nc parametre olarak ise eksi deerli bir
say veriyoruz. Eer saylar hem tersten, hem de mesela 3er 3er atlayarak yazmak isterseniz
yle bir komut verebilirsiniz:
>>> for i in range(10, 0, -3):
... print(i)
...
10
7
4
1

14.3. lgili Aralar 197


Python 3 iin Trke Klavuz, Srm 3

Bu arada, etkileimli kabukta range(10) gibi bir komut verdiinizde range(0, 10) kts
aldnz gryorsunuz. Bu kt, verdiimiz komutun 0 ile 10 aras saylar elde etmemizi
salayacan belirtiyor, ama bu saylar o anda bize gstermiyor. Daha nce verdiimiz
rneklerden de anlalaca gibi, 0 -10 aralndaki saylar grebilmek iin range(10)
ifadesi zerinde bir for dngs kurmamz gerekiyor. range(10) ifadesinin tad
saylar grebilmek iin for dngs kurmak tek seenek deildir. Bu ilem iin yldzl
parametrelerden de yararlanabiliriz. print() fonksiyonunu incelediimiz derste yldzl
parametrelerin nasl kullanldn gstermitik. Dilerseniz imdi bu parametre tipini range()
fonksiyonuna nasl uygulayabileceimizi grelim:
>>> print(*range(10))

0 1 2 3 4 5 6 7 8 9

print() fonksiyonunun sep parametresi yardmyla bu kty istediiniz gibi


dzenleyebileceinizi biliyorsunuz. Mesela ktdaki saylar birbirlerinden virglle ayrmak
iin yle bir komut verebiliyoruz:
>>> print(*range(10), sep=", ")

0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Bylece range() fonksiyonunu enine boyuna incelemi ve bu fonksiyonun ne ie yaradn,


nasl kullanlacan anlamamz salayan rnekler vermi olduk. Artk baka bir konuyu
geebiliriz.

14.3.2 pass Deyimi

pass kelimesi ngilizcede gemek, pas gemek gibi anlamlara gelir. Pythondaki kullanm
da bu anlama olduka yakndr. Biz bu deyimi Pyhonda grmezden gel, hibir ey yapma
anlamnda kullanacaz.
Dilerseniz pass deyimini tarif etmeye almak yerine bu deyimi bir rnek zerinde
aklamaya alalm.
Hatrlarsanz yukarda yle bir rnek vermitik:
while True:
parola = input("parola belirleyin: ")

if not parola:
print("parola blm bo geilemez!")

elif len(parola) in range(3, 8): #eer parolann uzunluu 3 ile 8 karakter


#aralnda ise...
print("Yeni parolanz", parola)
break

else:
print("parola 8 karakterden uzun 3 karakterden ksa olmamal")

Burada mesela eer kullanc parolay bo brakrsa parola blm bo geilemez! uyars
gsteriyoruz. imdi o if blounu yle yazdmz dnn:

198 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

while True:
parola = input("parola belirleyin: ")

if not parola:
pass

elif len(parola) in range(3, 8): #eer parolann uzunluu 3 ile 8 karakter


#aralnda ise...
print("Yeni parolanz", parola)
break

else:
print("parola 8 karakterden uzun 3 karakterden ksa olmamal")

Burada, eer kullanc parolay bo brakrsa programmz hibir ey yapmadan yoluna devam
edecektir. Yani burada pass deyimi yardmyla programmza u emri vermi oluyoruz:
Eer kullanc parolay bo geerse grmezden gel. Hibir ey yapmadan yoluna
devam et!
Baka bir rnek daha verelim:
while True:
say = int(input("Bir say girin: "))

if say == 0:
break

elif say < 0:


pass

else:
print(say)

Burada eer kullanc 0 saysn girerse programmz sona erer (break deyimini biraz sonra
inceleyeceiz). Eer kullanc 0 dan kk bir say girerse, yani kullancnn girdii say
eksi deerli ise, pass deyimininin etkisiyle programmz hibir ey yapmadan yoluna devam
eder. Bu koullarn dndaki durumlarda ise programmz kullancnn girdii saylar ekrana
yazdracaktr.
Yukarda anlatlan durumlarn dnda, pass deyimini kodlarnz henz taslak aamasnda
olduu zaman da kullanabilirsiniz. rnein, diyelim ki bir kod yazyorsunuz. Programn
gidiatna gre, bir noktada yapmanz gereken bir ilem var, ama henz ne yapacanza
karar vermediniz. Byle bir durumda pass deyiminden yararlanabilirsiniz. Mesela birtakm
if deyimleri yazmay dnyor olun:
if .....:
byle yap

elif .....:
yle yap

else:
pass

Burada henz else blounda ne yaplacana karar vermemi olduunuz iin, oraya bir pass
koyarak durumu imdilik geitiriyorsunuz. Program son haline gelene kadar oraya bir eyler

14.3. lgili Aralar 199


Python 3 iin Trke Klavuz, Srm 3

yazm olacaksnz.
Szn z, pass deyimlerini, herhangi bir ilem yaplmasnn gerekli olmad durumlar iin
kullanyoruz. lerde ie yarar programlar yazdnzda, bu pass deyiminin grndnden
daha faydal bir ara olduunu anlayacaksnz.

14.3.3 break Deyimi

Pythonda break zel bir deyimdir. Bu deyim yardmyla, devam eden bir sreci kesintiye
uratabiliriz. Bu deyimin kullanld basit bir rnek verelim:
>>> while True:
... parola = input("Ltfen bir parola belirleyiniz:")
... if len(parola) < 5:
... print("Parola 5 karakterden az olmamal!")
... else:
... print("Parolanz belirlendi!")
... break

Burada, eer kullancnn girdii parolann uzunluu 5 karakterden azsa, Parola 5 karakterden
az olmamal! uyars gsterilecektir. Eer kullanc 5 karakterden uzun bir parola belirlemise,
kendisine Parolanz belirlendi! mesajn gsterip, break deyimi yardmyla programdan
kyoruz.
Grdnz gibi, break ifadesinin temel grevi bir dngy sona erdirmek. Buradan
anlayacamz gibi, break ifadesinin her zaman bir dng iinde yer almas gerekiyor. Aksi
halde Python bize yle bir hata verecektir:
SyntaxError: 'break' outside loop

Yani:
SzDizimiHatas: ``break`` dng dnda ..

14.3.4 continue Deyimi

continue ilgin bir deyimdir. sterseniz continue deyimini anlatmaya almak yerine
bununla ilgili bir rnek verelim:
while True:
s = input("Bir say girin: ")
if s == "iptal":
break

if len(s) <= 3:
continue

print("En fazla haneli bir say girebilirsiniz.")

Burada eer kullanc klavyede iptal yazarsa programdan klacaktr. Bunu;


if s == "iptal":
break

satryla salamay baardk.

200 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

Eer kullanc tarafndan girilen say haneli veya daha az haneli bir say ise, continue
ifadesinin etkisiyle:
>>> print("En fazla haneli bir say girebilirsiniz.")

satr es geilecek ve dngnn en bana gidilecektir.


Eer kullancnn girdii saydaki hane ten fazlaysa ekrana:
En fazla haneli bir say girebilirsiniz.

cmlesi yazdrlacaktr.
Dolaysyla buradan anladmza gre, continue deyiminin grevi kendisinden sonra gelen
her eyin es geilip dngnn bana dnlmesini salamaktr. Bu bilgiye gre, yukardaki
programda eer kullanc, uzunluu karakterden az bir say girerse continue deyiminin
etkisiyle programmz dngnn en bana geri gidiyor. Ama eer kullanc, uzunluu
karakterden fazla bir say girerse, ekrana En fazla haneli bir say girebilirsiniz, cmlesinin
yazdrldn gryoruz.

14.4 rnek Uygulamalar

Python programlama dilinde dnglerin neye benzediini rendik. Bu blnde ayrca


dnglerle birlikte kullanabileceimiz baka aralar da tandk. imdi dilerseniz bu
rendiklerimizi pekitirmek iin birka ufak alma yapalm.

14.4.1 Karakter Dizilerinin eriini Karlatrma

Diyelim ki elinizde yle iki farkl metin var:


ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"

Siz burada, ilk_metin adl deiken iinde bulunan, ama ikinci_metin adl deiken iinde
bulunmayan eleri ayklamak istiyorsunuz. Yani bu iki metnin ieriini karlatrp, farkl
eleri bulmay amalyorsunuz. Bu ilem iin, bu blmde rendiimiz dnglerden ve
daha nce rendiimiz baka aralardan yararlanabilirsiniz. imdi dikkatlice bakn:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"

for s in ilk_metin:
if not s in ikinci_metin:
print(s)

Bu kodlar bir dosyaya kaydedip altrdmzda u kty alyoruz:


a
a

Demek ki ilk_metin adl deikende olup da ikinci_metin adl deikende olmayan eler
bunlarm...

14.4. rnek Uygulamalar 201


Python 3 iin Trke Klavuz, Srm 3

Bu kodlarda anlayamayacanz hibir ey yok. Ama dilerseniz biz yine de bu kodlar tek tek
inceleyelim.
lk olarak deikenlerimizi tanmladk:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"

Amacmz ilk_metin de olan, ama ikinci_metin de olmayan eleri grmek. Bunun iin
ilk_metin deki eleri tek tek ikinci_metin deki elerle karlatrmamz gerekiyor. Tahmin
edebileceiniz gibi, bir metnin btn elerine tek tek bakabilmenin en iyi yolu for
dnglerini kullanmaktr. O halde dngmz yazalm:
for s in ilk_metin: #ilk_metin'deki, 's' adn verdiimiz btn eler iin
if not s in ikinci_metin: #eer 's' adl bu e ikinci_metin'de yoksa
print(s) #'s' adl eyi ekrana bas

Grdnz gibi, dngleri (for), bool ilelerini (not ) ve aitlik ilelerini (in ) kullanarak,
istediimiz eyi rahatlkla yapabiliyoruz. Burada kullandmz if deyimi, bir nceki satrda
for dngs ile zerinden getiimiz eleri szmemizi salyor. Burada temel olarak u
ilemi yapyoruz:
1. ilk_metin iindeki btn elerin zerinden geiyoruz,
2. Bu eleri belli bir lte gre szyoruz,
3. lte uyan eleri ekrana basyoruz.
Elbette yukarda yaptmz ilemin tersini yapmak da mmkndr. Biz yukardaki kodlarda
ilk_metin de olan, ama ikinci_metin de olmayan eleri szdk. Eer istersek ikinci_metin de
olan, ama ilk_metin de olmayan eleri de szebiliriz. Mantmz yine ayn:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"

for s in ikinci_metin: #ikinci_metin'deki, 's' adn verdiimiz btn eler iin


if not s in ilk_metin: #eer 's' adl bu e ilk_metin'de yoksa
print(s) #'s' adl eyi ekrana bas

Bu da bize u kty veriyor:


u

o
r
y
e
u

r
u
e
e
e
u

Grdnz gibi, yaptmz tek ey, ilk_metin ile ikinci_metin in yerlerini deitirmek oldu.
Kullandmz mantk ise deimedi.

202 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

Bu arada, yukardaki ktda bizi rahatsz eden bir durum var. ktda baz harer birbirini
tekrar ediyor. Aslnda temel olarak sadece u harer var:
u

o
r
y
e

Ama metin iinde baz harer birden fazla sayda getii iin, doal olarak ktda da bu harer
birden fazla sayda grnyor. Ama tabii ki, eer biz istersek farkl olan her harften yalnzca
bir tanesini ktda grmeyi de tercih edebiliriz. Bunun iin yle bir kod yazabiliriz:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"

fark = ""

for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s
print(fark)

Burada da anlayamayacamz hibir ey yok. Bu kodlardaki btn paralar tanyoruz.


Herzamanki gibi ncelikle deikenlerimizi tanmladk:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"

Daha sonra fark adl bo bir karakter dizisi tanmlyoruz. Metinler iindeki farkl karakter
dizilerini fark adl bu karakter dizisi iinde depolayacaz.
Ardndan da for dngmz yazyoruz:
for s in ikinci_metin: # ikinci_metin'de 's' dediimiz btn eler iin
if not s in ilk_metin: # eer 's' ilk_metin'de yoksa
if not s in fark: # eer 's' fark'ta da yoksa
fark += s # bu eyi fark deikenine ekle
print(fark) # fark deikenini ekrana bas

Uyguladmz mantn ne kadar basit olduunu gryorsunuz. Bu kodlarda basite u


ilemleri yapyoruz:
1. ikinci_metin deikeni iindeki btn elerin zerinden tek tek ge,
2. Eer bu deikendeki herhangi bir e ilk_metin de ve fark ta yoksa o eyi fark a ekle.
3. Son olarak da fark ekrana bas.
Bu kodlarda dikkatimizi eken ve zerinde durmamz gereken baz noktalar var. Burada
zellikle fark deikenine e ekleme ilemini nasl yaptmza dikkat edin.
Python programlama dilinde nceden oluturduumuz bir karakter dizisini baka bir karakter
dizisi ile birletirdiimizde bu ilem ilk oluturduumuz karakter dizisini etkilemez. Yani:
>>> a = 'istihza'
>>> a + '.com'

14.4. rnek Uygulamalar 203


Python 3 iin Trke Klavuz, Srm 3

'istihza.com'

Burada sanki a adl zgn karakter dizisini deitirmiiz ve istihza.com deerini elde etmiiz
gibi grnyor. Ama aslnda a nn durumunda hibir deiiklik yok:
>>> a

'istihza'

Grdnz gibi, a deikeninin deeri hl istihza. Bu durumun nedeni, birletirme


ilemlerinin bir deitirme ilemi olmamasdr. Yani mesela iki karakter dizisini
birletirdiinizde birleen karakter dizileri zerinde herhangi bir deiiklik olmaz. Bu
durumda yapabileceimiz tek ey, karakter dizisine eklemek istediimiz eyi de ieren yeni
bir karakter dizisi oluturmaktr. Yani:
>>> a = 'istihza'
>>> a = a + '.com'
>>> print(a)

istihza.com

Burada sanki deeri istihza olan a adl bir deikene .com deerini eklemiiz gibi
grnyor, ama aslnda biz burada a deikenini yok edip, istihza.com deerini ieren, a
adl baka bir deiken tanmladk. Bu durumu nasl teyit edeceinizi biliyorsunuz:
>>> a = 'istihza'
>>> id(a)

15063200

>>> a = a + '.com'
>>> id(a)

15067960

Burada id() fonksiyonunu kullanarak karakter dizilerinin kimliklerini sorguladk. Grdnz


gibi, isimleri ayn da olsa, aslnda ortada iki farkl a deikeni var. Kimlik numaralarnn
farkl olmasndan anladmza gre, ilk bata tanmladmz a deikeni ile a = a + .com
satryla oluturduumuz a deikeni birbirinden farkl.
Bu arada, eer istersek yukardaki deer atama ilemini, nceki blmlerde rendiimiz
deer atama ileleri yardmyla ksaltabileceimizi de biliyorsunuz:
>>> a += '.com'

te ilk_metin ile ikinci_metin deikenleri arasndaki farkl hareri yalnzca birer kez
yazdrmak iin kullandmz kodlarda da yukardaki ilemi yaptk:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"

fark = ''

for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s
print(fark)

204 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, nce bo bir fark deikeni oluturduk. Daha sonra bu deikene for
dngs iinde yeni deerler atayabilmek (daha dorusu atarm gibi yapmak) iin fark += s
gibi bir kod kullandk. Bylece for dngsnn her dnnde s adn verdiimiz herbir eyi
tek tek fark deikenine yolladk. Bylece program sonunda elimizde, farkl eleri yalnzca
birer kez ieren fark adl bir deiken olmu oldu. Dediimiz gibi, ilk bata tanmladmz
bo fark deikeni ile, program sonunda farkl deerleri ieren fark deikeni aslnda ayn
deil. Yani biz ilk fark deikenine dngnn her dnnde yeni bir e eklemek yerine,
dngnn her dnnde yeni bir fark deikeni oluturmu oluyoruz. Ama programn
sonunda sanki fark deikenine her defasnda yeni bir deer atamz gibi grnyor ve bu
da bizim iimizi grmemize yetiyor...
Programn bandaki ve sonundaki fark deikenlerinin aslnda birbirinden farkl olduunu
teyit etmek iin u kodlar kullanabilirsiniz:
ilk_metin = "asdasfddgdhfjfdgdfkgjdfklgjdfklgjdfkghdfjghjklsdhajlsdhjkjhkhjjh"
ikinci_metin = "sdfsudoryeufsjkdfhdjklghjdfklruseldhfjlkdshfljskeeuf"

fark = ""
print("fark'n ilk tanmland zamanki kimlik numaras: ", id(fark))

for s in ikinci_metin:
if not s in ilk_metin:
if not s in fark:
fark += s

print("fark'n program sonundaki kimlik numaras: ", id(fark))

Grdnz gibi, gerekten de ortada iki farkl fark deikeni var. Bu durumu id()
fonksiyonu yardmyla dorulayabiliyoruz.
Peki bu bilginin bize ne faydas var?
imdilik u kadarn syleyelim: Eer o anda muhatap olduunuz bir veri tipinin mizacn,
huyunu-suyunu bilmezseniz yazdnz programlarda ok kt srprizlerle karlaabilirsiniz.
Birka blm sonra baka veri tiplerini de rendikten sonra bu durumu daha ayrntl bir
ekilde inceleyeceiz.
Bu arada, tahmin edebileceiniz gibi yukardaki for dngsn yle de yazabilirdik:
for s in ikinci_metin:
if not s in ilk_metin and not s in fark:
fark += s

Burada iki farkl if deyimini iki farkl satrda yazmak yerine, bu deyimleri and ileci ile
birbirine baladk.
Bu rnek ile ilgili syleyeceklerimiz imdilik bu kadar. Gelin biz imdi isterseniz bilgilerimizi
pekitirmek iin baka bir rnek daha yapalm.

14.4.2 Dosyalarn eriini Karlatrma

Bir nceki rnekte karakter dizilerinin ieriini nasl karlatrabileceimizi gsteren bir
rnek vermitik. imdi de, gerek hayatta karnza kmas daha olas bir durum olmas
bakmndan, dosyalarn ieriini nasl karlatracamza dair bir rnek verelim.

14.4. rnek Uygulamalar 205


Python 3 iin Trke Klavuz, Srm 3

Esasnda karakter dizilerinin ieriini birbirleriyle nasl karlatryorsak, dosyalarn ieriini


de benzer ekilde karlatrabiliriz. Mesela ierii u olan isimler1.txt adl bir dosyamz
olduunu varsayalm:
Ahmet
Mehmet
Sevgi
Sinan
Deniz
Ege
Efe
Ferhat
Frat
Zeynep
Hazan
Mahmut
Celal
Cemal
zhan
zkan

Yine ierii u olan bir de isimler2.txt adl baka bir dosya daha olduunu dnelim:
Grsel
Mehmet
Sevgi
Sami
Deniz
Ege
Efe
Ferhat
Frat
Tlay
Derya
Hazan
Mahmut
Tezcan
Cemal
zhan
zkan
zcan
Dilek

Amacmz bu iki dosyann ieriini karlatrp, farkl eleri ortaya sermek. Dediimiz gibi,
bir nceki rnekte izlediimiz yolu burada da takip edebiliriz. Dikkatlice bakn:
d1 = open("isimler1.txt") # dosyay ayoruz
d1_satrlar = d1.readlines() # satrlar okuyoruz

d2 = open("isimler2.txt")
d2_satrlar = d2.readlines()

for i in d2_satrlar:
if not i in d1_satrlar:
print(i)

d1.close()
d2.close()

206 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

Gerekten de mantn bir nceki rnekle tamamen ayn olduunu gryorsunuz. Biz henz
Pythonda dosyalarn nasl ileneceini renmedik, ama daha nce grdmz open()
fonksiyonu yardmyla en azndan dosyalar aabilecek kadar biliyoruz dosya ilemlerinin nasl
yrtleceini...
Burada farkl olarak readlines() adl bir metot gryoruz. Biz burada bu metodun
ayrntlarna inmeyeceiz, ama imdilik dosya ieriinin satrlar halinde okunmasn
saladn bilelim yeter.
Bu arada, eer ktda Trke karakterleri dzgn grntleyemiyorsanz open()
fonksiyonunun encoding adl bir parametresi vastasyla ierii UTF-8 olarak kodlayabilirsiniz:
d1 = open("isimler1.txt", encoding="utf-8") # dosyay ayoruz
d1_satrlar = d1.readlines() # satrlar okuyoruz

d2 = open("isimler2.txt", encoding="utf-8")
d2_satrlar = d2.readlines()

for i in d2_satrlar:
if not i in d1_satrlar:
print(i)

d1.close()
d2.close()

Bu ekilde Trke karakterleri dzgn bir ekilde grntleyebiliyor olmanz lazm.


Eer Windowsta Trke karakterleri hala dzgn grntleyemiyorsanz encoding
parametresinde utf-8 yerine cp1254 adl dil kodlamasn kullanmay deneyebilirsiniz:
encoding = "cp1254"

Yukardaki rneklerde bir ierik karlatrmas yapp, farkl eleri aykladk. Ayn ekilde
benzer eleri ayklamak da mmkndr. Bu ilemin nasl yaplacan az ok tahmin
ettiinizi zannediyorum:
d1 = open("isimler1.txt")
d1_satrlar = d1.readlines()

d2 = open("isimler1.txt")
d2_satrlar = d2.readlines()

for i in d2_satrlar:
if i in d1_satrlar:
print(i)

d1.close()
d2.close()

Burada bir ncekinden farkl olarak if not i in d2_satrlar kodu yerine, doal olarak, if
i in d2_satrlar kodunu kullandmza dikkat edin.
Dosyalar zerinde yaptmz ilemleri tamamladktan sonra close() metodu ile bunlar
kapatmay unutmuyoruz:
d1.close()
d2.close()

14.4. rnek Uygulamalar 207


Python 3 iin Trke Klavuz, Srm 3

14.4.3 Karakter Dizisindeki Karakterleri Sayma

Yukardaki rneklerde ierik karlatrmaya ilikin birka rnek verdik. imdi yine bilgilerimizi
pekitirmek iin baka bir konuya ilikin rnekler verelim.
Mesela elimizde yle bir metin olduunu varsayalm:
Bu programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90l yllarn banda gelitirilmeye balanmtr. ou insan,
isminin Python olmasna aldanarak, bu programlama dilinin, adn piton
ylanndan aldn dnr. Ancak zannedildiinin aksine bu programlama
dilinin ad piton ylanndan gelmez. Guido Van Rossum bu programlama dilini,
The Monty Python adl bir ngiliz komedi grubunun, Monty Pythons Flying
Circus adl gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar
gerek byle olsa da, Python programlama dilinin pek ok yerde bir ylan
figr ile temsil edilmesi neredeyse bir gelenek halini almtr.

Yapmamz gereken bir istatistik almas gereince bu metinde her harn ka kez getiini
hesaplamanz gerekiyor.
Bunun iin yle bir program yazabiliriz:
metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90l yllarn banda gelitirilmeye balanmtr. ou insan,
isminin Python olmasna aldanarak, bu programlama dilinin, adn piton
ylanndan aldn dnr. Ancak zannedildiinin aksine bu programlama dilinin
ad piton ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty
Python adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl
gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa
da, Python programlama dilinin pek ok yerde bir ylan figr ile temsil
edilmesi neredeyse bir gelenek halini almtr."""

harf = input("Sorgulamak istediiniz harf: ")

say = ''

for s in metin:
if harf == s:
say += harf

print(len(say))

Burada ncelikle metnimizi bir deiken olarak tanmladk. Ardndan da kullancya hangi
har sorgulamak istediini sorduk.
Bu kodlarda tanmladmz say adl deiken, sorgulanan har, metinde getii sayda iinde
barndracaktr. Yani mesela metin 5 tane a har varsa say deikeninin deeri aaaaa
olacaktr.
Sonraki satrlarda for dngmz tanmlyoruz:
for s in metin: # metin iinde 's' adn verdiimiz herbir e iin
if harf == s: # eer kullancdan gelen harf 's' ile aynysa
say += harf # kullancdan gelen bu harfi say deikenine yolla

Dediimiz gibi, say deikeni, sorgulanan har, metinde getii sayda barndryor.
Dolaysyla bir harn metinde ka kez getiini bulmak iin say deikeninin uzunluunu
yazdrmamz yeterli olacaktr:

208 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

print(len(say))

Dilerseniz yukardaki program yazmak iin daha farkl bir mantk da kullanabilirsiniz.
Dikkatlice bakn:
metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90l yllarn banda gelitirilmeye balanmtr. ou insan,
isminin Python olmasna aldanarak, bu programlama dilinin, adn piton
ylanndan aldn dnr. Ancak zannedildiinin aksine bu programlama dilinin
ad piton ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty
Python adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl
gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa
da, Python programlama dilinin pek ok yerde bir ylan figr ile temsil
edilmesi neredeyse bir gelenek halini almtr."""

harf = input("Sorgulamak istediiniz harf: ")

say = 0

for s in metin:
if harf == s:
say += 1

print(say)

Burada say deikeninin ilk deeri 0 olarak belirledik. Dng iinde de, sorgulanan harn
metin iinde her geiinde say deikeninin deerini 1 say artrdk. Dolaysyla sorgulanan
harn metinde ka kez getiini bulmak iin say deikeninin son deerini yazdrmamz
yeterli oldu.

14.4.4 Dosya iindeki Karakterleri Sayma

Dilerseniz bir nceki rnekte kullandmz metnin program iinde bir deiken deil de,
mesela bir dosyadan okunan bir metin olduunu varsayalm imdi:
hakknda = open("hakknda.txt", encoding="utf-8")

harf = input("Sorgulamak istediiniz harf: ")

say = 0

for karakter_dizisi in hakknda:


for karakter in karakter_dizisi:
if harf == karakter:
say += 1
print(say)

hakknda.close()

Burada yaptmz ilk i elbette dosyamz amak oldu:


hakknda = open("hakknda.txt", encoding="utf-8")

Bu komutla, hakknda.txt adl dosyay UTF-8 kodlamas ile atk. Daha sonra kullancya,
sorgulamak istedii har soruyoruz:

14.4. rnek Uygulamalar 209


Python 3 iin Trke Klavuz, Srm 3

harf = input("Sorgulamak istediiniz harf: ")

Ardndan da sorgulanan harn dosyada ka kez getii bilgisini tutacak olan say adl bir
deiken tanmlyoruz:
say = 0

Sra geldi for dngmz tanmlamaya:


for karakter_dizisi in hakknda:
for karakter in karakter_dizisi:
if harf == karakter:
say += 1

Bu dngy anlamakta bir miktar zorlanm olabilirsiniz. Her zaman sylediimiz gibi,
Pythonda bir kod parasn anlamann en iyi yntemi, gerekli yerlere print() fonksiyonlar
yerletirerek, programn verdii ktlar incelemektir:
for karakter_dizisi in hakknda:
print(karakter_dizisi)
#for karakter in karakter_dizisi:
# if harf == karakter:
# say += 1

Grdnz gibi, ilk for dngsnn hemen sonrasna bir print() fonksiyonu yerletirerek
bu dngnn verdii ktlar inceliyoruz. Bu arada, amacmza hizmet etmeyen satrlar da
yorum iine alarak etkisizletirdiimize dikkat edin.
ktya baktmz zaman, yle bir durumla karlayoruz:
Bu programlama dili Guido Van Rossum adl Hollandal bir programc

tarafndan 90l yllarn banda gelitirilmeye balanmtr. ou insan,

isminin Python olmasna aldanarak, bu programlama dilinin, adn piton

ylanndan aldn dnr. Ancak zannedildiinin aksine bu programlama dilinin

ad piton ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty

Python adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl

gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa

da, Python programlama dilinin pek ok yerde bir ylan figr ile temsil

edilmesi neredeyse bir gelenek halini almtr.

Burada herbir satr ayr bir karakter dizisidir. Eer herbir satrn ayr bir karakter dizisi
olduunu daha net bir ekilde grmek istiyorsanz repr() adl zel bir fonksiyondan
yararlanabilirsiniz:
for karakter_dizisi in hakknda:
print(repr(karakter_dizisi))
#for karakter in karakter_dizisi:
# if harf == karakter:
# say += 1

210 Blm 14. Dngler (Loops)


Python 3 iin Trke Klavuz, Srm 3

Bu kodlar bu kez yle bir kt verir:


'Bu programlama dili Guido Van Rossum adl Hollandal bir programc\n'
'tarafndan 90l yllarn banda gelitirilmeye balanmtr. ou insan,\n'
'isminin Python olmasna aldanarak, bu programlama dilinin, adn piton\n'
'ylanndan aldn dnr. Ancak zannedildiinin aksine bu programlama dilinin\n'
'ad piton ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty\n'
'Python adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl\n'
'gsterisinden esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa\n'
'da, Python programlama dilinin pek ok yerde bir ylan figr ile temsil\n'
'edilmesi neredeyse bir gelenek halini almtr.'

Bu ktya ok dikkatlice bakn. repr() fonksiyonu sayesinde Pythonn alttan alta neler
evirdiini bariz bir biimde gryoruz. Karakter dizisinin balang ve bitiini gsteren trnak
iaretleri ve \n ka dizilerinin grnr vaziyette olmas sayesinde herbir satrn ayr bir
karakter dizisi olduunu daha net bir ekilde grebiliyoruz.
Biz yazdmz kodlarda, kullancdan bir harf girmesini istiyoruz. Kullandmz algoritma
gereince bu har metindeki karakter dizileri iinde geen herbir karakterle tek tek
karlatrmamz gerekiyor. input() metodu araclyla kullancdan tek bir karakter alyoruz.
Kullandmz for dngs ise bize bir karakter yerine her satrda bir karakter dizisi veriyor.
Dolaysyla mesela kullanc a harni sorgulamsa, ilk for dngs bu harn karsna Bu
programlama dili Guido Van Rossum adl Hollandal bir programcn adl karakter dizisini
karacaktr. Dolaysyla bizim bir seviye daha alta inerek, ilk for dngsnden elde edilen
deiken zerinde baka bir for dngs daha kurmamz gerekiyor. Bu yzden yle bir kod
yazyoruz:
for karakter_dizisi in hakknda:
for karakter in karakter_dizisi:
...

Bylece i ie iki for dngs oluturmu oluyoruz. sterseniz bu anlattmz eyleri daha
net grmek iin yine print() fonksiyonundan yararlanabilirsiniz:
hakknda = open("hakknda.txt", encoding="utf-8")

harf = input("Sorgulamak istediiniz harf: ")

say = 0

for karakter_dizisi in hakknda:


for karakter in karakter_dizisi:
print(karakter)
# if harf == karakter:
# say += 1
#print(say)

karakter deikenin deerini ekrana yazdrarak Pythonn alttan alta neler evirdiini daha
net grebiliyoruz.
Kodlarn geri kalannda ise, kullancnn sorgulad harn, for dngs ile zerinden
getiimiz karakter_dizisi adl deiken iindeki karakterlerle eleip elemediini
denetliyoruz. Eer eleiyorsa, her elemede say deikeninin deerini 1 say artryoruz.
Bylece en elimizde sorgulanan harn metin iinde ka kez getii bilgisi olmu oluyor.
Son olarak da, ilk bata atmz dosyay kapatyoruz:

14.4. rnek Uygulamalar 211


Python 3 iin Trke Klavuz, Srm 3

hakknda.close()

Nihayet bir konunun daha sonuna ulatk. Dngler ve dnglerle ilikili aralar da epey
ayrntl bir ekilde incelediimize gre gnl rahatlyla bir sonraki konuya geebiliriz.

212 Blm 14. Dngler (Loops)


BLM 15

Hata Yakalama

imdiye kadar yazdmz btn programlar, dikkat ettiyseniz tek bir ortak varsaym zerine
kurulu. Buna gre biz, yazdmz programn kullanc tarafndan nasl kullanlmasn
istiyorsak, her zaman o ekilde kullanlacan varsayyoruz. rnein saylar toplayan bir
program yazdmzda, kullancnn her zaman say deerli bir veri gireceini dnyoruz.
Ancak btn iyi niyetimize ramen, yazdmz programlarda iler her zaman beklediimiz
gibi gitmeyebilir. rnein, dediimiz gibi, yazdmz program, kullancnn bir say girmesi
temeli zerine kurgulamsak, kullancnn her zaman say deerli bir veri gireceinden emin
olamayz
Mesela yle bir program yazdmz dnn:
veri1 = input("Karekkn hesaplamak istediiniz say: ")
karekk = int(veri1) ** 0.5

print(veri1, "saysnn karekk: ", karekk)

veri2 = input("Karesini hesaplamak istediiniz say: ")


kare = int(veri2) ** 2

print(veri2, "saysnn karesi: ", kare)

Bu kodlardaki sorunu anlamaya almadan nce dilerseniz kodlar yle bir inceleyelim.
Grdnz gibi, burada kullancnn girecei saylara gre karekk ve kare alma ilemleri
yapyoruz. Bu kodlarda grdmz ** ileci yardmyla bir saynn herhangi bir kuvvetini
hesaplayabileceimizi biliyorsunuz. Mesela 217 nin ka ettiini hesaplamak iin ** ilecini
kullanabiliyoruz:
>>> 21 ** 7

1801088541

Yine bildiiniz gibi, bu ileten, bir saynn karesini hesaplamak iin de yararlanabiliyoruz.
nk neticede bir saynn karesi, o saynn 2. kuvvetidir:
>>> 12 ** 2

144

Ayn ekilde, eer bir saynn, 0.5inci kuvvetini hesaplarsak o saynn karekkn bulmu
oluyoruz. (Bu bilgileri nceki konulardan hatrlyor olmalsnz):

213
Python 3 iin Trke Klavuz, Srm 3

>>> 144 ** 0.5

12

Kodlarmz incelediimize gre, bu programdaki aksaklklar irdelemeye balayabiliriz.


Bu program, kullanc say deerli bir veri girdii mddete sorunsuz bir ekilde alacaktr.
Peki ya kullanc say deerli bir veri yerine baka bir ey girerse ne olur?
rnein kullanc yukardaki programa bir say yerine, (bilerek veya bilmeyerek) iinde harf
barndran bir veri girerse una benzer bir hata alr:
Traceback (most recent call last):
File "deneme.py", line 2, in <module>
karekk = int(veri1) ** 0.5
ValueError: invalid literal for int() with base 10: 'fds'

Yazdnz programlarn bu tr hatalar vermesi normaldir. Ancak son kullanc asndan


dndmzde, kullancnn yukardaki gibi bir hata mesaj grmesi yerine, hatann neden
kaynaklandn ya da neyi yanl yaptn daha ak bir ekilde ifade eden bir mesaj almas
ok daha mantkl olacaktr. Zira yukardaki hata mesaj programclar asndan anlaml
olabilir, ancak son kullanc asndan bsbtn anlalmazdr!
Dediimiz gibi, programnzn alma esnasnda bu tr hatalar vermesi normal. nk
yapmaya altnz ilem, kullancnn belli tipte bir veri girmesine bal. Burada sizin
bir programc olarak greviniz, yazdnz programn alma esnasnda vermesi muhtemel
hatalar nceden kestirip, programnzda buna gre baz nlemler almanzdr. te biz de bu
blmde bu nlemleri nasl alacamz anlamaya alacaz.

15.1 Hata Trleri

Biz bu blmde hatalardan bahsedeceimizi sylemitik. Ancak her eyden nce hata
kavramnn ok boyutlu olduunu hatrlatmakta fayda var. zellikle programclk asndan
hata kavramnn ne anlama geldiini biraz incelememiz gerekiyor.
Biz bu blmde hatalar farkl balk altnda ele alacaz:
1. Programc Hatalar (Error )
2. Program Kusurlar (Bug )
3. stisnalar (Exception )
ncelikle programc hatalarndan bahsedelim.
Programcdan kaynaklanan hatalar dorudan doruya program yazan kiinin
dikkatsizliinden tr ortaya kan bariz hatalardr. rnein u kod bir programc
hatas ierir:
>>> print "Merhaba Python!"

Bu kodu altrdnzda yle bir hata mesaj grrsnz:


>>> print "Merhaba Python!"

File "<stdin>", line 1


print "Merhaba Python!"

214 Blm 15. Hata Yakalama


Python 3 iin Trke Klavuz, Srm 3

^
SyntaxError: invalid syntax

Bu hata mesajnda bizi ilgilendiren ksm son cmlede yer alyor: SyntaxError, yani Sz dizimi
hatas.
Bu hatalar, programlama diline ilikin bir zelliin yanl kullanmndan veya en basit
ekilde programcnn yapt yazm hatalarndan kaynaklanr. Programcnn hatalar genellikle
SyntaxError eklinde ortaya kar. Bu hatalar ounlukla programc tarafndan farkedilir ve
program kullancya ulamadan nce programc tarafndan dzeltilir. Bu tr hatalarn tespiti
dier hatalara kyasla kolaydr. nk bu tr hatalar programnzn almasn engelledii
iin bunlar farketmemek pek mmkn deildir...
Program kusurlar, baka bir deyile bug lar ise ok daha karmaktr. Kusurlu programlar
ou zaman herhangi bir hata vermeden alr. Ancak programn rettii ktlar beklediiniz
gibi deildir. rnein yazdnz programda bir forml hatas yapm olabilirsiniz. Bu
durumda programnz hibir ey yokmu gibi alr, ancak forml hatal olduu iin
hesaplamalarn sonular yanltr. rnein daha nceki derslerimizde yazdmz u program
yukardaki gibi bir kusur ierir:
say1 = input("Toplama ilemi iin ilk sayy girin: ")
say2 = input("Toplama ilemi iin ikinci sayy girin: ")

print(say1, "+", say2, "=", say1 + say2)

Bu programda kullanc veri girdii zaman, programmz toplama ilemi deil karakter dizisi
birletirme ilemi yapacaktr. Byle bir program alma srasnda hata vermeyecei iin
buradaki sorunu tespit etmek, zellikle byk programlarda ok gtr. Yani sizin dzgn
altn zannettiiniz program aslnda gizliden gizliye bir bug barndryor olabilir.
Ayn ekilde, mesela eval() fonksiyonunun dikkatsizce kullanld programlar da gvenlik
asndan kusurludur. Yani bu tr programlar bir gvenlik kusuru (security bug veya security
aw ) barndrr.
Dediimiz gibi, program kusurlar ok boyutlu olup, burada anlattmzdan ok daha
karmaktr.
Gelelim nc kategori olan istisnalara (exceptions )...
stisnalar, adndan da az ok anlalaca gibi, bir programn almas srasnda ortaya kan,
normalden farkl, istisnai durumlardr. rnein u programa bakalm:
ilk_say = input("ilk say: ")
ikinci_say = input("ikinci say: ")

ilk_say = int(ilk_say)
ikinci_say = int(ikinci_say)

print(ilk_say, "/", ikinci_say, "=", ilk_say / ikinci_say)

Burada ilk sayy ikinci sayya blen bir program yazdk. Bu program her trl blme ilemini
yapabilir. Ama burada hesaba katmamz gereken iki ey var:
1. Kullanc say yerine, say deerli olmayan bir veri tipi girebilir. Mesela ilk sayya karlk
23, ikinci sayya karlk fdsfd gibi bir ey yazabilir.

15.1. Hata Trleri 215


Python 3 iin Trke Klavuz, Srm 3

2. Kullanc bir sayy 0 a blmeye alabilir. Mesela ilk sayya karlk 23, ikinci sayya
karlk 0 yazabilir.
lk durumda programmz yle bir hata verir:
ilk say: 23
ikinci say: fdsfd
Traceback (most recent call last):
File "deneme.py", line 5, in <module>
ikinci_say = int(ikinci_say)
ValueError: invalid literal for int() with base 10: 'fdsfd'

Buradaki sorun, say deerli olmayan bir verinin, int() fonksiyonu araclyla sayya
evrilmeye allyor olmas.
kinci durumda ise programmz yle bir hata verir:
ilk say: 23
ikinci say: 0
Traceback (most recent call last):
File "deneme.py", line 7, in <module>
print(ilk_say, "/", ikinci_say, "=", ilk_say / ikinci_say)
ZeroDivisionError: division by zero

Buradaki sorun ise, bir saynn 0 a blnmeye allyor olmas. Matematikte saylar 0 a
blnemez...
te bu iki rnekte grdmz ValueError ve ZeroDivisionError birer istisnadr. Yani
kullanclarn, kendilerinden say beklenirken say deerli olmayan veri girmesi veya bir sayy
0a blmeye almas istisnai birer durumdur ve yazdmz programlarn exception (istisna)
retmesine yol aar.
Bylece hata (error ), kusur (bug ) ve istisna (exception ) arasndaki farklar yle bir gzden
geirmi olduk. Yalnz burada unu sylemekte yarar var: Bu kavram arasndaki fark belli
belirsizdir. Yani bu kavramlarn ou yerde birbirlerinin yerine kullanldn da grebilirsiniz.
rnein exception kavram iin Trkede ou zaman hata kelimesini kullanyoruz. Zaten
dikkat ederseniz bu blmn bal da stisna Yakalama deil, Hata Yakalamadr. Ayn
ekilde, ngilizcede de bu kavramlarn ou yerde birbirleri yerine kullanldn grebilirsiniz.
Dolaysyla, konuya kar zel bir ilginiz yoksa, hata, kusur ve istisna kavramlarn birbirinden
ayrmak iin kendinizi zorlamanza gerek yok. Bu kavram ou zaman birbirinin yerine
kullanlyor da olsa, aslnda aralarnda baz farklar olduunu renmiseniz bu blm
amacna ulam demektir.
Konuyla ilgili temel bilgileri edindiimize gre asl meseleye geebiliriz...

15.2 try... except...

Bir nceki blmde hatalardan ve hatalar yakalamaktan sz ettik. Peki bu hatalar nasl
yakalayacaz?
Pythonda hata yakalama ilemleri iin try... except... bloklarndan yararlanlr. Hemen
bir rnek verelim:
ilk_say = input("ilk say: ")
ikinci_say = input("ikinci say: ")

216 Blm 15. Hata Yakalama


Python 3 iin Trke Klavuz, Srm 3

try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ValueError:
print("Ltfen sadece say girin!")

Biliyoruz ki, bir veriyi sayya dntrmek istediimizde eer kullanc say deerli bir
veri yerine harf deerli bir veri girerse programmz ker. Dolaysyla int(ilk_say) ve
int(ikinci_say) kodlar, kullancnn girecei veri trne gre hata retme potansiyeline
sahiptir. O yzden, burada hata vereceini bildiimiz o kodlar try blou iine aldk.
Yine bildiimiz gibi, veri dntrme ilemi srasnda kullancnn uygun olmayan bir veri
girmesi halinde retilecek hata bir ValueErrordr. Dolaysyla except blou iine yazacamz
hata trnn ad da ValueError olacaktr. O yzden ValueError adl hatay yakalayabilmek
iin u satrlar yazdk:
except ValueError:
print("Ltfen sadece say girin!")

Burada bu kodlarla Pythona u emri vermi olduk:


Eer try blou iinde belirtilen ilemler srasnda bir ValueError ile karlarsan
bunu grmezden gel ve normal artlar altnda kullancya gsterecein hata
mesajn gsterme. Onun yerine kullancya Ltfen sadece say girin!
uyarsn gster.
Yukarda Trkeye evirdiimiz emri Pythoncada nasl ifade ettiimize dikkat edin. Temel
olarak yle bir yapyla kar karyayz:
try:
hata verebileceini bildiimiz kodlar
except HataAd:
hata durumunda yaplacak ilem

Gelin isterseniz bir rnek daha verelim.


Hatrlarsanz bir saynn 0 a blnmesinin mmkn olmadn, byle bir durumda
programmzn hata vereceini sylemitik. Bu durumu teyit etmek iin etkileimli kabukta
u kodu deneyebilirsiniz:
>>> 2 / 0

Bu kod yle bir hata mesaj verecektir:


>>> 2 / 0

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero

Daha nce de sylediimiz gibi, bu hata mesajnda bizi ilgilendiren ksm ZeroDivisionError.
Demek ki bir say 0 a blndnde Python ZeroDivisionError veriyormu. O halde yle
bir kod yazabiliriz:
ilk_say = input("ilk say: ")
ikinci_say = input("ikinci say: ")

15.2. try... except... 217


Python 3 iin Trke Klavuz, Srm 3

try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ZeroDivisionError:
print("Bir sayy 0'a blemezsiniz!")

Grdnz gibi, Pythonn ZeroDivisionError vereceini bildiimiz durumlara kar bu hata


trn yakalama yoluna gidiyoruz. Bylece kullancya anlamsz ve karmak hata mesajlar
gstermek ve daha da kts, programmzn kmesine sebep olmak yerine daha anlalr
mesajlar retiyoruz.
Yukardaki kodlarda zellikle bir nokta dikkatinizi ekmi olmal: Dikkat ederseniz yukardaki
kodlar aslnda bir deil iki farkl hata retme potansiyeline sahip. Eer kullanc say deerli
veri yerine harf deerli bir veri girerse ValueError, eer bir sayy 0 a blmeye alrsa
da ZeroDivisionError hatas alyoruz. Peki ayn kodlarda iki farkl hata trn nasl
yakalayacaz?
ok basit:
ilk_say = input("ilk say: ")
ikinci_say = input("ikinci say: ")

try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ZeroDivisionError:
print("Bir sayy 0'a blemezsiniz!")
except ValueError:
print("Ltfen sadece say girin!")

Grdnz gibi zm gayet mantkl. Birden fazla hata tr reteceini bildiimiz kodlar
yine tek bir try blou iine alyoruz. Hata trlerini ise ayr except bloklar iinde ele alyoruz.
Bir program yazarken, en iyi yaklam, yukarda yaptmz gibi, her hata tr iin kullancya
ayr bir uyar mesaj gstermektir. Bylece kullanclarmz bir hatayla karlatklarnda
sorunu nasl zebilecekleri konusunda en azndan bir kir sahibi olabilirler.
Dediimiz gibi, her hata iin ayr bir mesaj gstermek en iyisidir. Ama tabii dilerseniz hata
trlerini gruplayp hepsi iin tek bir hata mesaj gstermeyi de tercih edebilirsiniz. Bunu nasl
yapacamz grelim:
ilk_say = input("ilk say: ")
ikinci_say = input("ikinci say: ")

try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except (ValueError, ZeroDivisionError):
print("Bir hata olutu!")

Grdnz gibi, burada ValueError ve ZeroDivisionError adl hata trlerini tek bir
parantez iinde topladk. Burada dikkat edeceimiz nokta, bu hata trlerini gruplarken
bunlar parantez iine almak ve birbirlerinden virglle ayrmaktr.

218 Blm 15. Hata Yakalama


Python 3 iin Trke Klavuz, Srm 3

Bu arada, grdnz gibi yukardaki programlar sadece bir kez alp kapanyor. Ama biz
bu programlar tekrar tekrar nasl altrabileceimizi gayet iyi biliyoruz:
while True:
ilk_say = input("ilk say (Programdan kmak iin q tuuna basn): ")

if ilk_say == "q":
break

ikinci_say = input("ikinci say: ")

try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except (ValueError, ZeroDivisionError):
print("Bir hata olutu!")
print("Ltfen tekrar deneyin!")

Pythonda hata yakalamann en yaygn yolu yukarda gsterdiimiz gibi kodlar try...
except bloklar iine almaktr. Programclk maceranzn byk blmnde bu yapy
kullanacaksnz. Ama bazen, kar karya olduunuz duruma veya ihtiyacnza gre try...
except bloklarnn farkl varyasyonlarn kullanmanz gerekebilir. te imdi biz de bu farkl
varyasyonlarn neler olduunu incelemeye alacaz.

15.3 try... except... as...

Bildiiniz gibi, Python bir programn almas esnasnda hata retirken ktda hata trnn
adyla birlikte ksa bir hata aklamas veriyor. Yani mesela yle bir kt retiyor:
ValueError: invalid literal for int() with base 10: 'f'

Burada ValueError hata trnn ad, invalid literal for int() with base 10: f ise hatann
aklamasdr. Eer istersek, yazdmz programda bu hata aklamasna eriebiliriz.
Dikkatlice bakn:
ilk_say = input("ilk say: ")
ikinci_say = input("ikinci say: ")

try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ValueError as hata:
print(hata)

Bu program altrp say deerli olmayan bir veri girersek hata kts yle olacaktr:
invalid literal for int() with base 10: 'f'

Grdnz gibi, bu defa ktda hata trnn ad (ValueError) grnmyor. Onun yerine
sadece hata aklamas var.
Diyelim ki kullancya olas bir hata durumunda hem kendi yazdnz hata mesajn, hem
de zgn hata mesajn gstermek istiyorsunuz. te yukardaki yap byle durumlarda ie
yarayabilir:

15.3. try... except... as... 219


Python 3 iin Trke Klavuz, Srm 3

ilk_say = input("ilk say: ")


ikinci_say = input("ikinci say: ")

try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except ValueError as hata:
print("Sadece say girin!")
print("orijinal hata mesaj: ", hata)

Bu arada, biraz nce yaptmz gibi, hata trlerini grupladnzda da bu yntemi


kullanabilirsiniz:
ilk_say = input("ilk say: ")
ikinci_say = input("ikinci say: ")

try:
say1 = int(ilk_say)
say2 = int(ikinci_say)
print(say1, "/", say2, "=", say1 / say2)
except (ValueError, ZeroDivisionError) as hata:
print("Bir hata olutu!")
print("orijinal hata mesaj: ", hata)

Burada except falancaHata as filanca yapsn kullanarak falancaHatay lanca olarak


isimlendiriyor ve daha sonra bu ismi istediimiz gibi kullanabiliyoruz. Bylece btn hata
trleri iin hem kendi yazdnz mesaj grntleyebiliyor, hem de zgn hata mesajn da
ktya eklediimiz iin, kullancya hata hakknda en azndan bir kir sahibi olma imkan
vermi oluyoruz.

15.4 try... except... else...

Daha nce de dediimiz gibi, Pythonda hata yakalama ilemleri iin ounlukla try...
except... bloklarn bilmek yeterli olacaktr. lerimizin byk ksmn sadece bu bloklar
kullanarak halledebiliriz. Ancak Python bize bu konuda, zaman zaman iimize yarayabilecek
baka aralar da sunmaktadr. te try... except... else... bloklar da bu aralardan
biridir. Bu blmde ksaca bu bloklarn ne ie yaradndan sz edeceiz.
ncelikle try... except... else... blounun ne ie yaradna bakalm. Esasnda biz
bu else deyimini daha nce de koullu ifadeler konusunu ilerken grmtk. Buradaki
kullanm da zaten hemen hemen ayndr. Diyelim ki elimizde yle bir ey var:
try:
blnen = int(input("blnecek say: "))
blen = int(input("blen say: "))
print(blnen/blen)
except ValueError:
print("hata!")

Burada eer kullanc say yerine harf girerse ValueError hatas alrz. Bu hatay except
ValueError: ifadesiyle yakalyoruz ve hata verildiinde kullancya bir mesaj gstererek
programmzn kmesini engelliyoruz. Ama biliyoruz ki, bu kodlar altrdmzda Pythonn
verebilecei tek hata ValueError deildir. Eer kullanc bir sayy 0a blmeye alrsa Python

220 Blm 15. Hata Yakalama


Python 3 iin Trke Klavuz, Srm 3

ZeroDivisionError adl hatay verecektir. Dolaysyla bu hatay da yakalamak iin yle bir
ey yazabiliriz:
try:
blnen = int(input("blnecek say: "))
blen = int(input("blen say: "))
print(blnen/blen)
except ValueError:
print("Ltfen sadece say girin!")
except ZeroDivisionError:
print("Bir sayy 0'a blemezsiniz!")

Bu ekilde hem ValueError hatasn hem de ZeroDivisionError hatasn yakalam oluruz.


Bu kodlarn zellii, except... bloklarnn tek bir try... blounu temel almasdr. Yani biz
burada btn kodlarmz tek bir try... blou iine tktryoruz. Bu blok iinde gerekleen
hatalar da daha sonra tek tek except... bloklar yardmyla yakalyoruz. Ama eer biz
istersek bu kodlarda verilebilecek hatalar gruplamay da tercih edebiliriz:
try:
blnen = int(input("blnecek say: "))
blen = int(input("blen say: "))
except ValueError:
print("Ltfen sadece say girin!")
else:
try:
print(blnen/blen)
except ZeroDivisionError:
print("Bir sayy 0'a blemezsiniz!")

Burada yaptmz ey u: lk try... except... blou yardmyla ncelikle int(input())


fonksiyonu ile kullancdan gelecek verinin say olup olmadn denetliyoruz. Ardndan
bir else... blou aarak, bunun iinde ikinci try... except... bloumuzu devreye
sokuyoruz. Burada da blme ilemini gerekletiriyoruz. Kullancnn blme ilemi srasnda
0 saysn girmesi ihtimaline kar da except ZeroDivisionError ifadesi yardmyla olas
hatay gslyoruz. Bu ekilde bir kodlamann bize getirecei avantaj, hatalar zerinde
belli bir kontrol salamamza yardmc olmasdr. Yukardaki kodlar sayesinde hatalara bir
nevi teker teker gelin! mesaj vermi oluyoruz. Bylelikle her blok iinde sadece almay
beklediimiz hatay karlyoruz. Mesela yukarda ilk try... blou iindeki dntrme ilemi
yalnzca ValueError hatas verebilir. else: bloundan sonraki try... blounda yer alan
ilem ise ancak ZeroDivisionError verecektir. Biz yukarda kullandmz yap sayesinde
her bir hatay tek tek ve yeri geldiinde karlyoruz. Bu durumun aksine, blmn ilk
banda verdiimiz try... except blounda hem ValueError hem de ZeroDivisionError
hatalarnn gerekleme ihtimali bulunuyor. Dolaysyla biz orada btn hatalar tek bir
try... blou iine sktrm oluyoruz. te else: blou bu skkl gidermi oluyor. Ancak
sizi bir konuda uyarmak isterim: Bu yap, her akla geldiinde kullanlacak bir yap deildir.
Byk programlarda bu tarz bir kullanm kodlarnzn darmadan olmasna, kodlarnz
zerindeki denetimi tamamen kaybetmenize de yol aabilir. Sonunda da elinizde blk
prk bir kod yn kalabilir. Zaten aka sylemek gerekirse try... except... else...
yapsnn ok geni bir kullanm alan yoktur. Bu yap ancak ok nadir durumlarda kullanlmay
gerektirebilir. Dolaysyla bu l yapy hi kullanmadan bir mr rahatlkla geirebilirsiniz.

15.4. try... except... else... 221


Python 3 iin Trke Klavuz, Srm 3

15.5 try... except... nally...

try... except... else... yaplarnn dnda, Pythonn bize sunduu bir baka yap da
try... except... finally... yaplardr. Bunu yle kullanyoruz:
try:
...bir takm iler...
except birHata:
...hata alnnca yaplacak ilemler...
finally:
...hata olsa da olmasa da yaplmas gerekenler...

finally.. blounun en nemli zellii, programn almas srasnda herhangi bir hata
gereklese de gereklemese de iletilecek olmasdr. Eer yazdnz programda mutlaka
ama mutlaka iletilmesi gereken bir ksm varsa, o ksm finally... blou iine yazabilirsiniz.
finally... blou zellikle dosya ilemlerinde iimize yarayabilir. Henz Pythonda
dosyalarla nasl alacamz renmedik, ama ben imdilik size en azndan dosyalarla
alma prensibi hakknda bir eyler syleyeyim.
Genel olarak Pythonda dosyalarla alabilmek iin ncelikle bilgisayarda bulunan bir dosyay
okuma veya yazma kipinde aarz. Dosyay atktan sonra bu dosyayla ihtiyacmz olan
birtakm ilemler gerekletiririz. Dosyayla iimiz bittikten sonra ise dosyamz mutlaka
kapatmamz gerekir. Ancak eer dosya zerinde ilem yaplrken bir hata ile karlalrsa
dosyamz kapatma ilemini gerekletirdiimiz blme hi ulalamayabilir. te finally...
blou byle bir durumda iimize yarayacaktr:
try:
dosya = open("dosyaad", "r")
...burada dosyayla baz ilemler yapyoruz...
...ve anszn bir hata oluuyor...
except IOError:
print("bir hata olutu!")
finally:
dosya.close()

Burada finally... blou iine yazdmz dosya.close() ifadesi dosyamz gvenli bir
ekilde kapatmaya yaryor. Bu blok, yazdmz program hata verse de vermese de
iletilecektir.

15.6 raise

Bazen, yazdmz bir programda, kullancnn yapt bir ilem normal artlar altnda hata
vermeyecek olsa bile biz ona Python tarz bir hata mesaj gstermek isteyebiliriz. Byle
bir durumda ihtiyacmz olan ey Pythonn bize sunduu raise adl deyimdir. Bu deyim
yardmyla duruma zg hata mesajlar retebiliriz. Bir rnek verelim:
blnen = int(input("blnecek say: "))

if blnen == 23:
raise Exception("Bu programda 23 saysn grmek istemiyorum!")

blen = int(input("blen say: "))


print(blnen/blen)

222 Blm 15. Hata Yakalama


Python 3 iin Trke Klavuz, Srm 3

Burada eer kullanc 23 saysn girerse, kullancya bir hata mesaj gsterilip programdan
klacaktr. Biz bu kodlarda Exception adl genel hata mesajn kullandk. Burada Exception
yerine her istediimizi yazamayz. Yazabileceklerimiz ancak Pythonda tanml hata mesajlar
olabilir. rnein NameError, TypeError, ZeroDivisionError, IOError, vb...
Bir rnek verelim:
tr_karakter = ""

parola = input("Parolanz: ")

for i in parola:
if i in tr_karakter:
raise TypeError("Parolada Trke karakter kullanlamaz!")
else:
pass

print("Parola kabul edildi!")

Bu kodlar altrldnda, eer kullanc, iinde Trke karakter geen bir parola yazarsa
kendisine TypeError tipinde bir hata mesaj gsteriyoruz. Eer kullancnn parolas Trke
karakter iermiyorsa hibir ey yapmadan geiyoruz ve bir sonraki satrda kendisine Parola
kabul edildi! mesajn gsteriyoruz.
raise deyimini, bir hata mesajna ek olarak bir ilem yapmak istediimizde de kullanabiliriz.
rnein:
try:
blnen = int(input("blnecek say: "))
blen = int(input("blen say: "))
print(blnen/blen)
except ZeroDivisionError:
print("bir sayy 0'a blemezsiniz")
raise

Burada, eer kullanc bir sayy 0 a blmeye alrsa, normal bir ekilde ZeroDivisionError
hatas verilecek ve programdan klacaktr. Ama bu hata mesajyla birlikte kullancya bir
sayy 0a blemezsiniz, uyarsn da gsterme imkann elde edeceiz. Yani burada except
ZeroDivisionError blounu herhangi bir hatay engellemek iin deil, hataya ilave bilgi
eklemek iin kullanyoruz. Bunu yapmamz salayan ey tabii ki bu kodlar iinde grnen
raise adl deyimdir...

15.7 Btn Hatalar Yakalamak

imdiye kadar yaptmz btn rneklerde except... blounu bir hata mesaj adyla birlikte
kullandk. Yani rneklerimiz una benziyordu:
try:
....birtakm iler...
except ZeroDivisionError:
...hata mesaj...

Yukardaki kod yardmyla sadece ZeroDivisionError adl hatay yakalayabiliriz. Eer


yazdmz program baka bir hata daha veriyorsa, o hata mesaj yukardaki bloklarn kapsam

15.7. Btn Hatalar Yakalamak 223


Python 3 iin Trke Klavuz, Srm 3

dnda kalacaktr. Ama eer istersek yukardaki kodu u ekilde yazarak olas btn hatalar
yakalayabiliriz:
try:
....birtakm iler...
except:
...hata mesaj...

Grdnz gibi, burada herhangi bir hata ad belirtmedik. Bylece Python, yazdmz
programda hangi hata oluursa olusun hepsini yakalayabilecektir.
Bu yntem gznze ok pratik grnm olabilir, ama aslnda hi de yle saylmaz. Hatta
olduka kt bir yntem olduunu syleyebiliriz bunun. nk bu tarz bir kod yazmnn
baz dezavantajlar vardr. rnein bu ekilde btn hata mesajlarn ayn kefeye koyarsak,
programmzda ne tr bir hata oluursa olusun, kullancya hep ayn mesaj gstermek
zorunda kalacaz. Bu da, herhangi bir hata durumunda kullancy ne yapmas gerektii
konusunda doru dzgn bilgilendiremeyeceimiz anlamna geliyor. Yani kullanc bir hataya
sebep olduunda tersliin nereden kaynaklandn tam olarak kestiremeyecektir.
Ayrca, eer kendimiz bir program gelitirirken srekli olarak bu tarz bir yazm benimsersek,
kendi kodlarmzdaki hatalar da maskelemi oluruz. Dolaysyla, Python yukardaki geni
kapsaml except... blou nedeniyle programmzdaki btn hatalar gizleyecei iin,
programmzdaki potansiyel aksaklklar grme imkanmz olmaz. Dolaysyla bu tr bir
yapdan olabildiince kanmakta fayda var. Ancak elbette byle bir kod yazmanz gerektiren
bir durumla da karlaabilirsiniz. rnein:
try:
birtakm kodlar
except ValueError:
print("Yanl deer")
except ZeroDivisionError:
print("Sfra blme hatas")
except:
print("Beklenmeyen bir hata olutu!")

Burada olas btn hata trlerini yakaladktan sonra, bunlarn dnda bizim o anda
ngremediimiz bir hatann olumas ihtimaline kar except: kodunu kullanarak
kullancya genel bir hata mesaj gstermeyi tercih edebiliriz. Bylece beklenmeyen bir hata
meydana gelmesi durumunda da programmz kmek yerine almaya devam edebilecektir.

15.8 rnek Uygulama

Hata yakalama konusunu btn ayrntlaryla inceledik. Gelin imdi isterseniz ufak bir rnek
yapalm.
Hatrlarsanz bir ka blm nce yle bir uygulama yazmtk:
import sys

_2x_metni = """
Python'n 2.x srmlerinden birini kullanyorsunuz.
Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal."""

_3x_metni = "Programa hogeldiniz."

224 Blm 15. Hata Yakalama


Python 3 iin Trke Klavuz, Srm 3

if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)

Bu programn ne i yaptn biliyorsunuz. Bu program yardmyla, kullanclarmzn


bilgisayarlarndaki Python srmn kontrol edip, programmzn kullanlan srme gre
tepki vermesini salyoruz.
Ancak burada ok ciddi bir problem var. Pythonn 2.7 ncesi srmlerinde sys modlnn
version_info() metodu farkl ktlar verir. Mesela Pythonn 2.7 ncesi srmlerinde
version_info() metodunun major, minor veya micro gibi nitelikleri bulunmaz. Bu
nitelikler Python programlama diline 2.7 srmyle birlikte geldi. Dolaysyla yukardaki
program Pythonn 2.7 ncesi srmlerinden biriyle altran kullanclarnz istediiniz kty
alamayacak, Python bu kullancalara una benzer bir hata mesaj gstererek programn
kmesine sebep olacaktr:
AttributeError: 'tuple' object has no attribute 'major'

Pythonn 2.7 ncesi srmlerinin kurulu olduu bilgisayarlarda da programnzn en azndan


kmemesi ve makul bir kt verebilmesi iin yukardaki kodlar yle yazabilirsiniz:
import sys

_2x_metni = """
Python'n 2.x srmlerinden birini kullanyorsunuz.
Program altrabilmek iin sisteminizde Python'n
3.x srmlerinden biri kurulu olmal."""

_3x_metni = "Programa hogeldiniz."

try:
if sys.version_info.major < 3:
print(_2x_metni)
else:
print(_3x_metni)
except AttributeError:
print(_2x_metni)

Grdnz gibi, AttributeError adl hatay vereceini bildiimiz ksm bir try... except
blou iine aldk. Eer programmz AttributeError hatasn veriyorsa, programmzn
altrld sistem Pythonn 2.7 srmnden daha dk bir srm kullanyor demektir.
O yzden kullancya _2x_metni ni gsteriyoruz.
Elbette yukardaki program yazmann ok daha dzgn yollar vardr. Ama biz hata yakalama
yntemlerinin buna benzer durumlarda da bir alternatif olarak kullanlabileceini bilelim.
Ayrca, dediimiz gibi, try... except bloklar yukardaki sorunun zm iin en uygun
aralar olmasa da, baz durumlarda hatay nlemenin makul tek yoludur.

15.8. rnek Uygulama 225


BLM 16

Karakter Dizileri

Buraya gelene kadar Python programlama diline ilikin epey bilgi edindik. Artk yazdmz
programlarda input() fonksiyonu sayesinde kullancyla iletiim kurabiliyor; if, elif, else
deyimleri yardmyla programlarmzn karar vermesini salayabiliyor; ileler ve dngler
yoluyla programlarmz istediimiz sayda altrabiliyoruz. Eer buraya kadar olan
blmleri dikkatlice takip ettiyseniz, u ana kadar rendiklerinize dayanarak, Python
giri dzeyinde bildiinizi rahatlkla iddia edebilirsiniz. Zira imdiye kadar rendiklerinizi
kullanarak ufak tefek de olsa ie yarar programlar yazabilecek durumdasnz.
Buraya kadar rendiimiz bilgiler Python programlama dilinin temellerini oluturuyordu.
Temel Python bilgilerini edindiimize gre, artk balang-orta dzey aras konular
incelemeye balayabileceiz.
Bu blmde, nceki derslerde stnkr bakp getiimiz bir konu olan karakter dizilerini
ok daha derinlemesine ele alacaz. Python programlama dili iindeki nemi nedeniyle bu
blm epey uzun olacak.
Aslnda biz karakter dizisi kavramnn ne olduunu biliyoruz. ok kaba bir ekilde ifade etmek
gerekirse, karakter dizileri, adndan da anlalaca gibi, karakterlerin bir araya gelmesiyle
oluan bir dizidir. Karakter dizileri; tek, ift veya trnak iinde gsterilen, teki veri
tiplerinden de bu trnaklar araclyla ayrt edilen zel bir veri tipidir. Teknik olarak ifade
etmek gerekirse, bir nesneyi type() fonksiyonu yardmyla sorguladmzda, eer <class str>
kts alyorsak bu nesne bir karakter dizisidir.
Her ne kadar ayrntlarna girmemi de olsak, dediimiz gibi, biz karakter dizilerini daha
ilk blmlerden bu yana her frsatta kullanyoruz. Dolaysyla bu veri tipinin ne olduu
konusunda bir skntmz yok. Bu blmde, imdiye kadar karakter dizileri ile ilgili
rendiimiz eylere ek olarak, karakter dizilerin metotlarndan da sz edeceiz.
Peki bu metot denen ey de ne oluyor?
Kabaca ifade etmek gerekirse, metotlar Pythonda nesnelerin niteliklerini deitirmemizi,
sorgulamamz veya bu nesnelere yeni zellikler katmamz salayan aralardr. Metotlar
sayesinde karakter dizilerini istediimiz gibi eip bkebileceiz.
Elbette bu blmde bahsedeceimiz tek ey karakter dizilerinin metotlar olmayacak. Bu
blmde ayn zamanda karakter dizilerinin yaps ve zelliklerine dair syleyeceklerimiz de
olacak.
Pythonda imdiye kadar yapabildiimiz eylerin sizi tatmin etmekten uzak olduunu, daha
fazlasn yapabilmek iin sabrszlandnz tahmin edebiliyorum. O halde ne duruyoruz, hi
vakit kaybetmeden yola koyulalm.

226
Python 3 iin Trke Klavuz, Srm 3

16.1 Karakter Dizilerinin elerine Erimek

Python ile programlama yaparken karakter dizileri ile iki ekilde karlaabilirsiniz: Birincisi,
bir karakter dizisini dorudan kendiniz tanmlam olabilirsiniz. kincisi, karakter dizisi
size baka bir kaynak araclyla gelmi olabilir (mesela input() fonksiyonu yardmyla
kullancdan aldnz bir veri).
Pythonda kendi tanmladnz ya da herhangi baka bir kaynaktan gelen karakter dizilerine
erimenin birka farkl yolu vardr. rnein:
>>> nesne = "karakter dizisi"

Burada deeri karakter dizisi olan nesne adl bir deiken tanmladk. Yazdmz
programlarda bu deikene erimek iin, deikenin adn kullanmamz yeterlidir. rnein:
>>> print(nesne)

Bu komut bize karakter dizisinin tamamn verecektir.


Bir karakter dizisini yukarda grdmz gibi kendimiz tanmlayabiliriz. Bunun dnda,
mesela input() fonksiyonuyla kullancdan aldmz verilerin de birer karakter dizisi olacan
biliyoruz:
veri = input("Herhangi bir ey: ")

Tpk kendi tanmladmz karakter dizilerinde olduu gibi, kullancdan gelen karakter
dizilerini de aadaki komut yardmyla ekranda grntleyebiliriz:
print(veri)

Bu komut da bize veri deikeninin tuttuu karakter dizisinin tamamn verecektir.


Ayrca istersek bu karakter dizilerini bir for dngs iine alabilir, bylece bu dizinin
elerine tek tek de eriebiliriz:
for karakter in nesne:
print(karakter)

for dngsyle elde ettiimiz bu etkiyi u kodlar yardmyla da elde edebileceimizi gayet iyi
biliyor olmalsnz:
print(*nesne, sep="\n")

nceki derslerde verdiimiz rneklerden de bildiiniz gibi, karakter dizilerinin elerine


yukardaki yntemlerle tek tek eriebilmemiz sayesinde herhangi bir ilemi karakter
dizilerinin btn elerine bir rpda uygulayabiliyoruz. Mesela:
nesne = "123456789"

for n in nesne:
print(int(n) * 2)

Burada nesne deikeni iindeki say deerli karakter dizilerini n olarak adlandrdktan sonra,
n deikenlerinin her birini tek tek 2 says ile arptk. Yani arpma ilemini karakter
dizisinin btn elerine tek seferde uygulayabildik. Bu arada, yukardaki rnekte nesne
deikeninin her bir esini for dngs iinde int() fonksiyonu yardmyla tam sayya
evirdiimizi gryorsunuz. Daha nce de defalarca sylediimiz gibi, Pythonda o anda

16.1. Karakter Dizilerinin elerine Erimek 227


Python 3 iin Trke Klavuz, Srm 3

elinizde olan verinin tipini bilmeniz ok nemlidir. Eer kendi yazdnz veya mesela input()
fonksiyonundan gelen bir verinin karakter dizisi olduunu bilmezseniz yukardaki kodlar u
ekilde yazma gaetine debilirsiniz:
nesne = "123456789"

for n in nesne:
print(n * 2)

Bu kodlar altrldktan sonra hi beklemediiniz sonular verecektir:


11
22
33
44
55
66
77
88
99

Grdnz gibi, aslnda nesne iindeki eleri 2 ile arpmak isterken, biz her bir eyi
iki kez ekrana yazdrm olduk. nk bildiiniz gibi karakter dizileri ile aritmetik ilemler
yapamyoruz. Eer say deerli karakter dizileri arasnda aritmetik ilem yapacaksak
ncelikle bu karakter dizilerini sayya evirmemiz gerekir. Ayrca gerek bir program iinde
yukardaki gibi bir durumun ne kadar ykc sonular douracabileceini dnn. Yukardaki
program alma srasnda hibir hata vermeyecei iin, siz programnzn dzgn altn
zannederek hayatnza devam edeceksiniz. Ama belki de yukardaki sinsi hata yznden,
programnz kullanan bir irket veri, zaman ve para kaybna urayacak.
Yukardaki rneklerde bir ey daha dikkatinizi ekmi olmal: Grdnz gibi, karakter
dizisinin elerine eriirken bu elerin tamamn elde ediyoruz. Mesela print(nesne)
komutunu verdiimizde veya nesne deikenini bir dng iine aldmzda sonu olarak elde
ettiimiz ey, ilgili karakter dizisinin tamamdr. Yani aslnda karakter dizisinin hangi esine
erieceimizi seemiyoruz. Peki ya biz bir karakter dizisinin elerinin tamamna deil de,
sadece tek bir esine erimek istersek ne yapacaz? Mesela yukardaki rnekte nesne adl
deiken iindeki saylarn tamamn deil de sadece tek bir esini (veya belli bir lte gre
yalnzca baz elerini) 2 ile arpmak istersek nasl bir yol izleyeceiz?
Pythonda karakter dizilerinin iindeki elerin bir sras vardr. rnein Python
dediimizde, bu karakter dizisinin ilk esi olan P karakterinin sras 0 dr. y karakteri
ise 1. sradadr. Ayn ekilde devam edersek, t karakteri 2., h karakteri 3., o karakteri 4.,
n karakteri ise 5. srada yer alr.
Bu anlattmz soyut durumu bir rnekle somutlatrmaya alalm:
Dedik ki, Python gibi bir karakter dizisinin her bir esinin belli bir sras vardr. te eer
biz bu karakter dizisinin btn elerini deil de, sadece belli karakterlerini almak istersek,
karakter dizisindeki elerin sahip olduu bu sradan yararlanacaz.
Diyelim ki Python karakter dizisinin ilk karakterini almak istiyoruz. Yani biz bu karakter
dizisinin sadece P harne ulamay amalyoruz.
Bu isteimizi nasl yerine getirebileceimizi basit bir rnek zerinde gstermeye alalm:
>>> kardiz = "Python"

228 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

Burada deeri Python olan kardiz adl bir deiken tanmladk. imdi bu karakter dizisinin
ilk esine erieceiz:
>>> kardiz[0]

'P'

Burada yaptmz ileme ok dikkat edin. Karakter dizisinin istediimiz bir esine ulamak
iin, ilgili enin srasn keli parantezler iinde belirttik. Biz bu rnekte karakter dizisinin
ilk esine ulamak istediimiz iin keli parantez iinde 0 saysn kullandk.
imdi de, ilk verdiimiz rnekteki nesne deikeni iinde yer alan saylar arasndan sadece
birini 2 ile arpmak istediimizi dnelim:
>>> nesne = "123456789"
>>> int(nesne[1]) * 2

Burada da ncelikle nesne deikeninin birinci srasnda yer alan eyi (dikkat: sfrnc srada
yer alan eyi deil!) elde etmek iin keli parantezler iinde 1 saysn kullandk. Daha sonra
int() fonksiyonu yardmyla bu karakter dizisini tam sayya evirdik, ki bununla aritmetik
ilem yapabilelim... Son olarak da elimizdeki tam sayy 2 ile arparak istediimiz sonuca
ulatk.
Elbette yukardaki kodlar yle de yazabilirdik:
>>> nesne = "123456789"
>>> say = int(nesne[1])
>>> say * 2

Belki farkndasnz, belki de deilsiniz, ama aslnda u noktada karakter dizilerinin ok nemli
bir zellii ile kar karyayz. Grdnz gibi, yukarda bahsettiimiz sra kavram sayesinde
Pythonda karakter dizilerinin btn elerine tek tek ve herhangi bir sra gzetmeksizin
erimemiz mmkn. Mesela yukardaki ilk rnekte kardiz[0] gibi bir yap kullanarak karakter
dizisinin sfrnc (yani ilk) esini, nesne[1] gibi bir yap kullanarak da karakter dizisinin birinci
(yani aslnda ikinci) esini alabildik.
Bu yapnn mantn kavramak iin u rnekleri dikkatlice inceleyin:
>>> kardiz = "Python"

>>> kardiz[0]

'P'

>>> kardiz[1]

'y'

>>> kardiz[3]

'h'

>>> kardiz[5]

16.1. Karakter Dizilerinin elerine Erimek 229


Python 3 iin Trke Klavuz, Srm 3

'n'

>>> kardiz[2]

't'

>>> kardiz[4]

'o'

>>> nesne = "123456789"

>>> nesne[0]

'1'

>>> nesne[1]

'2'

>>> nesne[2]

'3'

>>> nesne[3]

'4'

>>> nesne[4]

'5'

>>> nesne[5]

'6'

>>> nesne[6]

'7'

>>> nesne[7]

'8'

>>> nesne[8]

'9'

Burada yle bir forml yazabiliriz:


karakter_dizisi[e_sras]

Bu forml uygulayarak karakter dizilerinin her bir esine tek tek erimemiz mmkn.
Burada ok nemli bir noktaya daha dikkatinizi ekmek isterim. Yukardaki rneklerden
de grdnz gibi, Pythonda e sralamas 0 dan balyor. Yani bir karakter dizisinin ilk
esinin sras 0 oluyor. Python programlama dilini zellikle yeni renenlerin en sk yapt
hatalardan biri de bir karakter dizisinin ilk esine ulamak iin 1 saysn kullanmalardr.

230 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

Asla unutmayn, Python saymaya her zaman 0 dan balar. Dolaysyla bir karakter dizisinin
ilk esinin sras 0 dr. Eer ilk eye ulaaym derken 1 saysn kullanrsanz ulatnz e
ilk e deil, ikinci e olacaktr. Bu ayrnty gzden karmamaya dikkat etmelisiniz.
Karakter dizilerinin elerine tek tek eriirken dikkat etmemiz gereken nemli noktalardan
biri de, e sras belirtirken, karakter dizisinin toplam uzunluu dna kmamaktr. Yani
mesela 7 karakterlik bir karakter dizimiz varsa, bu karakter dizisinin son esinin sras 6
olacaktr. nk biliyorsunuz, Python saymaya 0 dan balyor. Dolaysyla ilk karakterin sras
0 olaca iin, 7 karakterlik bir karakter dizisinde son enin sras 6 olacaktr. rnein:
>>> kardiz = "istihza"
>>> len(kardiz)

Grdnz gibi, istihza adl karakter dizisinin uzunluu 7. Yani bu karakter dizisi iinde 7
adet karakter var. Bu karakter dizisini incelemeye devam edelim:
>>> kardiz[0]

'i'

Dediimiz gibi, karakter dizisinin ilk esinin sras 0. Dolaysyla son enin sras 6 olacaktr:
>>> kardiz[6]

'a'

Bu durumu yle formle edebiliriz:


>>> kardiz[len(kardiz)-1]

Yani;
Bir karakter dizisinin uzunluunun 1 eksii, o karakter dizisinin son esini verir.
Yukardaki forml eer yle yazsaydk hata alrdk:
>>> kardiz[len(kardiz)]

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
IndexError: string index out of range

nk len(kardiz) kodu bize karakter dizisinin uzunluunu veriyor. Yani yukardaki istihza
karakter dizisini gz nne alrsak, len(kardiz) kts 7 olacaktr. Dolaysyla istihza
karakter dizisinin son esine ulamak istersek bu deerin 1 eksiini almamz gerekiyor. Yani
len(kardiz)-1.
u ana kadar e sras olarak hep art deerli saylar kullandk. Ancak istersek e sras
olarak eksi deerli saylar da kullanabiliriz. Eer bir karakter dizisine e sras olarak eksi
deerli bir say verirsek Python o karakter dizisini sondan baa doru okumaya balayacaktr.
Yani:
>>> kardiz[-1]

'a'

16.1. Karakter Dizilerinin elerine Erimek 231


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi -1 says karakter dizisini tersten okuyup, sondan baa doru ilk eyi
veriyor. Dolaysyla, yukarda anlattmz len(kardiz)-1 ynteminin yansra, -1 saysn
kullanarak da karakter dizilerinin son karakterini elde edebiliyoruz. Bir de una bakalm:
>>> kardiz[-2]

'z'

Dediimiz gibi, eksi deerli saylar karakter dizisindeki karakterleri sondan baa doru
elde etmemizi salar. Dolaysyla -2 says, karakter dizisinde sondan bir nceki karakteri
verecektir.
Karakter dizilerinin elerine tek tek erimek amacyla e sras belirtirken, karakter
dizisinin toplam uzunluu dna kmamamz gerektiini sylemitik. Peki karakter dizisinin
uzunluunu aan bir say verirsek ne olur? Ne olacan yukardaki rneklerden birinde
grmtk aslnda. Ama konunun neminden dolay bir kez daha tekrar edelim.
>>> kardiz = "istihza"
>>> kardiz[7]

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
IndexError: string index out of range

...veya:
>>> kardiz[-8]

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
IndexError: string index out of range

Eer karakter dizisinin uzunluunu aan bir say belirtirsek Python bize IndexError trnde
bir hata mesaj verecektir.
Grdnz gibi, kardiz[0], kardiz[1], kardiz[2], vb. komutlarla karakter dizisinin
elerine eriebiliyoruz. Burada e sralarn tek tek yazmak yerine range() fonksiyonunu
kullanarak da elere tek tek eriebilirsiniz:
for i in range(7):
print(kardiz[i])

Bu kodlarda, kardiz[0], kardiz[1], kardiz[2] eklinde e sralarn tek tek elle yazmak
yerine, range(7) aralndaki saylar bir for dngsne alyoruz. Bylece Python
kardiz[e_sras] gibi bir yap iinde e_sras yerine range(7) aralndaki btn saylar
(yani 0, 1, 2, 3, 4, 5, 6 saylarn) tek tek uyguluyor.
Burada aklnza hemen yle bir soru gelmi olabilir:
Biz kendi tanmladmz karakter dizisinin uzunluunun toplam 7 karakter
olduunu bildiimiz iin yukardaki rnekte range() fonksiyonunu range(7)
eklinde kullanabildik. Ama baka kaynaktan gelen bir karakter dizisinin
uzunluunu nasl bileceiz?
Aslnda bu sorunun cevab ok basit. Uzunluunu bilmediiniz karakter dizileri iin range()
fonksiyonuyla birlikte len() fonksiyonundan yararlanabilirsiniz. Nasl m? Hemen bir rnek
verelim:

232 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

for karakter in range(len(kardiz)):


print(kardiz[karakter])

Burada range() fonksiyonuna verdiimiz len(kardiz) parametresine dikkatlice bakn. Biz


kardiz adl deikenin tuttuu karakter dizisinin 7 karakterden olutuunu biliyoruz. Ama
eer bu karakter dizisini biz belirlememisek, karakter dizisinin tam olarak ka karakterden
oluacan bilemeyiz. Bu kodlarda len(kardiz) ifadesini kullanarak, sabit bir deer
belirlemekten kanm oluyoruz. Bylece, mesela kullancdan aldmz bir karakter dizisinin
ka karakterden olutuunu belirleme grevini Pythona brakm oluyoruz. Karakter dizisinin
uzunluu ne ise (len(kardiz)), Python range() fonksiyonuna o sayy parametre olarak
kendisi atayacaktr.
Yukardaki durumu daha iyi anlayabilmek iin bir rnek daha verelim. Diyelim ki kullancya
ismini sorup, kendisine yle bir kt vermek istiyorsunuz:
isminizin 1. harfi ...
isminizin 2. harfi ...
isminizin 3. harfi ...
...

Bunu yapabilmek iin yle bir uygulama yazabilirsiniz:


isim = input("isminiz: ")

for i in range(len(isim)):
print("isminizin {}. harfi: {}".format(i, isim[i]))

Grdnz gibi, kullancnn girdii kelimenin uzunluu ka ise o say otomatik olarak
range() fonksiyonuna atanyor. Diyelim ki kullanc Ferhat ismini girmi olsun. Bu kelimede
toplam 6 karakter var. Dolaysyla Python for satrn yle yorumlayacaktr:
for i in range(6):
...

Python for dngsnn ilk turunda yle bir ilem gerekletirir:


print("isminizin {}. harfi: {}".format(0, isim[0]))

kinci turda ise yle bir ilem:


print("isminizin {}. harfi: {}".format(1, isim[1]))

Bu dng 6 saysna gelene


kadar devam eder. Burada i
adl deikenin deerinin her
dngde nasl deitiine
dikkat edin. Python i adn
verdiimiz deikene, for
dngsnn her turunda
srasya 0, 1, 2, 3, 4 ve
5 saylarn atayaca iin
isim adl deikenin eleri
isim[e_sras] forml
sayesinde tek tek ekrana
dklecektir.

Figure 16.1: Annenizin kzlk soyadnn 0. har [kaynak]


16.1. Karakter Dizilerinin elerine Erimek 233
Python 3 iin Trke Klavuz, Srm 3

Yalnz bu kodlarn ktsnda


iki nokta dikkatinizi ekmi
olmal. Birincisi, isminizin 0.
har f gibi bir kty kullanclarnz yadrgayabilir. nk 0. harf ok yapay duran bir ifade.
Onun yerine ilk har 1. harf olarak adlandrmamz ok daha mantkl olacaktr. Bunun iin
kodlarnza u basit eklemeyi yapabilirsiniz:
isim = input("isminiz: ")

for i in range(len(isim)):
print("isminizin {}. harfi: {}".format(i+1, isim[i]))

Burada ilk i deikeninin deerini 1 say artrdk. Bylece 0 says 1 e, 1 says 2 ye, 2
says 3 e... dnm oldu. Bu ekilde kullanclarnza ok daha doal grnen bir kt
verebilmi oluyorsunuz. Eer bu ilemi yapmazsanz, kullanclarnzn doal grnmeyen
bir kt almalarnn yansra, programnzn verdii kt kimi durumlarda epey yanltc da
olabilir...

16.2 Karakter Dizilerini Dilimlemek

Bir nceki blmde bir karakter dizisinin istediimiz esini, o enin srasn belirterek
nasl elde edebileceimizi grdk. Bu blmde de benzer bir ey yapacaz. Ama burada
yapacamz ey, bir nceki blmde yaptmz ileme gre biraz daha kapsaml bir ilem
olacak.
Bu blmde karakter dizilerini dilimlemekten sz edeceiz. Peki dilimlemek derken neyi
kastediyoruz? Aslnda burada gerek anlamda karpuz gibi dilimlemekten sz ediyoruz... u
rnek, ne demek istediimizi daha net ortaya koyacaktr:
>>> site = "www.istihza.com"
>>> site[4:11]

'istihza'

>>> site[12:16]

'com'

>>> site[0:3]

'www'

Grdnz gibi, karakter dizisine keli parantez iinde baz deerler vererek bu karakter
dizisini dilim dilim ayrdk. Peki bunu nasl yaptk? Yukardaki rneklerde yle bir yap
gzmze arpyor:
karakter_dizisi[alnacak_ilk_enin_sras:alnacak_son_enin_srasnn_bir_fazlas]

Bu forml ok basit bir rnee uygulayalm:


>>> karakter_dizisi = "istanbul"
>>> karakter_dizisi[0:3]

'ist'

234 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

Burada alacamz ilk enin sra numaras 0. Yani istanbul karakter dizisindeki i har.
Alacamz son enin sra numarasnn 1 fazlas ise 3. Yani 2. sradaki t har. te
karakter_dizisi[0:3] dediimizde, Python 0. e ile 3. e arasnda kalan btn eleri
bize verecektir. Bizim rneimizde bu aralktaki eler i, s ve t hareri. Dolaysyla Python
bize istanbul kelimesindeki ist ksmn dilimleyip veriyor.
Bu bilgileri kullanarak yle bir uygulama yazalm:
site1 = "www.google.com"
site2 = "www.istihza.com"
site3 = "www.yahoo.com"
site4 = "www.gnu.org"

for isim in site1, site2, site3, site4:


print("site: ", isim[4:-4])

Bu rnek Pythonda dilimleme ilemlerinin yaps ve zellikleri hakknda bize epey bilgi
veriyor. Grdnz gibi, hem art hem de eksi deerli saylar kullanabiliyoruz. nceki
blmden hatrlayacanz gibi, eer verilen say eksi deerliyse Python karakter dizisini
sadan sola (yani sondan baa doru) okuyacaktr. Yukardaki rnekte isim[4:-4] yapsn
kullanarak, site1, site2, site3, site4 adl karakter dizilerini, ilk drt ve son drt karakterler
hari olacak ekilde dilimledik. Bylece elimizde ilk drt ve son drt karakter arasndaki btn
karakterler kalm oldu. Yani google, istihza, yahoo ve gnu.
Btn bu anlattklarmz daha iyi anlayabilmek iin bir rnek daha verelim:
ata1 = "Akll bizi arayp sormaz deli bacadan akar!"
ata2 = "Aa gl olunca kul sulu olur!"
ata3 = "Avc ne kadar hile bilirse ay da o kadar yol bilir!"
ata4 = "Lafla pilav pise deniz kadar ya benden!"
ata5 = "Zenginin gnl oluncaya kadar fukarann can kar!"

Burada be adet atasz verdik. Bizim grevimiz, bu ataszlerinin sonunda bulunan nlem
iaretlerini ortadan kaldrmak:
for ata in ata1, ata2, ata3, ata4, ata5:
print(ata[0:-1])

Burada yaptmz ey u: ata1, ata2, ata3, ata4 ve ata5 adl deikenlerin her birini ata
olarak adlandrdktan sonra ata adl deikenin en bandan en sonuna kadar olan ksm
dilimleyip aldk. Yani ata[0] ile ata[-1] arasnda kalan btn karakterleri elde etmi olduk.
Peki bu nlem iaretlerini kaldrdktan sonra bunlarn yerine birer nokta koymak istersek ne
yapacaz?
O da ok basit bir ilem:
for ata in ata1, ata2, ata3, ata4, ata5:
print(ata[0:-1] + ".")

Grdnz gibi, son karakter olan nlem iaretini attktan sonra onun yerine bir nokta
iareti koymak iin yaptmz tek ey, dilimlediimiz karakter dizisine, art iareti (+ )
yardmyla bir . karakteri eklemekten ibarettir.
Bylece karakter dizilerini nasl dilimleyeceimizi renmi olduk. Bu konuyu kapatmadan
nce dilimlemeye ilikin baz ayrntlardan sz edelim. Diyelim ki elimizde yle bir karakter
dizisi var:

16.2. Karakter Dizilerini Dilimlemek 235


Python 3 iin Trke Klavuz, Srm 3

>>> kardiz = "Sana Gl Bahesi Vadetmedim"

Bu karakter dizisi iinden sadece Sana ksmn dilimlemek iin yle bir ey yazabileceimizi
biliyorsunuz:
>>> kardiz[0:4]

'Sana'

Burada 0. karakterden 4. karaktere kadar olan ksm dilimlemi oluyoruz. Python bize bu
tr durumlarda yle bir kolaylk salar: Eer karakter dizisi iinden alnan ilk karakterin
srasn gsteren say 0 ise, bu sayy belirtmesek de olur. Yani kardiz[0:4] kodunu yle
de yazabiliriz:
>>> kardiz[:4]

'Sana'

Grdnz gibi, ilk sra saysn yazmazsak Python ilk sayy 0 kabul ediyor.
imdi de ayn karakter dizisi iindeki Vadetmedim ksmn dilimlemeye alalm:
>>> kardiz[17:27]

'Vadetmedim'

Burada da 17. karakter ile 27. karakter arasnda kalan btn karakterleri dilimledik. Tpk,
alacamz ilk karakterin sras 0 olduunda bu sayy belirtmemize gerek olmad gibi,
alacamz son karakterin sras karakter dizisinin sonuncu karakterine denk geliyorsa o sayy
da yazmamza gerek yok. Yani yukardaki kardiz[17:27] kodunu yle de yazabiliriz:
>>> kardiz[17:]

'Vadetmedim'

Pythondaki bu dilimleme zelliini kullanarak karakter dizilerini istediiniz gibi eip bkebilir,
evirip evirebilirsiniz.
Pythondaki bu dilimleme yaps ilk bakta gznze biraz karmakm gibi grnebilir. Ama
aslnda hi de yle deildir. Bu yapnn mantn bir kez kavradktan sonra kodlarnz hatasz
bir ekilde yazabilirsiniz.
Dilimleme yapsn daha iyi anlayabilmek iin kendi kendinize baz denemeler yapmanz
tavsiye ederim. Bu yapnn nasl altn anlamann en iyi yolu bol bol rnek kod yazmaktr.

16.3 Karakter Dizilerini Ters evirmek

Eer amacnz bir karakter dizisini ters evirmek, yani karakter dizisi iindeki her bir eyi
tersten yazdrmaksa biraz nce rendiimiz dilimleme yntemini kullanabilirsiniz. Dikkatlice
bakn:
>>> kardiz[::-1]

'midemtedaV isehaB lG anaS'

236 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, Sana Gl Bahesi Vadetmedim adl karakter dizisi iindeki btn
karakterler sondan baa doru ekrana dizildi.
Aslnda bu komutla Pythona yle bir emir vermi oluyoruz:
kardiz deikeni iindeki btn karakterleri, en son karakterden ilk karaktere
kadar sondan baa doru tek tek ekrana yazdr!
Bildiiniz gibi, eer almak istediimiz karakter, dizi iindeki ilk karakterse bu karakterin dizi
iindeki srasn belirtmemize gerek yok. Ayn ekilde, eer almak istediimiz karakter, dizi
iindeki son karakterse, bu karakterin de dizi iindeki srasn belirtmemize gerek yok. te
yukardaki rnekte bu kuraldan yararlandk.
Eer bir karakter dizisinin tamamnn deil de, sadece belli bir ksmnn ters evrilmi
halini elde etmek istiyorsanz elbette yapmanz gereken ey, almak istediiniz ilk ve son
karakterlerin srasn parantez iinde belirtmek olacaktr. Mesela yukardaki karakter dizisinde
sadece Gl kelimesini ters evirmek istersek yle bir ey yazabiliriz:
>>> kardiz[7:4:-1]

'lG'

Yukardaki rnek, karakter dizisi dilimlemeye ilikin olarak bize baz baka ipular da veriyor.
Grdnz gibi, keli parantez iinde toplam adet parametre kullanabiliyoruz. Yani
formlmz yle:
kardiz[ilk_karakter:son_karakter:atlama_says]

Bir rnek verelim:


>>> kardiz = "istanbul"
>>> kardiz[0:8:1]

'istanbul'

Burada istanbul adl karakter dizisinin btn elerini birer birer ekrana dktk. Bir de
una bakalm:
>>> kardiz[0:8:2]

'itnu'

Burada ise istanbul adl karakter dizisinin btn elerini ikier ikier atlayarak ekrana
dktk. Yani bir karakter yazp bir karakter atladk (istanbul).
Pythonn kurallar gereince yukardaki kodu yle yazabileceimizi de biliyorsunuz:
>>> kardiz[::2]

'itnu'

Eer karakter dizisini ters evirmek istiyorsak, yukardaki rnei eksi deerli bir atlama says
ile yazmamz gerekir:
>>> kardiz = "istanbul"
>>> kardiz[::-1]

'lubnatsi'

16.3. Karakter Dizilerini Ters evirmek 237


Python 3 iin Trke Klavuz, Srm 3

>>> kardiz[::-2]

'lbas'

Dediimiz gibi, yukardaki yntemi kullanarak karakter dizilerini ters evirebilirsiniz. Ama eer
isterseniz reversed() adl bir fonksiyondan da yararlanabiliriz.
Gelelim bu fonksiyonun nasl kullanlacana... nce yle bir deneme yapalm:
>>> reversed("Sana Gl Bahesi Vadetmedim")

<reversed object at 0x00E8E250>

Grdnz gibi, bu fonksiyonu dz bir ekilde kullandmzda bize bir reversed nesnesi
vermekle yetiniyor. Buna benzer bir olguyla range() fonksiyonunda da karlamtk:
>>> range(10)

range(0, 10)

Hatrlarsanz, range(10) gibi bir komutun ieriini grebilmek iin bu komut zerinde bir for
dngs kurmamz gerekiyordu:
for i in range(10):
print(i)

...veya:
print(*range(10))

Ayn durum reversed() fonksiyonu iin de geerlidir:


for i in reversed("Sana Gl Bahesi Vadetmedim"):
print(i, end="")

...veya:
print(*reversed("Sana Gl Bahesi Vadetmedim"), sep="")

Dilimleme veya reversed() fonksiyonunu kullanma yntemlerinden hangisi kolaynza


geliyorsa onu tercih edebilirsiniz.

16.4 Karakter Dizilerini Alfabe Srasna Dizmek

Pythonda karakter dizilerinin elerine tek tek ulama, eleri dilimleme ve ters evirmenin
yansra, bu eleri alfabe srasna dizmek de mmkndr. Bunun iin sorted() adl bir
fonksiyondan yararlanacaz:
>>> sorted("kitap")

['a', 'i', 'k', 'p', 't']

Nasl input() fonksiyonu kt olarak bir karakter dizisi ve len() fonksiyonu bir say veriyorsa,
sorted() fonksiyonu da bize kt olarak, birka blm sonra inceleyeceimiz liste adl bir veri
tipi verir.

238 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

Ama tabii eer isterseniz bu kty altnz biimde alabilirsiniz:


print(*sorted("kitap"), sep="")

...veya:
for i in sorted("kitap"):
print(i, end="")

Bir rnek daha verelim:


>>> sorted("elma")

['a', 'e', 'l', 'm']

Grdnz gibi, sorted() fonksiyonunu kullanmak ok kolay, ama aslnda bu fonksiyonun


nemli bir problemi var. Dikkatlice bakn:
>>> sorted("iek")

['e', 'i', 'k', '', '']

Burada Trke bir karakter olan harnin dzgn sralanamadn gryoruz. Bu sorun
btn Trke karakterler iin geerlidir.
Bu sorunu amak iin yle bir yntem deneyebilirsiniz:
>>> import locale
>>> locale.setlocale(locale.LC_ALL, "Turkish_Turkey.1254") #Windows iin
>>> locale.setlocale(locale.LC_ALL, "tr_TR") #GNU/Linux iin
>>> sorted("iek", key=locale.strxfrm)

['', '', 'e', 'i', 'k']

Burada locale adl bir modlden yararlandk. locale de tpk sys, os ve keyword gibi bir
modl olup, iinde pek ok deiken ve fonksiyon barndrr.
locale modl bize belli bir dilin kendine has zelliklerine gre programlama yapma
imkan verir. rnein bu modlnn iinde yer alan fonksiyonlardan biri olan setlocale()
fonksiyonunu kullanarak, programmzda ntanml dil ayarlarna uygun bir ekilde
programlama yapma olana salarz.
Bu modl ilerleyen derslerde daha ayrntl bir ekilde inceleyeceiz. O yzden locale
modln bir kenara brakp yolumuza devam edelim.
Yukardaki rnekte Trke karakterleri doru sralayabilmek iin sorted() fonksiyonunu nasl
kullandmza dikkat edin:
>>> sorted("iek", key=locale.strxfrm)

Burada sorted() metodunun key adl zel bir parametresine locale.strxfrm deerini vererek
Trkeye duyarl bir sralama yaplmasn saladk. Yukardaki yntem pek ok durumda
iinize yarar. Ancak bu yntem tek bir yerde ie yaramaz. Dikkatlice bakn:
>>> sorted("afgdhki", key=locale.strxfrm)

['a', 'd', 'f', 'g', 'h', 'i', '', 'k']

16.4. Karakter Dizilerini Alfabe Srasna Dizmek 239


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, bu yntem i harni harnden nce getiriyor. Halbuki Trk alfabesine
gre bunun tersi olmalyd. Buna benzer problemlerle ngiliz alfabesi dndaki pek ok
alfabede karlarsnz. Dolaysyla bu sadece Trkeye zg bir sorun deil.
Bu soruna kar yle bir kod da yazabilirsiniz:
>>> harfler = "abcdefghijklmnoprstuvyz"
>>> evrim = {i: harfler.index(i) for i in harfler}
>>> sorted("afgdhki", key=evrim.get)

['a', 'd', 'f', 'g', 'h', '', 'i', 'k']

Grdnz gibi burada ilk i olarak Trk alfabesindeki btn hareri harer adl bir
deikene atadk. Daha sonra ise yle bir kod yazdk:
>>> evrim = {i: harfler.index(i) for i in harfler}

Burada henz renmediimiz bir yap var, ama ne olup bittiini daha iyi anlamak iin bu
evrim deikeninin ieriini kontrol etmeyi deneyebilirsiniz:
>>> print(evrim)

{'': 8, '': 10, 'v': 26, 'g': 7, '': 22, 'a': 0, 'c': 2, 'b': 1, 'e': 5,
'd': 4, '': 3, 'f': 6, 'i': 11, 'h': 9, 'k': 13, 'j': 12, 'm': 15, 'l': 14,
'o': 17, 'n': 16, 'p': 19, 's': 21, 'r': 20, 'u': 24, 't': 23, '': 18,
'y': 27, 'z': 28, '': 25}

Bu ktya dikkatlice bakarsanz, her bir harn bir sayya karlk gelecek ekilde birbiriyle
eletirildiini greceksiniz. Mesela har 8 ile, f har 6 ile elemi. Yine dikkatlice
bakarsanz, biraz nce bize sorun karan harnin 10, i harnin ise 11 ile eletiini
greceksiniz. Evet, doru tahmin ettiniz. Hareri saylarla eletirerek, Pythonn harer
yerine saylar sralamasn salayacaz. Bunu da yine key parametresini kullanarak
yapyoruz:
>>> sorted("afgdhki", key=evrim.get)

Bu yapy daha iyi anlayabilmek iin kendi kendinize baz denemeler yapn. Eer burada
olan biteni anlamakta zorlanyorsanz hi endie etmeyin. Bir-iki blm sonra bunlar da
kolayca anlayabilecek duruma geleceksiniz. Bizim burada bu bilgileri vermekteki amacmz,
Pythonn Trke harerle sralama ilemini sorunsuz bir ekilde yapabileceini gstermektir.
Bu esnada bir-iki yeni bilgi krnts da kapmanz salayabildiysek kendimizi baarl sayacaz.

16.5 Karakter Dizileri zerinde Deiiklik Yapmak

Bu ksmda karakter dizilerinin ok nemli bir zelliinden sz edeceiz. Konumuz karakter


dizileri zerinde deiiklik yapmak. sterseniz neyle kar karya olduumuzu anlayabilmek
iin ok basit bir rnek verelim.
Elimizde yle bir karakter dizisi olduunu dnn:
>>> meyve = "elma"

Amacmz bu karakter dizisinin ilk harni bytmek olsun.


Bunun iin dilimleme ynteminden yararlanabileceimizi biliyorsunuz:

240 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

>>> "E" + meyve[1:]

'Elma'

Burada E har ile, meyve deikeninin ilk har dnda kalan btn hareri birletirdik.
Bir rnek daha verelim.
Elimizde yle drt adet internet sitesi adresi olsun:
site1 = "www.google.com"
site2 = "www.istihza.com"
site3 = "www.yahoo.com"
site4 = "www.gnu.org"

Bizim amacmz bu adreslerin her birinin ba tarafna http:// ifadesini eklemek. Bunun iin
de yine karakter dizisi birletirme ilemlerinden yararlanabiliriz. Dikkatlice inceleyin:
site1 = "www.google.com"
site2 = "www.istihza.com"
site3 = "www.yahoo.com"
site4 = "www.gnu.org"

for i in site1, site2, site3, site4:


print("http://", i, sep="")

Eer www. ksmlarn atmak isterseniz karakter dizisi birletirme ilemleri ile birlikte
dilimleme yntemini de kullanmanz gerekir:
for i in site1, site2, site3, site4:
print("http://", i[4:], sep="")

Belki farkndayz, belki de deiliz, ama aslnda yukardaki rnekler karakter dizileri hakknda
bize ok nemli bir bilgi veriyor. Dikkat ettiyseniz yukardaki rneklerde karakter dizileri
zerinde bir deiiklik yapmz gibi grnyor. Esasnda yle de denebilir. Ancak burada
nemli bir ayrnt var. Yukardaki rneklerde grdmz deiiklikler kalc deildir. Yani
aslnda bu deiikliklerin orijinal karakter dizisi zerinde hibir etkisi yoktur. Gelin isterseniz
bunu teyit edelim:
>>> kardiz = "istihza"
>>> "" + kardiz[1:]

'stihza'

Dediimiz gibi, sanki burada istihza karakter dizisini stihza karakter dizisine evirmiiz
gibi duruyor. Ama aslnda yle deil:
>>> print(kardiz)

istihza

Grdnz gibi, kardiz deikeninin orijinalinde hibir deiiklik yok. Ayrca burada ""
+ kardiz[1:] satr ile elde ettiiniz sonuca tekrar ulamanzn imkan yok. Bu deiiklik
kaybolmu durumda. Peki bunun sebebi nedir?
Bunun nedeni, karakter dizilerinin deitirilemeyen (immutable ) bir veri tipi olmasdr.
Pythonda iki tr veri tipi bulunur: deitirilemeyen veri tipleri (immutable datatypes ) ve
deitirilebilen veri tipleri (mutable datatypes ). Bizim imdiye kadar grdmz veri tipleri

16.5. Karakter Dizileri zerinde Deiiklik Yapmak 241


Python 3 iin Trke Klavuz, Srm 3

(saylar ve karakter dizileri), deitirilemeyen veri tipleridir. Henz deitirilebilen bir veri tipi
grmedik. Ama birka blm sonra deitirilebilen veri tiplerini de inceleyeceiz.
Neyse... Dediimiz gibi, karakter dizileri zerinde yaptmz deiikliklerin kalc olmamasn
nedeni, karakter dizilerinin deitirilemeyen bir veri tipi olmasdr. Pythonda bir karakter
dizisini bir kez tanmladktan sonra bu karakter dizisi zerinde artk deiiklik yapamazsnz.
Eer bir karakter dizisi zerinde deiiklik yapmanz gerekiyorsa, yapabileceiniz tek ey
o karakter dizisini yeniden tanmlamaktr. Mesela yukardaki rnekte kardiz deikeninin
tuttuu karakter dizisini deitirmek isterseniz yle bir kod yazabilirsiniz:
>>> kardiz = "" + kardiz[1:]
>>> print(kardiz)

stihza

Burada yaptmz ey kardiz deikeninin deerini deitirmek deildir. Biz burada aslnda
bambaka bir kardiz deikeni daha tanmlyoruz. Yani ilk kardiz deikeni ile sonraki kardiz
deikeni ayn eyler deil. Bunu teyit etmek iin nceki derslerimizde grdmz id()
fonksiyonundan yararlanabilirsiniz:
>>> kardiz = "istihza"
>>> id(kardiz)

3075853248

>>> kardiz = "" + kardiz[1:]


>>> id(kardiz)

3075853280

Grdnz gibi, ilk kardiz deikeni ile sonraki kardiz deikeni farkl kimlik numaralarna
sahip. Yani bu iki deiken bellek iinde farkl adreslerde tutuluyor. Daha dorusu, ikinci
kardiz, ilk kardiz i silip zerine yazyor.
Her ne kadar kardiz = "" + kardiz[1:] kodu kardiz in deerini aslnda deitirmiyor olsa
da, sanki kardiz deikeninin tuttuu karakter dizisi deiiyormu gibi bir etki elde ediyoruz.
Bu da bizi memnun etmeye yetiyor...
Yukardaki rnekte karakter dizisinin ba ksm zerinde deiiklik yaptk. Eer karakter
dizisinin ortasnda kalan bir ksm deitirmek isterseniz de yle bir ey yazabilirsiniz:
>>> kardiz = "istihza"
>>> kardiz = kardiz[:3] + "H" + kardiz[5:]
>>> kardiz

'istHza'

Grdnz gibi, yukardaki kodlarda karakter dizilerini dilimleyip birletirerek, yani bir
bakma kesip bierek istediimiz kty elde ettik.
Mesela ilk rnekte kardiz deikeninin ilk karakteri dnda kalan ksmn (kardiz[1:])
har ile birletirdik ("" + kardiz[1:]").
kinci rnekte ise kardiz deikeninin ilk karakterine H ifadesini ekledik ve sonra buna
kardiz deikeninin 5. karakterinden sonraki ksmn ilave ettik.
Karakter dizileri zerinde deiiklik yapmanzn hangi durumlarda gerekli olacan gsteren
bir rnek daha verip bu konuyu kapatalm.

242 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

Diyelim ki, bir kelime iindeki sesli ve sessiz hareri birbirinden ayrmanz gereken bir
program yazyorsunuz. Yani mesela amacnz istanbul kelimesi iinde geen i, a ve u
harerini bir yerde, s, t, n, b ve l harerini ise ayr bir yerde toplamak. Bunun iin yle
bir program yazabilirsiniz:
sesli_harfler = "aeiou"
sessiz_harfler = "bcdfghjklmnprstvyz"

sesliler = ""
sessizler = ""

kelime = "istanbul"

for i in kelime:
if i in sesli_harfler:
sesliler += i
else:
sessizler += i

print("sesli harfler: ", sesliler)


print("sessiz harfler: ", sessizler)

Burada ncelikle u kodlar yardmyla Trkedeki sesli ve sessiz hareri belirliyoruz:


sesli_harfler = "aeiou"
sessiz_harfler = "bcdfghjklmnprstvyz"

Ardndan da, sesli ve sessiz harerini ayklayacamz kelimedeki sesli harer ve sessiz harer
iin bo birer karakter dizisi tanmlyoruz:
sesliler = ""
sessizler = ""

Programmz iinde ilgili hareri, o harn ait olduu deikene atayacaz.


Kelimemiz istanbul :
kelime = "istanbul"

imdi bu kelime zerinde bir for dngs kuruyoruz ve kelime iinde geen herbir harfe tek
tek bakyoruz. Kelime iinde geen harerden, sesli_harer deikeninde tanml karakter
dizisinde geenleri sesliler adl deikene atyoruz. Aksi durumda ise, yani kelime iinde
geen harerden, sessiz_harer deikeninde tanml karakter dizisinde geenleri, sessizler
adl deikene gnderiyoruz:
for i in kelime:
if i in sesli_harfler:
sesliler += i
else:
sessizler += i

Bunun iin for dngs iinde basit bir if-else blou tanmladmz gryorsunuz.
Ayrca bunu yaparken, sesliler ve sessizler adl deikenlere, for dngsnn her bir
dnnde yeni bir harf gnderip, bu deikenleri, dngnn her dnnde yeni batan
tanmladmza dikkat edin. nk, dediimiz gibi, karakter dizileri deitirilemeyen veri
tipleridir. Bir karakter dizisi zerinde deiiklik yapmak istiyorsak, o karakter dizisini batan
tanmlamamz gerekir.

16.5. Karakter Dizileri zerinde Deiiklik Yapmak 243


Python 3 iin Trke Klavuz, Srm 3

16.6 nemli Fonksiyon

Karakter dizilerinin temel zellikleri hakknda syleyeceklerimizin sonuna geldik saylr. Biraz
sonra karakter dizilerinin ok nemli bir paras olan metotlardan sz edeceiz. Ama
isterseniz metotlara gemeden nce, ok nemli fonksiyondan sz edelim. Bu fonksiyonlar
sadece karakter dizileri ile deil, baka veri tipleri ile alrken de ilerimizi bir hayli
kolaylatracak.

16.6.1 dir()

lk olarak dir() adl zel bir fonksiyondan sz edeceiz. Bu metot bize Pythondaki bir
nesnenin zellikleri hakknda bilgi edinme imkan verecek. Mesela karakter dizilerinin bize
hangi metotlar sunduunu grmek iin bu fonksiyonu yle kullanabiliriz:
>>> dir(str)

['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',


'__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__',
'__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', 'capitalize', 'center', 'count', 'encode', 'endswith',
'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha',
'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',
'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase',
'title', 'translate', 'upper', 'zfill']

ngilizcede karakter dizisinin karlnn string, bu kelimenin ksaltmasnn da str olduunu


hatrlyor olmalsnz. te dir() fonksiyonuna parametre olarak bu str kelimesini
verdiimizde, Python bize karakter dizilerinin btn metotlarn listeliyor.
Karakter dizileri dnda, imdiye kadar rendiimiz baka bir veri tipi de saylar. Biz
Pythonda saylarn tam saylar (integer ), kayan noktal saylar (oat ) ve karmak saylar
(complex ) olarak e ayrldn da biliyoruz. rnek olmas asndan dir() fonksiyonunu bir
de srasyla, tam saylar, kayan noktal saylar ve karmak saylar zerinde de uygulayalm:
>>> dir(int)

>>> dir(float)

>>> dir(complex)

Grdnz gibi, dir() fonksiyonunu kullanmak iin, metotlarn listelemek istediimiz


nesneyi alp dir() fonksiyonuna parametre olarak veriyoruz. rnein yukarda karakter
dizileri iin str ; tam saylar iin int ; kayan noktal saylar iin oat ; karmak saylar iin ise
complex parametrelerini kullandk.
dir() fonksiyonunu kullanabilmek iin tek yntemimiz, sorgulamak istediimiz nesnenin
adn kullanmak deil. Mesela karakter dizilerinin metotlarn sorgulamak iin str kelimesini
kullanabileceimiz gibi, herhangi bir karakter dizisini de kullanabiliriz. Yani:

244 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

>>> dir("")

Burada dir() fonksiyonuna parametre olarak bo bir karakter dizisi verdik. Bu kodun
dir(str) kodundan hibir fark yoktur. Bu komut da bize karakter dizilerinin metotlarn
listeler.
Ayn etkiyi dilersek yle de elde edebiliriz:
>>> a = "karakter"
>>> dir(a)

Karakter dizilerinin metotlarn listelemek iin, siz hangi yntem kolaynza geliyorsa onu
kullanabilirsiniz. Bu satrlarn yazar genellikle u yntemi kullanyor:
>>> dir("")

dir("") komutunun ktsndan da greceiniz gibi, karakter dizilerinin epey metodu var.
Metot listesi iinde bizi ilgilendirenler banda veya sonunda _ iareti olmayanlar. Yani unlar:
>>> for i in dir(""):
... if "_" not in i[0]:
... print(i)
...

Bu arada bu metotlar listelemek iin nasl bir kod kullandmza dikkat edin:
for i in dir(""):
if "_" not in i[0]:
print(i)

Burada dir("") komutunun ierdii her bir metoda tek tek bakyoruz. Bu metotlar iinde, ilk
har _ karakteri olmayan btn metotlar listeliyoruz. Bylece istediimiz listeyi elde etmi
oluyoruz. sterseniz ilgilendiimiz metotlarn saysn da ktya ekleyebiliriz:
saya = 0

for i in dir(""):
if "_" not in i[0]:
saya += 1
print(i)

print("Toplam {} adet metot ile ilgileniyoruz.".format(saya))

Burada da, ilk karakteri _ olmayan her bir metot iin saya deikeninin deerini 1 artryoruz.
Bylece programn sonunda saya deikeni ilgilendiimiz metot saysn gstermi oluyor.
Eer her metodun soluna, sra numarasn da eklemek isterseniz elbette yle bir kod da
yazabilirsiniz:
saya = 0

for i in dir(""):
if "_" not in i[0]:
saya += 1
print(saya, i)

print("Toplam {} adet metot ile ilgileniyoruz.".format(saya))

16.6. nemli Fonksiyon 245


Python 3 iin Trke Klavuz, Srm 3

Bu noktada bir parantez aalm. Yukardaki yntemi kullanarak metotlar


numaralandrabilirsiniz. Ama aslnda Python bize numaralandrma ilemleri iin zel
bir fonksiyon sunar. imdi isterseniz bu zel fonksiyonu inceleyelim.

16.6.2 enumerate()

Eer yazdnz bir programda numaralandrmaya ilikin ilemler yapmanz gerekiyorsa


Pythonn size sunduu ok zel bir fonksiyondan yararlanabilirsiniz. Bu fonksiyonun ad
enumerate().
Gelelim bu fonksiyonun nasl kullanlacana... nce yle bir deneme yapalm:
>>> enumerate("istihza")

<enumerate object at 0x00E3BC88>

Tpk reversed() fonksiyonunun bir reversed nesnesi vermesi gibi, bu fonksiyonun da bize
yalnzca bir enumerate nesnesi verdiini gryorsunuz.
reversed() fonksiyonunu kullanabilmek iin yle bir kod yazmtk:
>>> print(*reversed("istihza"))

enumerate() iin de benzer bir eyi deneyebiliriz:


>>> print(*enumerate("istihza"))

Burada u kty aldk:


(0, 'i') (1, 's') (2, 't') (3, 'i') (4, 'h') (5, 'z') (6, 'a')

Enumerate kelimesi ngilizcede numaralamak, numaralandrmak gibi anlamlara gelir.


Dolaysyla enumerate() fonksiyonu, kendisine parametre olarak verilen deer hakknda bize
iki farkl bilgi verir: Bir e ve bu eye ait bir sra numaras. Yukardaki ktda grdnz
ey de ite her bir enin kendisi ve o eye ait bir sra numarasdr.
Yukardaki kty daha iyi anlayabilmek iin bir for dngs kullanmak daha aklayc olabilir:
>>> for i in enumerate("istihza"):
... print(i)
...
(0, 'i')
(1, 's')
(2, 't')
(3, 'i')
(4, 'h')
(5, 'z')
(6, 'a')

Grdnz gibi, gerekten de bu fonksiyon bize bir e (mesela i har) ve bu eye ait bir
sra numaras (mesela 0 ) veriyor.
Hatrlarsanz, enumerate() fonksiyonunu renmeden nce, dir("") komutundan elde
ettiimiz ktlar u ekilde numaralandrabileceimizi sylemitik:
saya = 0

246 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

for i in dir(""):
if "_" not in i[0]:
saya += 1
print(saya, i)

Ama artk enumerate() fonksiyonunu rendiimize gre, ayn ii ok daha verimli bir ekilde
gerekletirebiliriz:
for sra, metot in enumerate(dir("")):
print(sra, metot)

enumerate() metodunun verdii her bir ktnn iki eli olduunu biliyoruz (enin kendisi ve
o enin sra numaras). Yukardaki kodlar yardmyla, bu elerin her birini ayr bir deikene
(sra ve metot ) atam oluyoruz. Bylece bu kty maniple etmek bizim iin daha kolay
oluyor. Mesela bu zellii kullanarak metot ve sra numarasnn yerlerini deitirebiliriz:
>>> for sra, metot in enumerate(dir("")):
... print(metot, sra)
...
__add__ 0
__class__ 1
__contains__ 2
__delattr__ 3
__doc__ 4
__eq__ 5
__format__ 6
__ge__ 7

(...)

Pratik olmas asndan yle bir rnek daha verelim:


>>> for sra, metot in enumerate(dir("")):
... print(sra, metot, len(metot))
...
0 __add__ 7
1 __class__ 9
2 __contains__ 12
3 __delattr__ 11
4 __doc__ 7
5 __eq__ 6

(...)

Burada, dir("") ile elde ettiimiz metotlarn srasn (sra ), bu metotlarn adlarn (metot ) ve
her bir metodun ka karakterden olutuunu (len(metot)) gsteren bir kt elde ettik.
Bu arada, grdnz gibi, enumerate() fonksiyonu numaralandrmaya 0 dan balyor.
Elbette eer isterseniz bu fonksiyonun numaralandrmaya katan balayacan kendiniz de
belirleyebilirsiniz. Dikkatlice bakn:
>>> for sra, harf in enumerate("istihza", 1):
... print(sra, harf)
...
1 i
2 s
3 t

16.6. nemli Fonksiyon 247


Python 3 iin Trke Klavuz, Srm 3

4 i
5 h
6 z
7 a

Burada istihza kelimesi iindeki hareri numaralandrdk. Bunu yaparken de


numaralandrmaya 1 den baladk. Bunun iin enumerate() fonksiyonuna ikinci bir
parametre verdiimize dikkat edin.
enumerate() fonksiyonunu da incelediimize gre nemli bir baka fonksiyondan daha sz
edebiliriz.

16.6.3 help()

Pythonla ilgili herhangi bir konuda yardma ihtiyacnz olduunda, internetten aratrma
yaparak pek ok ayrntl belgeye ulaabilirsiniz. Ama eer herhangi bir nesne hakknda
hzl bir ekilde ve ngilizce olarak yardm almak isterseniz help() adl zel bir fonksiyondan
yararlanabilirsiniz.
Bu fonksiyonu iki farkl ekilde kullanyoruz. Birinci yntemde, etkileimli kabua help()
yazp Enter dmesine basyoruz:
>>> help()

Welcome to Python 3.3! This is the interactive help utility.

If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://docs.python.org/3.3/tutorial/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules. To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, or topics, type "modules",


"keywords", or "topics". Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".

help>

Grdnz gibi, Python bu komutu verdiimizde zel bir yardm ekran ayor bize. Bu
ekranda >>> yerine help> ifadesinin olduuna dikkat edin. Mesela dir() fonksiyonu
hakknda bilgi almak iin help> ifadesinden hemen sonra, hi boluk brakmadan, u komutu
verebiliriz:
help> dir

Bu komut bize u kty veriyor:


Help on built-in function dir in module builtins:

dir(...)
dir([object]) -> list of strings

If called without an argument, return the names in the current scope.


Else, return an alphabetized list of names comprising (some of) the attributes

248 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

of the given object, and of attributes reachable from it.


If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns:
for a module object: the module's attributes.
for a class object: its attributes, and recursively the attributes of its bases.
for any other object: its attributes, its class's attributes, and
recursively the attributes of its class's base classes.

Grdnz gibi, dir() fonksiyonunun ne ie yarad ve nasl kullanld konusunda ayrntl


bir bilgi ediniyoruz. Bu arada, hakknda bilgi almak istediimiz fonksiyonu parantezsiz
yazdmza dikkat edin.
rnek olmas asndan mesela bir de len() fonksiyonu hakknda bilgi edinelim:
help> len

Help on built-in function len in module builtins:

len(...)
len(object) -> integer

Return the number of items of a sequence or mapping.

help ekranndan kmak iin Enter dmesine basabilir veya quit komutu verebilirsiniz.
En bata da dediimiz gibi Pythonda etkileimli kabuk zerinde ngilizce yardm almak iin
iki farkl yntem kullanabiliyoruz. Bu yntemlerden ilkini yukarda anlattk. kincisi ise
dorudan etkileimli kabukta u komutu kullanmaktr: (Mesela dir() fonksiyonu hakknda
yardm alalm...)
>>> help(dir)

Help on built-in function dir in module builtins:

dir(...)
dir([object]) -> list of strings

If called without an argument, return the names in the current scope.


Else, return an alphabetized list of names comprising (some of) the attributes
of the given object, and of attributes reachable from it.
If the object supplies a method named __dir__, it will be used; otherwise
the default dir() logic is used and returns:
for a module object: the module's attributes.
for a class object: its attributes, and recursively the attributes of its bases.
for any other object: its attributes, its class's attributes, and
recursively the attributes of its class's base classes.

Grdnz gibi, help ekrann amadan, dorudan etkileimli kabuk zerinden de help()
fonksiyonunu herhangi bir fonksiyon gibi kullanp, hakknda yardm almak istediimiz nesneyi
help() fonksiyonunun parantezleri iine parametre olarak yazabiliyoruz.
Bylece dir(), enumerate() ve help() adl nemli fonksiyonu da geride brakm olduk.
Dilerseniz imdi karakter dizilerine dair birka ufak not delim.

16.6. nemli Fonksiyon 249


Python 3 iin Trke Klavuz, Srm 3

16.7 Notlar

Hatrlarsanz dngleri anlatrken yle bir rnek vermitik:


tr_harfler = ""
a = 0

while a < len(tr_harfler):


print(tr_harfler[a], sep="\n")
a += 1

Bu kodlarn for dngs ile yazlabilecek olan u kodlara alternatif olduundan sz etmitik:
tr_harfler = ""

for tr_harf in tr_harfler:


print(tr_harf)

Yukardaki while rneini verirken, henz karakter dizilerinin elerine tek tek nasl
eriebileceimizi renmemitik. Ama artk bu konuyu da rendiimiz iin yukardaki while
dngsn rahatlkla anlayabiliyoruz:
while a < len(tr_harfler):
print(tr_harfler[a], sep="\n")
a += 1

Burada yaptmz ey u: a deikeninin deeri tr_harer deikeninin uzunluundan


(len(tr_harfler)) kk olduu mddete a deikeninin deerini 1 say artrp yine a
deikenine gnderiyoruz (a += 1).
while dngsnn her dnnde de, a deikeninin yeni deeri yardmyla tr_harer adl
karakter dizisinin elerine tek tek ve srayla eriiyoruz (print(tr_hafler[a])).
Yine hatrlarsanz, nceki derslerimizde sys adl bir modl iindeki version adl bir
deikenden sz etmitik. Bu deiken bize kullandmz Pythonn srmn bir karakter
dizisi olarak veriyordu:
>>> import sys
>>> sys.version

Buradan u kty alyoruz:


`3.5.1 (default, 20.04.2016, 12:24:55)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
Bu ktda, kullandmz Python srmnn dnda baka birtakm bilgiler de var. te biz
eer istersek, bu blmde rendiimiz bilgileri kullanarak bu karakter dizisinin istediimiz
ksmn, mesela sadece srm bilgisini karakter dizisinin iinden dilimleyip alabiliriz:
>>> sys.version[:5]

`3.5.1'
Elbette, yukardaki karakter dizisini elde etmek iin, kullanmas ve ynetmesi daha kolay bir
ara olan version_info deikeninden de yararlanabilirdiniz:
>>> '{}.{}.{}'.format(sys.version_info.major, sys.version_info.minor, sys.version_info.micro)

250 Blm 16. Karakter Dizileri


Python 3 iin Trke Klavuz, Srm 3

`3.5.1'
Ancak burada yle bir sorun olduunu biliyorsunuz: Pythonn 2.7 ncesi srmlerinde
version_info nun major, minor ve micro gibi nitelikleri yok. Dolaysyla 2.7 ncesi
srmlerde version_info yu kullanrken hata almamak iin try... except bloklarndan
yararlanabileceimizi grmtk. Ancak version_info yu btn Python srmlerinde gvenli
bir ekilde kullanmann baka bir yntemi daha var. Dikkatlice bakn:
>>> major = sys.version_info[0]
>>> minor = sys.version_info[1]
>>> micro = sys.version_info[2]

>>> print(major, minor, micro, sep=".")

3.5.1
Bu yntem btn Python srmlerinde alr. Dolaysyla, farkl Python srmlerinde
almasn tasarladnz programlarnzda srm kontroln sys.version_info nun major,
minor veya micro nitelikleri ile yapmak yerine yukardaki yntemle yapabilirsiniz:
if sys.version_info[1] < 3:
print("Kullandnz Python srm eski!")

Grdnz gibi, karakter dizisi dilimleme ilemleri pek ok farkl kullanm alanna
sahip. Programlama maceranz boyunca karakter dizilerinin bu zelliinden bol bol
yararlanacanzdan hi kukunuz olmasn.

16.7. Notlar 251


BLM 17

Karakter Dizilerinin Metotlar

Geen blmde karakter dizilerinin genel zelliklerinden sz ettik. Bu ikinci blmde ise
karakter dizilerini biraz daha ayrntl bir ekilde incelemeye ve karakter dizilerinin yepyeni
zelliklerini grmeye balayacaz.
Hatrlarsanz, geen blmn en banda, metot diye bir eyden sz edeceimizi
sylemitik. Orada da kabaca tarif ettiimiz gibi, metotlar Pythonda nesnelerin niteliklerini
deitirmemizi, sorgulamamz veya bu nesnelere yeni zellikler katmamz salayan
aralardr. Metotlar sayesinde karakter dizilerini istediimiz gibi eip bkebileceiz.
Geen blmn sonlarna doru, bir karakter dizisinin hangi metotlara sahip olduunu u
komut yardmyla listeleyebileceimizi renmitik:
>>> dir("")

Bu komutu verdiinizde aldnz ktdan da grdnz gibi, karakter dizilerinin 40 n


zerinde metodu var. Dolaysyla metot saysnn okluu gznz korkutmu olabilir. Ama
aslnda buna hi lzum yok. nk programclk maceranzda bu metotlarn bazlarn ya ok
nadiren kullanacaksnz, ya da hi kullanmayacaksnz. ok kullanlan metotlar belli baldr.
Elbette btn metotlar hakknda kir sahibi olmak gerekir. Zaten siz de greceksiniz ki,
bu metotlar kullandka aklnzda kalacak. Doal olarak ok kullandnz metotlar daha
kolay reneceksiniz. Eer bir program yazarken hangi metodu kullanmanz gerektiini
veya kullanacanz metodun ismini hatrlayamazsanz etkileimli kabukta dir("") gibi bir
komut verip kan sonucu incelemek pek zor olmasa gerek. Ayrca hatrlayamadnz bir
metot olmas durumunda dnp bu sayfalar tekrar gzden geirme imkanna da sahipsiniz.
Unutmayn, btn metotlar ve bu metotlarn nasl kullanldn ezbere bilmeniz zaten
beklenmiyor. Metotlar hatrlayamamanz gayet normal. Byle bir durumda referans
kitaplarna bakmak en doal hakknz.

17.1 replace()

Karakter dizisi metotlar arasnda inceleyeceimiz ilk metot replace() metodu olacak.
replace kelimesi Trkede deitirmek, yerine koymak gibi anlamlar tar. te bu metodun
yerine getirdii grev de tam olarak budur. Yani bu metodu kullanarak bir karakter dizisi
iindeki karakterleri baka karakterlerle deitirebileceiz.
Peki bu metodu nasl kullanacaz? Hemen bir rnek verelim:
>>> kardiz = "elma"

252
Python 3 iin Trke Klavuz, Srm 3

Burada elma deerini tayan kardiz adl bir karakter dizisi tanmladk. imdi bu karakter
dizisinin iinde geen e harni E ile deitirelim. Dikkatlice bakn:
>>> kardiz.replace("e", "E")

'Elma'

Grdnz gibi, replace() son derece yararl ve kullanm olduka kolay bir metot. Bu arada
bu ilk metodumuz sayesinde Pythondaki metotlarn nasl kullanlaca konusunda da bilgi
edinmi olduk. Yukardaki rneklerin bize gsterdii gibi yle bir formlle kar karyayz:
karakter_dizisi.metot(parametre)

Metotlar karakter dizilerinden nokta ile ayrlr. Pythonda bu ynteme noktal gsterim (dot
notation ) ad verilir.
Bu arada metotlarn grn ve kullanm olarak fonksiyonlara ne kadar benzediine dikkat
edin. Tpk fonksiyonlarda olduu gibi, metotlar da birtakm parametreler alabiliyor.
Yukardaki rnekte, replace() metodunun iki farkl parametre aldn gryoruz. Bu metoda
verdiimiz ilk parametre deitirmek istediimiz karakter dizisini gsteriyor. kinci parametre
ise birinci parametrede belirlediimiz karakter dizisinin yerine ne koyacamz belirtiyor. Yani
replace() metodu yle bir formle sahiptir:
karakter_dizisi.replace(eski_karakter_dizisi, yeni_karakter_dizisi)

Gelin isterseniz elimizin almas iin replace() metoduyla birka rnek daha verelim:
>>> kardiz = "memleket"
>>> kardiz.replace("ket", "KET")

'memleKET'

Burada grdnz gibi, replace() metodu ayn anda birden fazla karakteri deitirme
yeteneine de sahip.
replace() metodunun iki parametreden olutuunu, ilk parametrenin deitirilecek karakter
dizisini, ikinci parametrenin ise ilk karakter dizisinin yerine geecek yeni karakter dizisini
gsterdiini sylemitik. Aslnda replace() metodu nc bir parametre daha alr. Bu
parametre ise bir karakter dizisi iindeki karakterlerin ka tanesinin deitirileceini gsterir.
Eer bu parametreyi belirtmezsek replace() metodu ilgili karakterlerin tamamn deitirir.
Yani:
>>> kardiz = "memleket"

>>> kardiz.replace("e", "")

'mmlkt'

Grdnz gibi, replace() metodunu iki parametre ile kullanp nc parametreyi


belirtmediimizde, memleket kelimesi iindeki btn e hareri bo karakter dizisi ile
deitiriliyor (yani bir anlamda siliniyor).
imdi u rnee bakalm:
>>> kardiz.replace("e", "", 1)

'mmleket'

17.1. replace() 253


Python 3 iin Trke Klavuz, Srm 3

Burada replace() metodunu nc bir parametre ile birlikte kullandk. nc parametre


olarak 1 saysn verdiimiz iin replace() metodu sadece tek bir e harni sildi.
Bu nc parametreyi, silmek istediiniz harf says kadar artrabilirsiniz. Mesela:
>>> kardiz.replace("e", "", 2)

'mmlket'

>>> kardiz.replace("e", "", 3)

'mmlkt'

Burada ilk rnekte nc parametre olarak 2 saysn kullandmz iin, replace ileminden
karakter dizisi iindeki 2 adet e har etkilendi. nc rnekte ise memleket adl karakter
dizisi iinde geen adet e har deiiklikten etkilendi.
Karakter dizileri konusunun ilk blmnde deitirilebilirlik (mutability ) zerine sylediimiz
eylerin burada da geerli olduunu unutmayn. Orada da sylediimiz gibi, karakter dizileri
deitirilemeyen veri tipleridir. Dolaysyla eer bir karakter dizisi zerinde deiiklik yapmak
istiyorsanz, o karakter dizisini batan tanmlamalsnz. rnein:
>>> meyve = "elma"
>>> meyve = meyve.replace("e", "E")
>>> meyve

'Elma'

Bylece replace() metodunu incelemi olduk. Srada nemli metot var.

17.2 split(), rsplit(), splitlines()

imdi size yle bir soru sorduumu dnn: Acaba aadaki karakter dizisinde yer alan
btn kelimelerin ilk harni nasl alrz?
>>> kardiz = "stanbul Bykehir Belediyesi"

Yani diyorum ki burada BB gibi bir kty nasl elde ederiz?


Sadece bu karakter dizisi sz konusu ise, elbette karakter dizilerinin dilimlenme zelliinden
yararlanarak, kardiz deikeni iindeki , B, ve B harerini tek tek alabiliriz:
>>> print(kardiz[0], kardiz[9], kardiz[20], sep="")

BB

Ancak bu yntemin ne kadar kullansz olduu ortada. nk bu metot yalnzca stanbul


Bykehir Belediyesi adl karakter dizisi iin geerlidir. Eer karakter dizisi deiirse bu
yntem de pe gider. Bu soruna genel bir zm retebilsek ne gzel olurdu, deil mi?
te Pythonda bu sorunu zmemizi salayacak ok gzel bir metot bulunur. Bu metodun ad
split().
Bu metodun grevi karakter dizilerini belli noktalardan blmektir. Zaten split kelimesi
Trkede blmek, ayrmak gibi anlamlara gelir. te bu metot, zerine uyguland karakter
dizilerini paralarna ayrr. rnein:

254 Blm 17. Karakter Dizilerinin Metotlar


Python 3 iin Trke Klavuz, Srm 3

>>> kardiz = "stanbul Bykehir Belediyesi"


>>> kardiz.split()

['stanbul', 'Bykehir', 'Belediyesi']

Grdnz gibi bu metot sayesinde stanbul Bykehir Belediyesi adl karakter dizisini
kelimelere blmeyi baardk. Eer bu kt zerine bir for dngs uygularsak yle bir sonu
elde ederiz:
>>> for i in kardiz.split():
... print(i)
...
stanbul
Bykehir
Belediyesi

Artk bu bilgiyi kullanarak yle bir program yazabiliriz:


kardiz = input("Ksaltmasn renmek istediiniz kurum adn girin: ")

for i in kardiz.split():
print(i[0], end="")

Burada kullanc hangi kurum adn girerse girsin, bu kurum adnn her kelimesinin ilk
har ekrana dklecektir. rnein kullanc burada Trkiye Byk Millet Meclisi ifadesini
girmise split() metodu ncelikle bu ifadeyi alp u ekle dntrr:
['Trkiye', 'Byk', 'Millet', 'Meclisi']

Daha sonra biz bu kt zerinde bir for dngs kurarsak bu kelime grubunun her bir
esine tek tek mdahale etme imkanna eriiriz. rnein yukardaki programda bu kelime
grubunun her bir esinin ilk harni tek tek ekrana dktk ve TBMM ktsn elde ettik.
Yukardaki rneklerde split() metodunu herhangi bir parametre iermeyecek ekilde
kullandk. Yani metodun parantezleri iine herhangi bir ey eklemedik. split() metodunu
bu ekilde parametresiz olarak kullandmzda bu metot karakter dizilerini blerken boluk
karakterini lt alacaktr. Yani karakter dizisi iinde karlat her boluk karakterinde bir
blme ilemi uygulayacaktr. Ama bazen istediimiz ey, bir karakter dizisini boluklardan
blmek deildir. Mesela u rnee bakalm:
>>> kardiz = "Bolvadin, Kilis, Siverek, skenderun, stanbul"

Eer bu karakter dizisi zerine split() metodunu parametresiz olarak uygularsak yle bir
kt elde ederiz:
['Bolvadin,', 'Kilis,', 'Siverek,', 'skenderun,', 'stanbul']

split() metoduna herhangi bir parametre vermediimiz iin bu metot karakter dizisi iindeki
kelimeleri boluklardan bld. Bu yzden karakter dizisi iindeki virgl iaretleri de blnen
kelimeler iinde grnyor:
>>> kardiz = kardiz.split()
>>> for i in kardiz:
... print(i)
...
Bolvadin,

17.2. split(), rsplit(), splitlines() 255


Python 3 iin Trke Klavuz, Srm 3

Kilis,
Siverek,
skenderun,
stanbul

Bu arada tpk replace() metodunu anlatrken gsterdiimiz gibi, kardiz.split() ifadesini


de yine kardiz adn tayan bir deikene atadk. Bylece kardiz.split() komutu ile
elde ettiimiz deiiklik kaybolmam oldu. Karakter dizilerinin deitirilemeyen bir veri
tipi olduunu biliyorsunuz. Dolaysyla yukardaki karakter dizisi zerine split() metodunu
uyguladmzda aslnda orijinal karakter dizisi zerinde herhangi bir deiiklik yapm
olmuyoruz. ktda grnen deiikliin orijinal karakter dizisini etkileyebilmesi iin eski
karakter dizisini silip, yerine yeni deerleri yazmamz gerekiyor. Bunu da kardiz =
kardiz.split() gibi bir komutla hallediyoruz.
Nerede kalmtk? Grdnz gibi split() metodu parametresiz olarak kullanldnda
karakter dizisini boluklardan blyor. Ama yukardaki rnekte karakter dizisini boluklardan
deil de virgllerden blsek ok daha anlaml bir kt elde edebiliriz.
Dikkatlice inceleyin:
>>> kardiz = "Bolvadin, Kilis, Siverek, skenderun, stanbul"
>>> kardiz = kardiz.split(",")
>>> print(kardiz)

['Bolvadin', ' Kilis', ' Siverek', ' skenderun', ' stanbul']

>>> for i in kardiz:


... print(i)
...
Bolvadin
Kilis
Siverek
skenderun
stanbul

Grdnz gibi, split() metodu tam da istediimiz gibi, karakter dizisini bu kez
boluklardan deil virgllerden bld. Peki bunu nasl baard? Aslnda bu sorunun cevab
gayet net bir ekilde grnyor. Dikkat ederseniz yukardaki rnekte split() metoduna
parametre olarak virgl karakter dizisini verdik. Yani yle bir ey yazdk:
kardiz.split(",")

Bu sayede split() metodu karakter dizisini virgllerden blmeyi baard. Tahmin


edebileceiniz gibi, split() metoduna hangi parametreyi verirseniz bu metot ilgili karakter
dizisini o karakterin getii yerlerden blecektir. Yani mesela siz bu metoda l parametresini
verirseniz, bu metot da l har geen yerden karakter dizisini blecektir:
>>> kardiz.split("l")

['Bo', 'vadin, Ki', 'is, Siverek, skenderun, stanbu', '']

>>> for i in kardiz.split("l"):


... print(i)
...
Bo
vadin, Ki
is, Siverek, skenderun, stanbu

256 Blm 17. Karakter Dizilerinin Metotlar


Python 3 iin Trke Klavuz, Srm 3

Eer parametre olarak verdiiniz deer karakter dizisi iinde hi gemiyorsa karakter dizisi
zerinde herhangi bir deiiklik yaplmaz:
>>> kardiz.split("z")

['Bolvadin, Kilis, Siverek, skenderun, stanbul']

Ayn ey, split() metodundan nce rendiimiz replace() metodu iin de geerlidir. Yani
eer deitirilmek istenen karakter, karakter dizisi iinde yer almyorsa herhangi bir ilem
yaplmaz.
split() metodu ounlukla, yukarda anlattmz ekilde parametresiz olarak veya tek
parametre ile kullanlr. Ama aslnda bu metot ikinci bir parametre daha alr. Bu ikinci
parametre, karakter dizisinin ka kez blneceini belirler:
>>> kardiz = "Ankara Bykehir Belediyesi"

>>> kardiz.split(" ", 1)

['Ankara', 'Bykehir Belediyesi']

>>> kardiz.split(" ", 2)

['Ankara', 'Bykehir', 'Belediyesi']

Grdnz gibi, ilk rnekte kullandmz 1 says sayesinde blme ilemi karakter dizisi
zerine bir kez uyguland. kinci rnekte ise 2 saysnn etkisiyle karakter dizimiz iki kez blme
ilemine maruz kald.
Elbette, split() metodunun ikinci parametresini kullanabilmek iin ilk parametreyi de
mutlaka yazmanz gerekir. Aksi halde Python ne yapmaya altnz anlayamaz:
>>> kardiz.split(2)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

Grdnz gibi, ilk parametreyi es geip dorudan ikinci parametreyi yazmaya altmzda
Python parametre olarak verdiimiz 2 saysnn blme lt olduunu zannediyor.
Yukardaki hatay engellemek iin blme ltn de aka belirtmemiz gerekir. Yukardaki
rnekte blme ltmz bir adet boluk karakteri idi. Bildiiniz gibi, blme lt herhangi
bir ey olabilir. Mesela virgl.
>>> arkadalar = "Ahmet, Mehmet, Kezban, Mualla, Sreyya, Veli"
>>> arkadalar.split(",", 3)

['Ahmet', ' Mehmet', ' Kezban', ' Mualla, Sreyya, Veli']

Burada da blme lt olarak virgl karakterini kullandk ve arkadalar adl karakter dizisi
zerine 3 kez blme ilemi uyguladk. lk blme ilemi Ahmet karakter dizisini; ikinci blme
ilemi Mehmet karakter dizisini; nc blme ilemi ise Kezban karakter dizisini ayrd.
arkadalar adl karakter dizisinin geri kalann oluturan Mualla, Sreyya, Veli ksm ise
herhangi bir blme ilemine tabi tutulmadan tek para olarak kald.
split() metoduyla son bir rnek verip yolumuza devam edelim.
Bildiiniz gibi sys modlnn version deikeni bize bir karakter dizisi veriyor:

17.2. split(), rsplit(), splitlines() 257


Python 3 iin Trke Klavuz, Srm 3

`3.5.1 (default, 20.04.2016, 12:24:55)


[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
Bu karakter dizisi iinden yalnzca srm ksmn ayklamak iin karakter dizilerinin
dilimlenme zelliinden yararlanabiliyoruz:
>>> srm = sys.version
>>> print(srm[:5])

3.5.1
Bu ilemin bir benzerini split() metoduyla da yapabiliriz. Dikkatlice inceleyin:
>>> srm = sys.version
>>> srm.split()

['3.3.0', '(v3.3.0:bd8afb90ebf2,', 'Sep', '29', '2012,', '10:55:48)',


'[MSC', 'v.1600', '32', 'bit', '(Intel)]']

Grdnz gibi, sys.version komutuna split() metodunu uyguladmzda, zerinde


ilem yapmas ok daha kolay olan bir veri tipi elde ediyoruz. Bu veri tipinin ad liste. nceki
derslerimizde rendiimiz dir() fonksiyonunun da liste adl bu veri tipini verdiini hatrlyor
olmalsnz. lerleyen derslerde, tpk karakter dizileri ve saylar adl veri tipleri gibi, liste adl
veri tipini de btn ayrntlaryla inceleyeceiz. imdilik biz sadece baz durumlarda liste veri
tipinin karakter dizilerine kyasla daha kullanl bir veri tipi olduunu bilelim yeter.
Yukardaki rnekten de grdnz gibi, sys.version komutunun ktsn split() metodu
yardmyla boluklardan blerek bir liste elde ettik. Bu listenin ilk esi, kullandmz Python
serisinin srm numarasn verecektir:
>>> print(srm.split()[0])

3.5.1
Bylece split() metodunu renmi olduk. Gelelim rsplit() metoduna...
rsplit() metodu her ynyle split() metoduna benzer. split() ile rsplit() arasndaki
tek fark, split() metodunun karakter dizisini soldan saa, rsplit() metodunun ise sadan
sola doru okumasdr. u rnekleri dikkatlice inceleyerek bu iki metot arasndaki fark bariz
bir ekilde grebilirsiniz:
>>> kardiz.split(" ", 1)

['Ankara', 'Bykehir Belediyesi']

>>> kardiz.rsplit(" ", 1)

['Ankara Bykehir', 'Belediyesi']

Grdnz gibi, split() metodu karakter dizisini soldan saa doru okuduu iin blme
ilemini Ankara karakter dizisine uygulad. rsplit() metodu ise karakter dizisini sadan
sola soru okuduu iin blme ilemini Belediyesi adl karakter dizisine uygulad.
rsplit() metodunun pek yaygn kullanlan bir metot olmadn belirterek splitlines()
metoduna geelim.
Bildiiniz gibi, split() metodunu bir karakter dizisini kelime kelime ayrabilmek iin
kullanabiliyoruz. splitlines() metodunu ise bir karakter dizisini satr satr ayrmak iin

258 Blm 17. Karakter Dizilerinin Metotlar


Python 3 iin Trke Klavuz, Srm 3

kullanabiliriz. Mesela elinizde uzun bir metin olduunu ve amacnzn bu metin iindeki
herbir satr ayr ayr almak olduunu dnn. te splitlines() metoduyla bu amacnz
gerekletirebilirsiniz. Hemen bir rnek verelim:
metin = """Python programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90'l yllarn banda gelitirilmeye balanmtr. ou insan, isminin
Python olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn
dnr. Ancak zannedildiinin aksine bu programlama dilinin ad piton ylanndan
gelmez. Guido Van Rossum bu programlama dilini, The Monty Python adl bir ngiliz
komedi grubunun, Monty Python's Flying Circus adl gsterisinden esinlenerek
adlandrmtr. Ancak her ne kadar gerek byle olsa da, Python programlama
dilinin pek ok yerde bir ylan figr ile temsil edilmesi neredeyse bir gelenek
halini almtr diyebiliriz."""

print(metin.splitlines())

Bu program altrdnzda yle bir kt alrsnz:


['Python programlama dili Guido Van Rossum adl Hollandal bir programc ',
"tarafndan 90'l yllarn banda gelitirilmeye balanmtr. ou insan,
isminin", 'Python olmasna bakarak, bu programlama dilinin, adn piton
ylanndan aldn ', 'dnr. Ancak zannedildiinin aksine bu programlama
dilinin ad piton ylanndan ', 'gelmez. Guido Van Rossum bu programlama
dilini, The Monty Python adl bir ngiliz ', "komedi grubunun, Monty Python's
Flying Circus adl gsterisinden esinlenerek ", 'adlandrmtr. Ancak her ne
kadar gerek byle olsa da, Python programlama ', 'dilinin pek ok yerde bir
ylan figr ile temsil edilmesi neredeyse bir gelenek ', 'halini almtr
diyebiliriz.']

Grdnz gibi, metnimiz Enter tuuna bastmz noktalardan blnd. Biz henz bu kty
nasl deerlendireceimizi ve bu ktdan nasl yararlanacamz bilmiyoruz. Ayrca u anda
bu kt gznze ok anlaml grnmemi olabilir. Ama Listeler adl konuyu rendiimizde
bu kt size ok daha anlaml grnecek.
splitlines() metodu yukardaki gibi parametresiz olarak kullanlabilecei gibi, bir adet
parametre ile de kullanlabilir. Bunu bir rnek zerinde gsterelim:
metin = """Python programlama dili Guido Van Rossum adl Hollandal bir programc
tarafndan 90'l yllarn banda gelitirilmeye balanmtr. ou insan, isminin
Python olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn
dnr. Ancak zannedildiinin aksine bu programlama dilinin ad piton ylanndan
gelmez. Guido Van Rossum bu programlama dilini, The Monty Python adl bir ngiliz
komedi grubunun, Monty Python's Flying Circus adl gsterisinden esinlenerek
adlandrmtr. Ancak her ne kadar gerek byle olsa da, Python programlama
dilinin pek ok yerde bir ylan figr ile temsil edilmesi neredeyse bir gelenek
halini almtr diyebiliriz."""

print(metin.splitlines(True))

Bu program altrdmzda una benzer bir sonu elde ederiz:


['Python programlama dili Guido Van Rossum adl Hollandal bir programc \n',
"tarafndan 90'l yllarn banda gelitirilmeye balanmtr. ou insan,
isminin \n", 'Python olmasna bakarak, bu programlama dilinin, adn piton
ylanndan aldn \n', 'dnr. Ancak zannedildiinin aksine bu programlama
dilinin ad piton ylanndan \n', 'gelmez. Guido Van Rossum bu programlama
dilini, The Monty Python adl bir ngiliz \n', "komedi grubunun, Monty
Python's Flying Circus adl gsterisinden esinlenerek \n", 'adlandrmtr.

17.2. split(), rsplit(), splitlines() 259


Python 3 iin Trke Klavuz, Srm 3

Ancak her ne kadar gerek byle olsa da, Python programlama \n', 'dilinin pek
ok yerde bir ylan figr ile temsil edilmesi neredeyse bir gelenek \n',
'halini almtr diyebiliriz.']

Grdnz gibi, parametresiz kullanmda, program ktsnda satr ba karakterleri (\n )


grnmyor. Ama eer splitlines() metoduna parametre olarak True verirsek program
ktsnda satr ba karakterleri de grnyor. Yazdnz programlarda ihtiyacnza gre
splitlines() metodunu parametreli olarak veya parametresiz bir ekilde kullanabilirsiniz.

17.3 lower()

Mutlaka karlamsnzdr. Baz programlarda kullancdan istenen veriler byk-kk


harfe duyarldr. Yani mesela kullancdan bir parola isteniyorsa, kullancnn bu parolay
byk-kk harfe dikkat ederek yazmas gerekir. Bu programlar asndan, rnein parola
ve Parola ayn kelimeler deildir. Mesela kullancnn parolas parola ise, bu kullanc
programa Parola yazarak giremez.
Baz baka programlarda ise bu durumun tam tersi sz konusudur. Yani byk-kk harfe
duyarl programlarn aksine baz programlar da kullancdan gelen verinin byk hari mi
yoksa kk hari mi olduunu nemsemez. Kullanc doru kelimeyi byk hare de
yazsa, kk hare de yazsa program istenen ilemi gerekletirir. Mesela Googleda yaplan
aramalar bu mantk zerine alr. rnein kitap kelimesini Googleda aratyorsanz, bu
kelimeyi byk hare de yazsanz, kk hare de yazsanz Google size ayn sonular
gsterecektir. Google asndan, aradnz kelimeyi byk ya da kk hare yazmanzn
bir nemi yoktur.
imdi yle bir program yazdmz dnn:
kii = input("Aradnz kiinin ad ve soyad: ")

if kii == "Ahmet z":


print("email: aoz@hmail.com")
print("tel : 02121231212")
print("ehir: istanbul")

elif kii == "Mehmet Sz":


print("email: msoz@zmail.com")
print("tel : 03121231212")
print("ehir: ankara")

elif kii == "Mahmut Gz":


print("email: mgoz@jmail.com")
print("tel : 02161231212")
print("ehir: istanbul")

else:
print("Aradnz kii veritabannda yok!")

Bu programn doru alabilmesi iin kullancnn, rnein, Ahmet z adl kiiyi ararken
byk-kk harfe dikkat etmesi gerekir. Eer kullanc Ahmet z yazarsa o kiiyle ilgili
bilgileri alabilir, ama eer mesela Ahmet z yazarsa bilgileri alamaz. Peki acaba biz
bu sorunun stesinden nasl gelebiliriz? Yani programmzn byk-kk harfe duyarl
olmamasn nasl salayabiliriz?

260 Blm 17. Karakter Dizilerinin Metotlar


Python 3 iin Trke Klavuz, Srm 3

Bu ii yapmann iki yolu var: Birincisi if bloklarn her trl ihtimali dnerek yazabiliriz.
Mesela:

if kii == "Ahmet z" or "Ahmet z" or "ahmet z":


...

Ama burada baz problemler var. Birincisi, kullancnn ka trl veri girebileceini
kestiremeyebilirsiniz. kincisi, kestirebilseniz bile, her kii iin olaslklar girmeye almak
eziyetten baka bir ey deildir...
te burada imdadmza lower() metodu yetiecek. Dikkatlice inceleyin:
kii = input("Aradnz kiinin ad ve soyad: ")
kii = kii.lower()

if kii == "ahmet z":


print("email: aoz@hmail.com")
print("tel : 02121231212")
print("ehir: istanbul")

elif kii == "mehmet sz":


print("email: msoz@zmail.com")
print("tel : 03121231212")
print("ehir: ankara")

elif kii == "mahmut gz":


print("email: mgoz@jmail.com")
print("tel : 02161231212")
print("ehir: istanbul")

else:
print("Aradnz kii veritabannda yok!")

Artk kullanc ahmet z de yazsa, Ahmet z de yazsa, hatta AhMeT Z de yazsa programmz
doru alacaktr. Peki bu nasl oluyor? Elbette lower() metodu sayesinde...
Yukardaki rneklerin de bize gsterdii gibi, lower() metodu, karakter dizisindeki btn
hareri kk harfe eviriyor. rnein:
>>> kardiz = "ELMA"
>>> kardiz.lower()

'elma'

>>> kardiz = "arMuT"


>>> kardiz.lower()

'armut'

>>> kardiz = "PYTHON PROGRAMLAMA"


>>> kardiz.lower()

'python programlama'

Eer karakter dizisi zaten tamamen kk harerden oluuyorsa bu metot hibir ilem
yapmaz:

17.3. lower() 261


Python 3 iin Trke Klavuz, Srm 3

>>> kardiz = "elma"


>>> kardiz.lower()

'elma'

te verdiimiz rnek programda da lower() metodunun bu zelliinden yararlandk. Bu


metot sayesinde, kullanc ne tr bir kelime girerse girsin, bu kelimeler her halkarda kk
harfe evrilecei iin, if bloklar kullancdan gelen veriyi yakalayabilecektir.
Grdnz gibi, son derece kolay ve kullanl bir metot bu. Ama bu metodun bir problemi
var. u rnei dikkatlice inceleyin:
>>> il = "STANBUL"
>>> print(il.lower())

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
File "C:\Python33\lib\encodings\cp857.py", line 19, in encode
return codecs.charmap_encode(input,self.errors,encoding_map)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u0307' in position
1: character maps to <undefined>

Buradaki problem harnden kaynaklanyor. Python programlama dili bu har Trkeye


uygun bir ekilde kltemedii iin yukardaki hatay alyoruz. Yukardaki hatann tam olarak
ne anlama geldiini birka blm sonra anlayacaksnz. Biz imdilik sadece Pythonn harni
Trkeye uygun olarak kltemediini bilelim yeter.
Bir de u rnee bakalm:
>>> il = "ADIYAMAN"
>>> print(il.lower())

adiyaman

Grdnz gibi, Python programlama dili I harni de dzgn kltemiyor. I harnin


kk biimi olmas gerekirken, bu metot I harni i diye kltyor. Yani:
>>> "I".lower()

'i'

Peki bu durumda ne yapacaz? Elimiz kolumuz bal oturacak myz? Elbette hayr! Biz bu tr
kk sorunlar aabilecek kadar Python bilgisine sahibiz. ve I hareri ile ilgili problemi,
yalnzca mevcut bilgilerimizi kullanarak rahatlkla zebiliriz:

iller = "ISPARTA, ADIYAMAN, DYARBAKIR, AYDIN, BALIKESR, ARI"

iller = iller.replace("I", "").replace("", "i").lower()


print(iller)

Bu kodlarla yaptmz ey ok basit:


1. lk replace() metoduyla karakter dizisi iinde geen btn I harerini, ile
deitiriyoruz.
2. kinci replace() metoduyla karakter dizisi iinde geen btn harerini i ile
deitiriyoruz.

262 Blm 17. Karakter Dizilerinin Metotlar


Python 3 iin Trke Klavuz, Srm 3

3. Bu iki ilemin ardndan karakter dizisi iinde geen I ve harerini kltm olduk.
Ancak teki harer henz klmedi. O yzden de karakter dizimiz zerine bir de
lower() metodunu uyguluyoruz. Bylece btn harer dzgn bir ekilde klm
oluyor.
4. Bu kodlarda farkl metotlar u uca nasl eklediimize dikkat edin.
Bu rnek size unu gstermi olmal: Aslnda programlama dediimiz ey gerekten de ok
basit paralarn uygun bir ekilde birletirilmesinden ibaret. Tpk bir yap-bozun paralarn
birletirmek gibi...
Ayrca bu rnek sizi bir gerekle daha tantryor: Grdnz gibi, artk Pythonda
o kadar ilerlediniz ki Pythonn problemlerini tespit edip bu problemlere zm dahi
retebiliyorsunuz!

17.4 upper()

Bu metot biraz nce rendiimiz lower() metodunun yapt iin tam tersini yapar.
Hatrlarsanz lower() metodu yardmyla karakter dizileri iindeki hareri kltyorduk.
upper() metodu ise bu hareri bytmemizi salar.
rnein:
>>> kardiz = "kalem"
>>> kardiz.upper()

'KALEM'

lower() metodunu anlatrken, kullancdan gelen verileri belli bir dzene sokmak konusunda
bu metodun olduka faydal olduunu sylemitik. Kullancdan gelen verilerin lower()
metodu yardmyla standart bir hale getirilmesi sayesinde, kullancnn girdii kelimelerin
byk-kk hari olmasnn nemli olmad programlar yazabiliyoruz. Elbette eer
isterseniz kullancdan gelen btn verileri lower() metoduyla kk harfe evirmek yerine,
upper() metoduyla byk harfe evirmeyi de tercih edebilirsiniz. Python programclar
genellikle kullanc verilerini standart bir hale getirmek iin btn hareri kltmeyi tercih
eder, ama tabii ki sizin bunun tersini yapmak istemenizin nnde hibir engel yok.
Diyelim ki, ehirlere gre hava durumu bilgisi veren bir program yazmak istiyorsunuz. Bunun
iin yle bir kod yazarak ie balayabilirsiniz:
ehir = input("Hava durumunu renmek iin bir ehir ad girin: ")

if ehir == "ADANA":
print("paral bulutlu")

elif ehir == "ERZURUM":


print("karla kark yamurlu")

elif ehir == "ANTAKYA":


print("ak ve gneli")

else:
print("Girdiiniz ehir veritabannda yok!")

Burada programmzn doru alabilmesi, kullancnn ehir adlarn byk hare girmesine
baldr. rnein programmz ADANA cevabn kabul edecek, ama mesela Adana cevabn

17.4. upper() 263


Python 3 iin Trke Klavuz, Srm 3

kabul etmeyecektir. Bunu engellemek iin lower() metodunu kullanabileceimizi biliyoruz.


Bu sorunu zmek iin ayn ekilde upper() metodunu da kullanabiliriz:
ehir = input("Hava durumunu renmek iin bir ehir ad girin: ")

ehir = ehir.upper()

if ehir == "ADANA":
print("paral bulutlu")

elif ehir == "ERZURUM":


print("karla kark yamurlu")

elif ehir == "ANTAKYA":


print("ak ve gneli")

else:
print("Girdiiniz ehir veritabannda yok!")

Burada yazdmz ehir = ehir.upper() kodu sayesinde artk kullanc ehir adn byk
hare de girse, kk hare de girse programmz dzgn alacaktr.
Hatrlarsanz lower() metodunu anlatrken bu metodun baz Trke karakterlerle problemi
olduunu sylemitik. Ayn sorun, tahmin edebileceiniz gibi, upper() metodu iin de
geerlidir.
Dikkatlice inceleyin:
>>> kardiz = "istanbul"
>>> kardiz.upper()

'ISTANBUL'

lower() metodu Trkedeki I harni i eklinde kltyordu. upper() metodu ise i harni
yanl olarak I eklinde bytyor. Elbette bu sorun da zlemeyecek gibi deil. Burada da
lower() metodu iin uyguladmz yntemin bir benzerini uygulayacaz:
iller = "istanbul, izmir, siirt, mersin"

iller = iller.replace("i", "").upper()


print(iller)

Bu kodlarla, nce karakter dizisi iinde geen i harerini ile deitiriyoruz. Bylece yle
bir ey elde etmi oluyoruz:
stanbul, zmr, srt, mersn

Grdnz gibi teki harer eski hallerinde kald. teki hareri de bytebilmek iin
karakter dizisine upper() metodunu uygulamamz yeterli olacaktr.
Bir sorunun daha stesinden geldiimize gre kendimizden emin bir ekilde bir sonraki
metodumuzu incelemeye geebiliriz.

264 Blm 17. Karakter Dizilerinin Metotlar


Python 3 iin Trke Klavuz, Srm 3

17.5 islower(), isupper()

Yukarda rendiimiz lower() ve upper() adl metotlar karakter dizileri zerinde baz
deiiklikler yapmamza yardmc oluyor. Karakter dizileri zerinde birtakm deiiklikler
yapmamz salayan bu tr metotlara deitirici metotlar ad verilir. Bu tr metotlarn
dnda bir de sorgulayc metotlardan sz edebiliriz. Sorgulayc metotlar, deitirici
metotlarn aksine, bir karakter dizisi zerinde deiiklik yapmamz salamaz. Bu tr
metotlarn grevi karakter dizilerinin durumunu sorgulamaktr. Sorgulayc metotlara rnek
olarak islower() ve isupper() metotlarn verebiliriz.
Bildiiniz gibi, lower() metodu bir karakter dizisini tamamen kk harerden oluacak ekle
getiriyordu. islower() metodu ise bir karakter dizisinin tamamen kk harerden oluup
olumadn sorguluyor.
Hemen bir rnek verelim:
>>> kardiz = "istihza"
>>> kardiz.islower()

True

istihza tamamen kk harerden oluan bir karakter dizisi olduu iin islower() sorgusu
True kts veriyor. Bir de una bakalm:
>>> kardiz = "Ankara"
>>> kardiz.islower()

False

Ankara ise iinde bir adet byk harf barndrd iin islower() sorgusuna False cevab
veriyor.
Yazdnz programlarda, rnein, kullancdan gelen verinin sadece kk harerden
olumasn istiyorsanz bu metottan yararlanarak kullancdan gelen verinin gerekten
tamamen kk harerden oluup olumadn denetleyebilirsiniz:
veri = input("Adnz: ")

if not veri.islower():
print("Ltfen isminizi sadece kk harflerle yazn")

isupper() metodu da islower() metodunun yapt iin tam tersini yapar. Bildiiniz gibi,
upper() metodu bir karakter dizisini tamamen byk harerden oluacak ekle getiriyordu.
isupper() metodu ise bir karakter dizisinin tamamen byk harerden oluup olumadn
sorguluyor:
>>> kardiz = "STHZA"
>>> kardiz.isupper()

True

>>> kardiz = "python"


>>> kardiz.isupper()

False

17.5. islower(), isupper() 265


Python 3 iin Trke Klavuz, Srm 3

Tpk islower() metodunda olduu gibi, isupper() metodunu da kullancdan gelen verinin
byk hari mi yoksa kk hari mi olduunu denetlemek iin kullanabilirsiniz.
rnein, internet kltrnde kullanclarn forum ve e.posta listesi gibi yerlerde tamam
byk harerden oluan kelimelerle yazmas kaba bir davran olarak kabul edilir.
Kullanclarn tamam byk harerden oluan kelimeler kullanmasn engellemek iin
yukardaki metotlardan yararlanabilirsiniz:
veri = input("mesajnz: ")
bl = veri.split()

for i in bl:
if i.isupper():
print("Tamam byk harflerden oluan kelimeler kullanmayn!")

Burada kullancnn girdii mesaj iindeki her kelimeyi tek tek sorgulayabilmek iin ncelikle
split() metodu yardmyla karakter dizisini paralarna ayrdmza dikkat edin. bl =
veri.split() satrnn tam olarak ne ie yaradn anlamak iin bu program bir de o satr
olmadan altrmay deneyebilirsiniz.
islower() ve isupper() metotlar programlamada sklkla kullanlan karakter dizisi
metotlarndan ikisidir. Dolaysyla bu iki metodu iyi renmek programlama maceranz
srasnda ilerinizi epey kolaylatracaktr.

17.6 endswith()

Tpk isupper() ve islower() metotlar gibi, endswith() metodu da sorgulayc metotlardan


biridir. endswith() metodu karakter dizileri zerinde herhangi bir deiiklik yapmamz
salamaz. Bu metodun grevi karakter dizisinin durumunu sorgulamaktr.
Bu metot yardmyla bir karakter dizisinin hangi karakter dizisi ile bittiini sorgulayabiliyoruz.
Yani rnein:
>>> kardiz = "istihza"
>>> kardiz.endswith("a")

True

Burada, deeri istihza olan kardiz adl bir karakter dizisi tanmladk. Daha sonra da
kardiz.endswith("a") ifadesiyle bu karakter dizisinin a karakteri ile bitip bitmediini
sorguladk. Gerekten de istihza karakter dizisinin sonunda a karakteri bulunduu iin
Python bize True cevab verdi. Bir de una bakalm:
>>> kardiz.endswith("z")

False

Bu defa da False kts aldk. nk karakter dizimiz z haryle bitmiyor.


Gelin isterseniz elimizi altrmak iin bu metotla birka rnek daha yapalm:
d1 = "python.ogg"
d2 = "tkinter.mp3"
d3 = "pygtk.ogg"
d4 = "movie.avi"
d5 = "sarki.mp3"

266 Blm 17. Karakter Dizilerinin Metotlar


Python 3 iin Trke Klavuz, Srm 3

d6 = "filanca.ogg"
d7 = "falanca.mp3"
d8 = "dosya.avi"
d9 = "perl.ogg"
d10 = "c.avi"
d11 = "c++.mp3"

for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if i.endswith(".mp3"):
print(i)

Bu rnekte, elimizde farkl uzantlara sahip baz dosyalar olduunu varsaydk ve bu dosya
adlarnn herbirini ayr birer deiken iinde depoladk. Grdnz gibi, dosya uzantlar
.ogg, .mp3 veya .avi. Bizim burada amacmz elimizdeki mp3 dosyalarn listelemek. Bu ilem
iin endswith() metodundan yararlanabiliyoruz. Burada yaptmz ey u:
ncelikle d1, d2, d3, d4, d5, d6, d7, d8, d9, d10 ve d11 adl deikenleri bir for dngs
iine alyoruz ve bu deikenlerinin herbirinin ieriini tek tek kontrol ediyoruz (for i in d1,
d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:). Ardndan, eer baktmz bu deikenlerin
deerleri .mp3 ifadesi ile bitiyorsa (if i.endswith(".mp3"):), lte uyan btn karakter
dizilerini ekrana dkyoruz (print(i)).
Yukardaki rnei, dilerseniz, endswith() metodunu kullanmadan yle de yazabilirsiniz:
for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if i[-4:len(i)] == ".mp3":
print(i)

Burada karakter dizilerinin dilimlenebilme zelliinden yararlandk. Ancak grdnz gibi,


dilimlenecek ksm ayarlamaya uramak yerine endswith() metodunu kullanmak ok daha
mantkl ve kolay bir yntemdir.
Yukardaki rnekte de grdnz gibi, endswith() metodu zellikle dosya uzantlarna gre
dosya trlerini tespit etmede olduka ie yarar bir metottur.

17.7 startswith()

Bu metot, biraz nce grdmz endswith() metodunun yapt iin tam tersini yapar.
Hatrlarsanz endswith() metodu bir karakter dizisinin hangi karakter veya karakterlerle
bittiini denetliyordu. startswith() metodu ise bir karakter dizisinin hangi karakter veya
karakterlerle baladn denetler:
>>> kardiz = "python"
>>> kardiz.startswith("p")

True

>>> kardiz.startswith("a")

False

Grdnz gibi, eer karakter dizisi gerekten belirtilen karakterle balyorsa Python True
kts, yok eer belirtilen karakterle balamyorsa False kts veriyor.
Bu metodun gerek hayatta nasl kullanlabileceine dair bir rnek verelim:

17.7. startswith() 267


Python 3 iin Trke Klavuz, Srm 3

d1 = "python.ogg"
d2 = "tkinter.mp3"
d3 = "pygtk.ogg"
d4 = "movie.avi"
d5 = "sarki.mp3"
d6 = "filanca.ogg"
d7 = "falanca.mp3"
d8 = "dosya.avi"
d9 = "perl.ogg"
d10 = "c.avi"
d11 = "c++.mp3"

for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if i.startswith("p"):
print(i)

Burada p haryle balayan btn dosyalar listeledik. Elbette ayn etkiyi u ekilde de elde
edebilirsiniz:
for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if i[0] == "p":
print(i)

Sadece tek bir har sorguluyorsanz yukardaki yntem de en az startswith() metodunu


kullanmak kadar pratiktir. Ama birden fazla karakteri sorguladnz durumlarda elbette
startswith() ok daha mantkl bir tercih olacaktr:
for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if i.startswith("py"):
print(i)

Yukarda yazdmz kodu dilimleme tekniinden yararlanarak yeniden yazmak isterseniz


yle bir eyler yapmanz gerekiyor:
for i in d1, d2, d3, d4, d5, d6, d7, d8, d9, d10, d11:
if i[:2] == "py":
print(i)

Dediim gibi, birden fazla karakteri sorguladnz durumlarda, dilimlemek istediiniz ksmn
karakter dizisi iinde hangi arala denk geldiini hesaplamaya uramak yerine, daha kolay
bir yntem olan startswith() metodundan yararlanmay tercih edebilirsiniz.
Bylece karakter dizilerinin 2. blmn de bitirmi olduk. Sonraki blmde yine karakter
dizilerinin metotlarndan sz etmeye devam edeceiz.

268 Blm 17. Karakter Dizilerinin Metotlar


BLM 18

Karakter Dizilerinin Metotlar (Devam)

Karakter dizileri konusunun en banda sylediimiz gibi, karakter dizileri metot ynnden
bir hayli zengin bir veri tipidir. Bir nceki blmde karakter dizileri metotlarnn bir ksmn
incelemitik. Bu blmde yine metotlar incelemeye devam edeceiz.

18.1 capitalize()

Hatrlarsanz, bir nceki blmde rendiimiz startswith() ve endswith() metotlar


karakter dizileri zerinde herhangi bir deiiklik yapmyordu. Bu iki metodun grevi, karakter
dizilerini sorgulamamz salamakt. imdi greceimiz capitalize() metodu ise karakter
dizileri zerinde deiiklik yapmamz salayacak. Dolaysyla bu capitalize() metodu da
deitirici metotlardan biridir diyebiliriz.
Hatrlarsanz, upper() ve lower() metotlar bir karakter dizisi iindeki btn karakterleri
etkiliyordu. Yani mesela upper() metodunu bir karakter dizisine uygularsak, o karakter
dizisi iindeki btn karakterler byk harfe dnecektir. Ayn ekilde lower() metodu da
bir karakter dizisi iindeki btn karakterleri kk harfe evirir.
imdi greceimiz capitalize() metodu da upper() ve lower() metotlarna benzemekle
birlikte onlardan biraz daha farkl davranr: capitalize() metodunun grevi karakter
dizilerinin yalnzca ilk harni bytmektir. rnein:
>>> a = "python"
>>> a.capitalize()

'Python'

Bu metodu kullanrken dikkat etmemiz gereken bir nokta var: Bu metot bir karakter dizisinin
yalnzca ilk harni bytr. Yani birden fazla kelimeden oluan karakter dizilerine bu metodu
uyguladmzda btn kelimelerin ilk har bymez. Yalnzca ilk kelimenin ilk har byr.
Yani:
>>> a = "python programlama dili"
>>> a.capitalize()

'Python programlama dili'

python programlama dili kelimeden oluan bir karakter dizisidir. Bu karakter dizisi
zerine capitalize() metodunu uyguladmzda bu kelimenin tamamnn ilk hareri
bymyor. Yalnzca ilk python kelimesinin ilk har bu metottan etkileniyor.

269
Python 3 iin Trke Klavuz, Srm 3

Bu arada capitalize() metodunu kullanrken bir ey dikkatinizi ekmi olmal. Bu metodun


da, tpk upper() ve lower() metotlarnda olduu gibi, Trke karakterlerden bazlar ile ufak
bir problemi var. Mesela u rnee bir bakn:
>>> kardiz = "istanbul"
>>> kardiz.capitalize()

'Istanbul'

istanbul kelimesinin ilk har bytldnde olmas gerekirken I oldu. Bildiiniz gibi bu
problem , , , ve gibi teki Trke karakterlerde karmza kmaz. Sadece i ve
hareri karakter dizisi metotlarnda bize problem karacaktr. Ama endie etmemize hi
gerek yok. Bu sorunu da basit bir if-else yapsyla zebilecek kadar Python bilgisine sahibiz:
kardiz = "istanbul bykehir belediyesi"

if kardiz.startswith("i"):
kardiz = "" + kardiz[1:]

kardiz = kardiz.capitalize()

print(kardiz)

Burada yaptmz ey u: Eer deikenin tuttuu karakter dizisi i har ile balyorsa,
"" + kardiz[1:] kodunu kullanarak karakter dizisinin ilk har dnda kalan ksmyla
harni birletiriyoruz. Bu yapy daha iyi anlayabilmek iin etkileimli kabukta u denemeleri
yapabilirsiniz:
>>> kardiz = "istanbul"
>>> kardiz[1:]

'stanbul'

Grdnz gibi, kardiz[1:] kodu bize karakter dizisinin ilk har hari geri kalan ksmn
veriyor. Bu yapy dilimleme konusundan hatrlyor olmalsnz. te biz dilimleme tekniinin
bu zelliinden yararlanarak, karakter dizisinin ilk harni kesip, ba tarafa bir adet har
ekliyoruz:
>>> "" + kardiz[1:]

'stanbul'

Hatrlarsanz karakter dizilerinin deitirilemeyen bir veri tipi olduunu sylemitik. O


yzden, karakter dizisinin stanbul ksmn haryle birletirdikten sonra, bu deiikliin
kalc olabilmesi iin kardiz = "" + kardiz[1:] kodu yardmyla, yaptmz deiiklii
tekrar kardiz adl bir deikene atyoruz.
Bylece;
if kardiz.startswith("i"):
kardiz = "" + kardiz[1:]

kodlarnn ne yaptn anlam olduk. Kodlarn geri kalannda ise yle bir kod blou
gryoruz:
kardiz = kardiz.capitalize()

270 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

Buna gre, hangi hare balarsa balasn Pythonn standart capitalize() metodunu bu
karakter dizisi zerine uyguluyoruz.
Son olarak da print(kardiz) kodunu kullanarak yeni karakter dizisini ekrana yazdryoruz
ve bylece capitalize() metodundaki Trke karakter sorununu kvrak bir almla am
oluyoruz.

18.2 title()

Bu metot biraz nce rendiimiz capitalize() metoduna benzer. Bildiiniz gibi


capitalize() metodu bir karakter dizisinin yalnzca ilk harni bytyordu. title() metodu
da karakter dizilerinin ilk harni bytr. Ama capitalize() metodundan farkl olarak
bu metot, birden fazla kelimeden oluan karakter dizilerinin her kelimesinin ilk harerini
bytr.
Bunu bir rnek zerinde anlatsak sanrm daha iyi olacak:
>>> a = "python programlama dili"
>>> a.capitalize()

'Python programlama dili'

>>> a.title()

'Python Programlama Dili'

capitalize() metodu ile title() metodu arasndaki fark bariz bir biimde grnyor.
Dediimiz gibi, capitalize() metodu yalnzca ilk kelimenin ilk harni bytmekle yetinirken,
title() metodu karakter dizisi iindeki btn kelimelerin ilk harerini bytyor.
Tahmin edebileceiniz gibi, capitalize() metodundaki Trke karakter problemi title()
metodu iin de geerlidir. Yani:
>>> kardiz = "istanbul"
>>> kardiz.title()

'Istanbul'

>>> kardiz = "istanbul bykehir belediyesi"


>>> kardiz.title()

'Istanbul Bykehir Belediyesi'

Grdnz gibi, burada da Python i harni dzgn bytemedi. Ama tabii ki bu bizi
durduramaz! zmmz hazr:
kardiz = "istanbul"

if kardiz.startswith("i"):
kardiz = "" + kardiz[1:]
kardiz = kardiz.title()
else:
kardiz = kardiz.title()

print(kardiz)

18.2. title() 271


Python 3 iin Trke Klavuz, Srm 3

Bu kodlarn capitalize() metodunu anlatrken verdiimiz koda ne kadar benzediini


gryorsunuz. Bu iki kod hemen hemen birbirinin ayns. Tek fark, en sondaki
kardiz.capitalize() kodunun burada kardiz.title() olmas ve if blou iine ek
olarak kardiz = kardiz.title() satrn yazm olmamz. kardiz.capitalize() kodunun
neden kardiz.title() koduna dntn aklamaya gerek yok. Ama eer kardiz =
kardiz.title() kodunun ne ie yaradn tam olarak anlamadysanz o satr silin ve kardiz
deikeninin deerini istanbul bykehir belediyesi yapn. Yani:
kardiz = "istanbul bykehir belediyesi"

if kardiz.startswith("i"):
kardiz = "" + kardiz[1:]
else:
kardiz = kardiz.title()

print(kardiz)

Bu kodlar bu ekilde altrrsanz u kty alrsnz:


stanbul bykehir belediyesi

Burada yalnzca ilk kelimenin ilk har byd. Halbuki title() metodunun ileyii gereince
karakter dizisi iindeki btn kelimelerin ilk harerinin bymesi gerekiyordu. te o satr
btn kelimelerin ilk harerinin bymesini salyor. Eer bir kelimenin ilk har zaten
bykse title() metodu bu harfe dokunmaz, ama karakter dizisi iindeki br kelimelerin
ilk harerini yine de bytr.
te yukarda title() metodunun bu zelliinden faydalanyoruz. kardiz = "" +
kardiz[1:] komutu karakter dizisinin ilk kelimesinin ilk harni dzgn bir ekilde bytyor,
ama geri kalan kelimelere hibir ey yapmyor. kardiz = kardiz.title() komutu ise
karakter dizisi iindeki geri kalan kelimelerin ilk harerini bytyor. Bylece istediimiz
kty elde edebilmi oluyoruz. Yalnz bu kodlarda bir ey dikkatinizi ekmi olmal.
kardiz = kardiz.title() komutunu program iinde iki yerde kullandk. Programclktaki
en nemli ilkelerden biri de mmkn olduunca tekrardan kanmaktr. Eer yazdnz
bir programda ayn kodlar program boyunca tekrar tekrar yazyorsanz muhtemelen bir
yerde hata yapyorsunuzdur. yle bir durumda yapmanz gereken ey kodlarnz tekrar
gzden geirip, tekrar eden kodlar nasl azaltabileceinizi dnmektir. te burada da byle
bir tekrar sz konusu. Biz tekrara dmekten kurtulmak iin yukardaki kodlar yle de
yazabiliriz:
kardiz = "istanbul bykehir belediyesi"

if kardiz.startswith("i"):
kardiz = "" + kardiz[1:]

kardiz = kardiz.title()

print(kardiz)

kardiz = kardiz.title() komutunu hem if blounda, hem de else blounda kullandmz


iin, programmz her koulda bu kodu zaten altracak. O yzden bu satr if blouna
yazdktan sonra bir de ayn eyi else blou iine yazmak gereksiz. Onun yerine else blounu
tamamen kaldrp, o satr if blounun kna yerletirebiliriz.
Eski kodlardaki mantk ileyii yle idi:

272 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

1. kardiz adl bir deiken tanmla


2. Eer kardiz i har ile balyorsa (if), kardiz in ilk har hari geri kalan ksm ile harni
birletir.
3. Daha sonra kardiz deikenine title() metodunu uygula.
4. Eer kardiz i har ile deil de baka bir hare balyorsa (else), kardiz deikenine
title() metodunu uygula.
5. Son olarak kardiz deikenini yazdr.
Tekrar eden kodlar kardktan sonra ise kodlarmzn mantk ileyii yle oldu:
1. kardiz adl bir deiken tanmla
2. Eer kardiz i har ile balyorsa (if), kardiz in ilk har hari geri kalan ksm ile harni
birletir.
3. Daha sonra kardiz deikenine title() metodunu uygula.
4. Son olarak kardiz deikenini yazdr.
Grdnz gibi, ayn sonuca daha ksa bir yoldan ulaabiliyoruz.
Ama bir dakika! Burada bir sorun var!
Bu kodlar i harnin karakter dizisinin yalnzca en banda yer ald durumlarda dzgn
alacaktr. Bu kodlar mesela u karakter dizisini dzgn bytemez:
on iki ada

Ayn ekilde bu kodlar u karakter dizisini de bytemez:


hkmet istifa!

nk bu karakter dizilerinde i har karakter dizisini oluturan kelimelerin ilkinde yer


almyor. Bizim yazdmz kod ise yalnzca ilk kelime dnlerek yazlm. Peki bu sorunun
stesinden nasl geleceiz?
Evet, doru tahmin ettiniz. Bizi kurtaracak ey split() metodu ve basit bir for dngs.
Dikkatlice bakn:
kardiz = "on iki ada"

for kelime in kardiz.split():


if kelime.startswith("i"):
kelime = "" + kelime[1:]

kelime = kelime.title()

print(kelime, end=" ")

Bu defa istediimizi gerekletiren bir kod yazabildik. Bu kodlar, i har karakter dizisini
oluturan kelimelerin hangisinde bulunursa bulunsun, karakter dizisini Trkeye uygun bir
ekilde bytebilecektir.
Bir nceki kodlara gre, bu son kodlardaki tek farkn split() metodu ve for dngs
olduuna dikkat edin.
Bu kodlar daha iyi anlayabilmek iin etkileimli kabukta kendi kendinize baz deneme
almalar yapabilirsiniz:

18.2. title() 273


Python 3 iin Trke Klavuz, Srm 3

>>> kardiz = "on iki ada"


>>> kardiz.split()

['on', 'iki', 'ada']

>>> for kelime in kardiz.split():


... print(kelime[0])
...
o
i
a

Grdnz gibi, split() metodu "on iki ada" adl karakter dizisini kelimelerine ayryor.
te biz de kelimelerine ayrlm bu yap zerinde bir for dngs kurarak herbir enin ilk
harnin i olup olmadn kontrol edebiliyoruz.

18.3 swapcase()

swapcase() metodu da byk-kk hare ilgili bir metottur. Bu metot bir karakter dizisi
iindeki byk hareri kk harfe; kk hareri de byk harfe dntrr. rnein:
>>> kardiz = "python"
>>> kardiz.swapcase()

'PYTHON'

>>> kardiz = "PYTHON"


>>> kardiz.swapcase()

'python'

>>> kardiz = "Python"


>>> kardiz.swapcase()

'pYTHON'

Grdnz gibi, bu metot aynen dediimiz gibi iliyor. Yani kk hareri byk harfe;
byk hareri de kk harfe dntryor.
Yine tahmin edebileceiniz gibi, bu metodun da baz Trke karakterlerle problemi var:
>>> kardiz = "istihza"
>>> kardiz.swapcase()

'ISTIHZA'

Bu sorunu da amak tabii ki bizim elimizde:


kardiz = "istanbul"

for i in kardiz:
if i == '':
kardiz = kardiz.replace('', 'i')
elif i == 'i':
kardiz = kardiz.replace('i', '')
else:

274 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

kardiz = kardiz.replace(i, i.swapcase())

print(kardiz)

Daha nceki rneklerde de olduu gibi, bu kodlarda da i ve I harerini tek tek kontrolden
geiriyoruz. Eer bir karakter dizisi iinde bu iki harften biri varsa, bunlarn byk harf veya
kk harf karlklarn elle yerine koyuyoruz. Bu karakterler dnda kalan karakterlere ise
dorudan swapcase() metodunu uygulayarak istediimiz sonucu elde ediyoruz. Bu kodlarda
kafanza yatmayan yerler varsa, kodlar iinde kendinize gre baz eklemeler karmalar
yaparak neyin ne ie yaradn daha kolay anlayabilirsiniz.

18.4 casefold()

Bu metot ilev olarak lower() metoduna ok benzer. Hatta Trke asndan, bu metodun
lower() metodundan hibir fark yoktur. Ancak baz baka dillerde, bu metot baz harer
iin lower() metodunun verdiinden farkl bir kt verir. rnein Almancadaki har bu
duruma bir rnek olabilir:
>>> "".lower()
''

>>> "".casefold()
'ss'

Grdnz gibi, lower() ve casefold() metotlar bu harfe farkl davranyor.


Trkedeki -i sorunu bu metot iin de aynen geerlidir.

18.5 strip(), lstrip(), rstrip()

Bu balkta birbiriyle balantl adet karakter dizisi metodunu inceleyeceiz. Bu metotlar


strip(), lstrip() ve rstrip(). lk olarak strip() metoduyla balayalm.
Zaman zaman, iinde anlamsz ya da gereksiz karakterler barndran metinleri bu anlamsz
ve gereksiz karakterlerden temizlemeniz gereken durumlarla karlaabilirsiniz. rnein
arkadanzdan gelen bir e.postada her satrn banda ve/veya sonunda > gibi bir karakter
olabilir. Arkadanzdan gelen bu e.postay kullanabilmek iin ncelikle metin iindeki o >
karakterlerini silmeniz gerekebilir. Hepimizin bildii gibi, bu tr karakterleri elle temizlemeye
kalkmak son derece skc ve zaman alc bir yntemdir. Ama artk siz bir Python programcs
olduunuza gre bu tr angaryalar Pythona devredebilirsiniz.
Yukarda bahsettiimiz duruma ynelik bir rnek vermeden nce dilerseniz strip()
metoduyla ilgili ok basit rnekler vererek balayalm ie:
>>> kardiz = " istihza "

Burada deeri istihza olan kardiz adl bir karakter dizisi tanmladk. Dikkat ederseniz
bu karakter dizisinin sanda ve solunda birer boluk karakteri var. Baz durumlarda
kullancdan ya da baka kaynaktan gelen karakter dizilerinde bu tr istenmeyen boluklar
olabilir. Ama sizin kullancdan veya baka bir kaynaktan gelen o karakter dizisini dzgn
kullanabilmeniz iin ncelikle o karakter dizisinin sanda ve solunda bulunan boluk

18.4. casefold() 275


Python 3 iin Trke Klavuz, Srm 3

karakterlerinden kurtulmanz gerekebilir. te byle anlarda strip() metodu yardmnza


yetiecektir. Dikkatlice inceleyin:
>>> kardiz = " istihza "
>>> print(kardiz)

' istihza '

>>> kardiz.strip()

'istihza'

Grdnz gibi, strip() metodunu kullanarak, karakter dizisinin orijinalinde bulunan sal
sollu boluk karakterlerini bir rpda ortadan kaldrdk.
strip() metodu yukardaki rnekte olduu gibi parametresiz olarak kullanldnda, bir
karakter dizisinin sanda veya solunda bulunan belli bal karakterleri krpar. strip()
metodunun ntanml olarak krpt karakterler unlardr:
boluk karakteri
\t sekme (TAB) oluturan ka dizisi
\n satr bana geiren ka dizisi
\r imleci ayn satrn bana dndren ka dizisi
\v dey sekme oluturan ka dizisi
\f yeni bir sayfaya geiren ka dizisi
Yani eer strip() metoduna herhangi bir parametre vermezsek bu metot otomatik olarak
karakter dizilerinin sanda ve solunda bulunan yukardaki karakterleri krpacaktr. Ancak
eer biz istersek strip() metoduna bir parametre vererek bu metodun istediimiz herhangi
baka bir karakteri krpmasn da salayabiliriz. rnein:
>>> kardiz = "python"
>>> kardiz.strip("p")

'ython'

Burada strip() metoduna parametre olarak p karakter dizisini vererek, strip()


metodunun, karakter dizisinin banda bulunan p karakterini ortadan kaldrmasn saladk.
Yalnz strip() metodunu kullanrken bir noktaya dikkat etmelisiniz. Bu metot bir karakter
dizisinin hem banda, hem de sonunda bulunan karakterlerle ilgilenir. Mesela u rnee
bakalm:
>>> kardiz = "kazak"
>>> kardiz.strip("k")

'aza'

Grdnz gibi, strip() metoduna k parametresini vererek, kazak adl karakter


dizisinin hem bandaki hem de sonundaki k harerini krpmay baardk. Eer bu metoda
verdiiniz parametre karakter dizisinde gemiyorsa, bu durumda strip() metodu herhangi
bir ilem yapmaz. Ya da aradnz karakter, karakter dizisinin yalnzca tek bir tarafnda
(mesela sadece banda veya sadece sonunda) geiyorsa, strip() metodu, ilgili karakter
hangi taraftaysa onu siler. Aranan karakterin bulunmad taraa ilgilenmez.
strip() metodunu anlatmaya balarken, iinde gereksiz yere > iaretlerinin getii
e.postalardan sz etmi ve bu e.postalardaki o gereksiz karakterleri elle silmenin ne kadar
da skc bir i olduunu sylemitik. Eer e.postalarnzda bu tip durumlarla sk sk

276 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

karlayorsanz, gereksiz karakterleri silme grevini sizin yerinize Python yerine getirebilir.
imdi u kodlar dikkatlice inceleyin:
metin = """
> Python programlama dili Guido Van Rossum adl Hollandal bir programc tarafndan
> 90'l yllarn banda gelitirilmeye balanmtr. ou insan, isminin Python
> olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn dnr.
> Ancak zannedildiinin aksine bu programlama dilinin ad piton ylanndan gelmez.
> Guido Van Rossum bu programlama dilini, The Monty Python adl bir ngiliz komedi
> grubunun, Monty Python's Flying Circus adl gsterisinden esinlenerek adlandrmtr.
> Ancak her ne kadar gerek byle olsa da, Python programlama dilinin pek ok yerde
> bir ylan figr ile temsil edilmesi neredeyse bir gelenek halini almtr diyebiliriz.
"""

for i in metin.split():
print(i.strip("> "), end=" ")

Bu program altrdnzda yle bir kt elde edeceksiniz:


Python programlama dili Guido Van Rossum adl Hollandal bir programc tarafndan
90'l yllarn banda gelitirilmeye balanmtr. ou insan, isminin Python
olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn dnr.
Ancak zannedildiinin aksine bu programlama dilinin ad piton ylanndan gelmez.
Guido Van Rossum bu programlama dilini, The Monty Python adl bir ngiliz komedi
grubunun, Monty Python's Flying Circus adl gsterisinden esinlenerek adlandrmtr.
Ancak her ne kadar gerek byle olsa da, Python programlama dilinin pek ok yerde
bir ylan figr ile temsil edilmesi neredeyse bir gelenek halini almtr diyebiliriz.

Grdnz gibi, her satrn banda bulunan > karakterlerini ufack birka kod yardmyla
rahatlkla temizledik. Burada strip() metoduyla birlikte split() metodunu da kullandmz
gryorsunuz. split() metodu ile nce metin adl karakter dizisini paraladk. Daha sonra
da strip() metodu yardmyla ba taraftaki istenmeyen karakterleri temizledik.
Yukardaki rnekte verdiimiz metin, istenmeyen karakterleri yalnzca tek bir tarafta ieriyor.
Ama elbette istenmeyen karakterler, karakter dizisinin ne tarafnda olursa olsun strip()
metodu bu karakterleri baaryla krpacaktr.
Bu blmn balnda strip() metodu ile birlikte lstrip() ve rstrip() adl iki metodun
daha ad geiyordu. strip() metodunun ne ie yaradn rendik. Peki bu lstrip() ve
rstrip() metotlar ne ie yaryor?
lstrip() metodundan balayalm anlatmaya...
strip() metodunu anlatrken, bu metodun bir karakter dizisinin sanda ve solunda
bulunan istenmeyen karakterleri krptn sylemitik. Ancak bazen, istediimiz ey bu
olmayabilir. Yani biz bir karakter dizisinin hem sanda, hem de solunda bulunan gereksiz
karakterleri deil, yalnzca sanda veya yalnzca solunda bulunan gereksiz karakterleri
krpmak isteyebiliriz. rnein strip() metodunu anlatrken verdiimiz kazak rneini ele
alalm. yle bir komutun ne yapacan biliyorsunuz:
>>> "kazak".strip("k")

Bu komut hem sol, hem de sa taraftaki k karakterlerini krpacaktr. Ama peki ya biz
sadece sol taraftaki k karakterini atmak istersek ne olacak? te byle bir durumda strip()
metodundan deil, lstrip() metodundan faydalanacaz.
lstrip() metodu bir karakter dizisinin sol tarafndaki gereksiz karakterlerden kurtulmamz
salar. Mesela bu bilgiyi yukardaki rnee uygulayalm:

18.5. strip(), lstrip(), rstrip() 277


Python 3 iin Trke Klavuz, Srm 3

>>> "kazak".lstrip("k")

'azak'

Grdnz gibi, lstrip() metodu yalnzca sol bataki k haryle ilgilendi. Sa taraftaki k
harne ise dokunmad. Eer sol taraftaki karakteri deil de yalnzca sa taraftaki karakteri
uurmak istemeniz halinde ise rstrip() metodundan yararlanacaksnz:
>>> "kazak".rstrip("k")

'kaza'

Bu arada, yukardaki metotlar dorudan karakter dizileri zerine uygulayabildiimize de


dikkat edin. Yani u iki yntem de uygun ve dorudur:
>>> kardiz = "karakter dizisi"
>>> kardiz.metot_ad()

veya:
>>> "karakter dizisi".metot_ad()

18.6 join()

Hatrlarsanz imdiye kadar rendiimiz metotlar arasnda split() adl bir metot vard. Bu
metodun ne ie yaradn ve nasl kullanldn biliyorsunuz:
>>> kardiz = "Beikta Jimnastik Kulb"
>>> blnm = kardiz.split()
>>> print(blnm)

['Beikta', 'Jimnastik', 'Kulb']

Grdnz gibi split() metodu bir karakter dizisini belli yerlerden blerek paralara
ayryor. Bu noktada insann aklna yle bir soru geliyor: Diyelim ki elimizde byle blnm
bir karakter dizisi grubu var. Biz bu grup iindeki karakter dizilerini tekrar birletirmek istersek
ne yapacaz?
imdi u kodlara ok dikkatlice bakn:
>>> " ".join(blnm)

'Beikta Jimnastik Kulb'

Grdnz gibi, Beikta Jimnastik Kulb adl karakter dizisinin ilk halini tekrar elde ettik.
Yani bu karakter dizisine ait, blnm paralar tekrar bir araya getirdik. Ancak bu ii yapan
kod gznzne biraz tuhaf ve anlalmaz grnm olabilir.
lk bata dikkatimizi eken ey, bu metodun br metotlara gre biraz daha farkl bir yapya
sahipmi gibi grnmesi. Ama belki yukardaki rnei yle yazarsak bu rnek biraz daha
anlalr gelebilir gznze:
>>> birletirme_karakteri = " "
>>> birletirme_karakteri.join(blnm)

278 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

Burada da tpk teki metotlarda olduu gibi, join() metodunu bir karakter dizisi zerine
uyguladk. Bu karakter dizisi bir adet boluk karakteri. Ayrca grdnz gibi join()
metodu bir adet de parametre alyor. Bu rnekte join() metoduna verdiimiz parametre
blnm adl deiken. Aslnda yle bir dnnce yukardaki kodlarn sanki yle
yazlmas gerekiyormu gibi gelebilir size:
>>> blnm.join(birletirme_karakteri)

Ama bu kullanm yanltr. stelik kodunuzu byle yazarsanz Python size bir hata mesaj
gsterecektir:
>>> blnm.join(birletirme_karakteri)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'join'

Buradaki hata mesaj bize yle diyor: liste nesnesinin join adl bir nitelii yoktur!. Bu
cmledeki liste nesnesi ifadesine zellikle dikkatinizi ekmek istiyorum. Biz imdiye kadar iki
tr nesne (ya da baka bir ifadeyle veri tipi) grmtk. Bunlar karakter dizileri ve saylard.
Burada karmza nc bir nesne kyor. Grdmz kadaryla bu yeni nesnenin ad liste.
(Liste adl veri tipini birka blm sonra en ince ayrntsna kadar inceleyeceiz. Pythonda
byle bir veri tipi olduunu bilmemiz bizim iin imdilik yeterli.)
te yukardaki hatay almamzn nedeni, aslnda karakter dizilerine ait bir metot olan join()
metodunu bir liste zerinde uygulamaya almamz. Byle bir durumda da Python doal
olarak bizi liste nesnelerinin join adl bir nitelii olmad konusunda uyaryor. Btn bu
anlattklarmz bizi u sonuca ulatryor: Bir veri tipine ait metotlar doal olarak yalnzca o
veri tipi zerinde kullanlabilir. Mesela yukardaki rnekte grdmz gibi, bir karakter dizisi
metodu olan join()i baka bir veri tipine uygulamaya alrsak hata alrz.
Sonu olarak, join() adl metodu blnm adl deikene uygulayamayacamz anlam
bulunuyoruz. O halde bu metotla birlikte kullanlmak zere bir karakter dizisi bulmamz
gerekiyor.
En bata da sylediimiz gibi, join() metodunun grevi blnm karakter dizisi gruplarn
birletirmektir. Bu metot grevini yerine getirirken, yani karakter dizisi gruplarn
birletirirken bir birletirme karakterine ihtiya duyar. Bizim rneimizde bu birletirme
karakteri bir adet boluktur. Durumu daha iyi anlayabilmek iin rneimizi tekrar gzmnn
nne getirelim:
>>> kardiz = "Beikta Jimnastik Kulb"
>>> blnm = kardiz.split()
>>> print(blnm)

['Beikta', 'Jimnastik', 'Kulb']

>>> kardiz = " ".join(blnm)


>>> print(kardiz)

Beikta Jimnastik Kulb

Grdnz gibi, orijinal karakter dizisinin blnm paralarn, her bir parann arasnda
bir adet boluk olacak ekilde yeniden birletirdik. Elbette sadece boluk karakteri
kullanabileceiz diye bir kaide yok. Mesela u rneklere bakn:

18.6. join() 279


Python 3 iin Trke Klavuz, Srm 3

>>> kardiz = "-".join(blnm)

Beikta-Jimnastik-Kulb

>>> kardiz = "".join(blnm)

BeiktaJimnastikKulb

lk rnekte, blnm karakter dizilerini - iareti ile birletirdik. kinci rnekte ise bu karakter
dizilerini birletirmek iin bo bir karakter dizisi kullandk. Yani paralar birletirirken arada
boluk olmamasn saladk.
join() metodu ile bol bol pratik yaparak bu metodu hakkyla renmenizi tavsiye ederim.
Zira programclk maceranz boyunca en sk kullanacanz karakter dizisi metotlar listesinin
en balarnda bu metot yer alr.

18.7 count()

Tpk daha nce rendiimiz sorgulayc metotlar gibi, count() metodu da bir karakter dizisi
zerinde herhangi bir deiiklik yapmamz salamaz. Bu metodun grevi bir karakter dizisi
iinde belli bir karakterin ka kez getiini sorgulamaktr. Bununla ilgili hemen bir rnek
verelim:
>>> ehir = "Kahramanmara"
>>> ehir.count("a")

Buradan anlyoruz ki, Kahramanmara adl karakter dizisi iinde toplam 5 adet a karakteri
geiyor.
count() metodu yaygn olarak yukardaki rnekte grld ekilde sadece tek bir parametre
ile kullanlr. Ama aslnda bu metot toplam 3 parametre alr. imdi u rnekleri dikkatlice
inceleyin:
>>> ehir = "adana"
>>> ehir.count("a")

>>> ehir.count("a", 1)

>>> ehir.count("a", 2)

>>> ehir.count("a", 3)

>>> ehir.count("a", 4)

280 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

lk rnekte count() metodunu tek bir parametre ile birlikte kullandmz iin adana adl
karakter dizisi iindeki btn a harerinin toplam says kt olarak verildi.
kinci rnekte ise count() metoduna ikinci bir parametre daha verdik. Bu ikinci parametre,
count() metodunun bir karakteri saymaya balarken karakter dizisinin kanc srasndan
balayacan gsteriyor. Bu rnekte ikinci parametre olarak 1 saysn verdiimiz iin, Python
saymaya adana karakter dizisinin 1. srasndan balayacak. Dolaysyla 0. sradaki a
har saym ileminin dnda kalaca iin toplam a says 4 deil 3 olarak grnecek.
Grdnz gibi, sonraki rneklerde de ayn mant takip ettiimiz iin aradmz karakterin
toplam says rnekten rnee farkllk gsteriyor.
Peki bu metodu gerek programlarda ne amala kullanabilirsiniz? Bu metodu kullanarak,
rnein, kullancy ayn karakterden yalnzca bir adet girmeye zorlayabilirsiniz. Bunun iin
mesela yle bir yap kullanabilirsiniz:
parola = input("parolanz: ")

kontrol = True

for i in parola:
if parola.count(i) > 1:
kontrol = False

if kontrol:
print('Parolanz onayland!')
else:
print('Parolanzda ayn harfi bir kez kullanabilirsiniz!')

Burada kontrol deikeninin deerini True olarak belirledik. Eer parola iindeki harerden
herhangi biri 1den fazla geiyorsa bu durumda kontrol deikeninin deerini False
yapyoruz:
for i in parola:
if parola.count(i) > 1:
kontrol = False

Daha sonra da kontrol deikeninin durumuna gre kullancya parolann onayland veya
onaylanmad bilgisini veriyoruz. Buna gre eer kontrol deikeninin deeri True ise u
kty veriyoruz:
Parolanz onayland!

Aksi halde u kty veriyoruz:


Parolanzda ayn harfi bir kez kullanabilirsiniz!

Yukardakine benzer durumlarn dnda count() metodunu yle durumlarda da


kullanabilirsiniz:
kelime = input("Herhangi bir kelime: ")

for harf in kelime:


print("{} harfi {} kelimesinde {} kez geiyor!".format(harf,
kelime,
kelime.count(harf)))

Burada amacmz kullancnn girdii bir kelime iindeki btn harerin o kelime iinde
ka kez getiini bulmak. count() metodunu kullanarak bu ii ok kolay bir ekilde

18.7. count() 281


Python 3 iin Trke Klavuz, Srm 3

halledebiliyoruz. Kullancnn mesela adana kelimesini girdiini varsayarsak yukardaki


program yle bir kt verecektir:
a harfi adana kelimesinde 3 kez geiyor!
d harfi adana kelimesinde 1 kez geiyor!
a harfi adana kelimesinde 3 kez geiyor!
n harfi adana kelimesinde 1 kez geiyor!
a harfi adana kelimesinde 3 kez geiyor!

Ancak burada yle bir problem var: adana kelimesi iinde birden fazla geen harer
(mesela a har) ktda birka kez tekrarlanyor. Yani mesela a harnin getii her yerde
programmz a harnin kelime iinde ka kez getiini rapor ediyor. stediiniz davran bu
olabilir. Ama baz durumlarda her harn kelime iinde ka kez getii bilgisinin yalnzca bir
kez raporlanmasn isteyebilirsiniz. Yani siz yukardaki gibi bir kt yerine yle bir kt elde
etmek istiyor olabilirsiniz:
a harfi adana kelimesinde 3 kez geiyor!
d harfi adana kelimesinde 1 kez geiyor!
n harfi adana kelimesinde 1 kez geiyor!

Byle bir kt elde edebilmek iin yle bir program yazabilirsiniz:


kelime = input("Herhangi bir kelime: ")
saya = ""

for harf in kelime:


if harf not in saya:
saya += harf

for harf in saya:


print("{} harfi {} kelimesinde {} kez geiyor!".format(harf,
kelime,
kelime.count(harf)))

Gelin isterseniz bu kodlar yle bir inceleyelim.


Bu kodlarda ncelikle kullancdan herhangi bir kelime girmesini istiyoruz.
Daha sonra saya adl bir deiken tanmlyoruz. Bu deiken, kullancnn girdii kelime
iindeki hareri tutacak. Bu deiken, kelime deikeninden farkl olarak, kullancnn girdii
szck iinde birden fazla geen harerden yalnzca tek bir rnek ierecek.
Deikenimizi tanmladktan sonra bir for dngs kuruyoruz. Bu dngye dikkatlice bakn.
Kullancnn girdii kelime iinde geen harerden her birini yalnzca bir kez alp saya
deikenine gnderiyoruz. Bylece elimizde her harften sadece bir adet olmu oluyor.
Burada Pythonn arka planda neler evirdiini daha iyi anlayabilmek iin isterseniz dngden
sonra yle bir satr ekleyerek saya deikeninin ieriini inceleyebilir, bylece burada
kullandmz for dngsnn nasl altn daha iyi grebilirsiniz:
print("saya ierii: ", saya)

lk dngmz sayesinde, kullancnn girdii kelime iindeki her har teke indirerek, bu
hareri saya deikeni iinde topladk. imdi yapmamz gereken ey, saya deikenine
gnderilen her bir harn, kelime adl deiken iinde ka kez getiini hesaplamak olmal.
Bunu da yine bir for dngs ile yapabiliriz:

282 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

for harf in saya:


print("{} harfi {} kelimesinde {} kez geiyor!".format(harf,
kelime,
kelime.count(harf)))

Burada yaptmz ey u: count() metodunu kullanarak, saya deikeninin iindeki her bir
harn, kelime deikeninin iinde ka kez getiini buluyoruz. Bu dngnn nasl altn
daha iyi anlayabilmek iin, isterseniz bu dngy u ekilde sadeletirebilirsiniz:
for harf in saya:
print(harf, kelime, kelime.count(harf))

Grdnz gibi, saya deikeni iindeki herbir harn kelime adl karakter dizisi iinde ka
kez getiini tek tek sorguladk.
Yukardaki rneklerde count() metodunun iki farkl parametre aldn grdk. Bu metot
bunlarn dnda nc bir parametre daha alr. Bu nc parametre ikinci parametreyle
ilikilidir. Dilerseniz bu ilikiyi bir rnek zerinde grelim:
>>> kardiz = "python programlama dili"
>>> kardiz.count("a")

>>> kardiz.count("a", 15)

Bu rneklerden anladmza gre, python programlama dili adl karakter dizisi iinde
toplam 3 adet a har var. Eer bu karakter dizisi iindeki a harerini karakter dizisinin
en bandan itibaren deil de, 15. karakterden itibaren saymaya balarsak bu durumda 2
adet a har buluyoruz. imdi de u rnee bakalm:
>>> kardiz.count("a", 15, 17)

Burada, 15. karakter ile 17. karakter arasnda kalan a harerini saym olduk. 15. karakter
ile 17. karakter arasnda toplam 1 adet a har olduu iin de Python bize 1 sonucunu verdi.
Btn bu rneklerden sonra count() metoduna ilikin olarak yle bir tespitte bulunabiliriz:
count() metodu bir karakter dizisi iinde belli bir karakterin ka kez getiini
sorgulamamz salar. rnein bu metodu count("a") eklinde kullanrsak
Python bize karakter dizisi iindeki btn a harerinin saysn verecektir. Eer
bu metoda 2. ve 3. parametreleri de verirsek, sorgulama ilemi karakter
dizisinin belli bir ksmnda gerekletirilecektir. rnein count("a", 4, 7) gibi bir
kullanm, bize karakter dizisinin 4. ve 7. karakterleri arasnda kalan a harerinin
saysn verecektir.
Bylece bir metodu daha ayrntl bir ekilde incelemi olduk. Artk baka bir metot
incelemeye geebiliriz.

18.7. count() 283


Python 3 iin Trke Klavuz, Srm 3

18.8 index(), rindex()

Bu blmn banda karakter dizilerinin dilimlenme zelliinden sz ederken, karakter dizisi


iindeki her harn bir sras olduunu sylemitik. rnein python adl karakter dizisinde
p harnin sras 0 dr. Ayn ekilde n harnin sras ise 5 tir. Karakterlerin, bir karakter dizisi
iinde hangi srada bulunduunu renmek iin index() adl bir metottan yararlanabiliriz.
rnein:
>>> kardiz = "python"
>>> kardiz.index("p")

>>> kardiz.index("n")

Eer srasn sorguladmz karakter, o karakter dizisi iinde bulunmuyorsa, bu durumda


Python bize bir hata mesaj gsterir:
>>> kardiz.index("z")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
ValueError: substring not found

Bu metodun zellii, sorguladmz karakterin, karakter dizisi iinde getii ilk konumu
vermesidir. Yani rnein:
>>> kardiz = "adana"
>>> kardiz.index("a")

adana adl karakter dizisi iinde 3 adet a har var. Ancak biz index() metodu yardmyla
adana karakter dizisi iindeki a harnin konumunu sorgularsak, Python bize a harnin
getii ilk konumu, yani 0. konumu, bildirecektir. Halbuki adana karakter dizisi iinde 2. ve
4. sralarda da birer a har var. Ancak index() metodu 0. konumdaki a harni grdkten
sonra karakter dizisinin geri kalanna bakmaz.
index() metodunu biz yukarda tek bir parametre ile birlikte kullandk. Bu parametre,
karakter dizisi iinde konumunu renmek istediimiz karakteri gsteriyor. Ama bu metot
aslnda toplam 3 parametre alr. u rnekleri dikkatlice inceleyelim:
>>> kardiz = "adana"
>>> kardiz.index("a")

Burada normal bir ekilde index() metodunu tek bir parametre ile birlikte kullandk. Bylece
Python bize a harnin karakter dizisi iinde ilk olarak hangi srada bulunduunu gsterdi. Bir
de u rnee bakalm:
>>> kardiz.index("a", 1)

284 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, bu defa index() metoduna ikinci bir parametre daha verdik. index()
metodunun ikinci parametresi, Pythonn aramaya kanc sradan itibaren balayacan
gsteriyor. Biz yukardaki rnekte Pythonn aramaya 1. sradan itibaren balamasn istedik.
Bu yzden Python 0. sradaki a karakterini es geti ve 2. srada bulunan a karakterini
grd. Bir de una bakalm:
>>> kardiz.index("a", 3)

Bu defa Pythonn aramaya 3. sradan balamasn istedik. Dolaysyla Python 0. ve 2.


sralardaki a harerini grmezden gelip bize 4. sradaki a harnin srasn bildirdi.
Gelelim index() metodunun 3. parametresine... Dilerseniz 3. parametrenin ne ie yaradn
bir rnek zerinde gsterelim:
>>> kardiz = "adana"
>>> kardiz.index("a", 1, 3)

Hatrlarsanz, bundan nce count() adl bir metot renmitik. O metot da toplam 3
parametre alyordu. count() metodunda kullandmz 2. ve 3. parametrelerin grevlerini
hatrlyor olmalsnz. te index() metodunun 2. ve 3. parametreleri de aynen count()
metodundaki gibi alr. Yani Pythonn sorgulama ilemini hangi sra aralklarndan
gerekletireceini gsterir. Mesela yukardaki rnekte biz adana karakter dizisinin 1. ve 3.
sralar arasndaki a harerini sorguladk. Yani yukardaki rnekte Python a harni aramaya
1. konumdan balad ve aramay 3. konumda kesti. Bylece adana karakter dizisinin 2.
srasndaki a harnin konumunu bize bildirdi.
Grdnz gibi, index() metodu bize aradmz karakterin yalnzca ilk konumunu
bildiriyor. Peki biz mesela adana karakter dizisi iindeki btn a harerinin srasn
renmek istersek ne yapacaz?
Bu isteimizi yerine getirmek iin karakter dizisinin her bir srasn tek tek kontrol etmemiz
yeterli olacaktr. Yani yle bir ey yazmamz gerekiyor:
kardiz = "adana"

print(kardiz.index("a", 0))
print(kardiz.index("a", 1))
print(kardiz.index("a", 2))
print(kardiz.index("a", 3))
print(kardiz.index("a", 4))

Buradaki mant anladnz sanyorum. Bildiiniz gibi, index() metodunun ikinci


parametresi sayesinde karakter dizisi iinde aradmz bir karakteri hangi konumdan itibaren
arayacamz belirleyebiliyoruz. rnein yukardaki kodlarda grdnz ilk print() satr
a karakterini 0. konumdan itibaren aryor ve grd ilk a harnin konumunu raporluyor.
kinci print() satr a karakterini 1. konumdan itibaren aryor ve grd ilk a harnin
konumunu raporluyor. Bu sre karakter dizisinin sonuna ulalncaya kadar devam ediyor.
Bylece karakter dizisi iinde geen btn a harerinin konumunu elde etmi oluyoruz.
Elbette yukardaki kodlar, sadece iin mantn anlamanz salamak iin bu ekilde verdik.
Tahmin edebileceiniz gibi, yukardaki kod yazm son derece verimsiz bir yoldur. Ayrca
grdnz gibi, yukardaki kodlar sadece 5 karakter uzunluundaki karakter dizileri iin
geerlidir. Halbuki programlamada esas alnmas gereken yntem, kodlarnz olabildiince
genel amal tutup, farkl durumlarda da alabilmesini salamaktr. Dolaysyla yukardaki

18.8. index(), rindex() 285


Python 3 iin Trke Klavuz, Srm 3

mant u ekilde kodlara dkmek ok daha akllca bir yol olacaktr:


kardiz = "adana"

for i in range(len(kardiz)):
print(kardiz.index("a", i))

Grdnz gibi, yukardaki kodlar yardmyla, bir nceki verimsiz kodlar hem ksalttk, hem
de daha geni kapsaml bir hale getirdik. Hatta yukardaki kodlar yle yazarsanz karakter
dizisi ve bu karakter dizisi iinde aranacak karakteri kullancdan da alabilirsiniz:
kardiz = input("Metin girin: ")
aranacak = input("Aradnz harf: ")

for i in range(len(kardiz)):
print(kardiz.index(aranacak, i))

Bu kodlarda baz problemler dikkatinizi ekmi olmal. Mesela, aranan karakter dizisinin
bulunduu konumlar ktda tekrar ediyor. rnein, kullancnn adana karakter dizisi iinde
a harni aramak istediini varsayarsak programmz yle bir kt veriyor:
0
2
2
4
4

Burada 2 ve 4 saylarnn birden fazla getiini gryoruz. Bunu engellemek iin yle bir
kod yazabiliriz:
kardiz = input("Metin girin: ")
aranacak = input("Aradnz harf: ")

for i in range(len(kardiz)):
if i == kardiz.index(aranacak, i):
print(i)

Bu kodlarla yaptmz ey u: ncelikle karakter dizisinin uzunluunu gsteren say aral


zerinde bir for dngs kuruyoruz. Kullancnn burada yine adana karakter dizisini
girdiini varsayarsak, adana karakter dizisinin uzunluu 5 olduu iin for dngmz yle
grnecektir:
for i in range(5):
...

Daha sonra for dngs iinde tanmladmz i deikeninin deerinin, karakter dizisi iinde
aradmz karakterin konumu ile eleip elemediini kontrol ediyoruz ve deeri eleen
saylar print() fonksiyonunu kullanarak ekrana dkyoruz.
Eer bu kodlar ilk bakta gznze anlalmaz grndyse bu kodlar bir de u ekilde
yazarak arka planda neler olup bittiini daha net grebilirsiniz:
kardiz = input("Metin girin: ")
aranacak = input("Aradnz harf: ")

for i in range(len(kardiz)):
print("i'nin deeri: ", i)
if i == kardiz.index(aranacak, i):

286 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

print("%s. srada 1 adet %s harfi bulunuyor" %(i, aranacak))


else:
print("%s. srada %s harfi bulunmuyor" %(i, aranacak))

Grdnz gibi index() metodu bir karakter dizisi iindeki karakterleri ararken karakter
dizisini soldan saa doru okuyor. Pythonda bu ilemin tersi de mmkndr. Yani isterseniz
Pythonn, karakter dizisini soldan saa doru deil de, sadan sola doru okumasn da
salayabilirsiniz. Bu i iin rindex() adl bir metottan yararlanacaz. Bu metot her ynden
index() metoduyla ayndr. index() ve rindex() metotlarnn birbirinden tek fark, index()
metodunun karakter dizilerini soldan saa, rindex() metodunun ise sadan sola doru
okumasdr. Hemen bir rnekle durumu aklamaya alalm:
>>> kardiz = "adana"
>>> kardiz.index("a")

>>> kardiz.rindex("a")

Bu iki rnek, index() ve rindex() metotlar arasndaki fark gayet net bir ekilde ortaya
koyuyor. index() metodu, karakter dizisini soldan saa doru okuduu iin adana karakter
dizisinin 0. srasndaki a harni yakalad. rindex() metodu ise karakter dizisini sadan sola
doru okuduu iin adana karakter dizisinin 4. srasndaki a harni yakalad...

18.9 nd, rnd()

find() ve rfind() metotlar tamamen index() ve rindex() metotlarna benzer. find()


ve rfind() metotlarnn grevi de bir karakter dizisi iindeki bir karakterin konumunu
sorgulamaktr:
>>> kardiz = "adana"
>>> kardiz.find("a")

>>> kardiz.rfind("a")

Peki index()/rindex() ve find()/rfind() metotlar arasnda ne fark var?


index() ve rindex() metotlar karakter dizisi iindeki karakteri sorgularken, eer o karakteri
bulamazsa bir ValueError hatas verir:
>>> kardiz = "adana"
>>> kardiz.index("z")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
ValueError: substring not found

Ama find() ve rfind() metotlar byle bir durumda -1 kts verir:

18.9. nd, rnd() 287


Python 3 iin Trke Klavuz, Srm 3

>>> kardiz = "adana"


>>> kardiz.find("z")

-1

Bu iki metot ifti arasndaki tek fark budur.

18.10 center()

Center kelimesi ngilizcede orta, merkez, ortalamak gibi anlamlara gelir. Bu anlama uygun
olarak, center() metodunu karakter dizilerini ortalamak iin kullanabilirsiniz. rnein:
for metot in dir(""):
print(metot.center(15))

Grdnz gibi center() metodu bir adet parametre alyor. Bu parametre, karakter dizisine
uygulanacak ortalama ileminin geniliini gsteriyor. Bu parametrenin nasl bir etki ortaya
kardn daha iyi anlayabilmek iin isterseniz bir iki basit rnek verelim:
>>> kardiz = "python"

Burada 6 karakterlik bir karakter dizisi tanmladk. imdi dikkatlice bakn:


>>> kardiz.center(1)

'python'

Burada ise center() metoduna parametre olarak 1 saysn verdik. Ancak bu parametre
karakter dizimizinin uzunluundan az olduu iin kt zerinde herhangi bir etkisi olmad.
Bir de una bakalm:
>>> kardiz.center(10)

' python '

ktdaki trnak iaretlerine bakarak, python kelimesinin ortalandn grebilirsiniz. Buradan


u sonucu karyoruz: center() metoduna verilen genilik parametresi aslnda bir karakter
dizisinin toplam ka karakterlik bir yer kaplayacan gsteriyor. Mesela yukardaki rnekte
bu metoda verdiimiz 10 says "python" adl karakter dizisinin toplam 10 karakterlik bir
yer kaplayacan gsteriyor. Kaplanacak yere karakter dizisinin kendisi de dahildir. Yani 10
olarak belirttiimiz boluk adedinin 6 s python kelimesinin kendisi tarafndan igal ediliyor.
Geriye kalan 4 bolukluk mesafe ise karakter dizisinin sol ve sa tarafna paylatrlyor.
center() metodunun karakter dizileri zerindeki etkisini daha net olarak grmek iin yle
bir dng kurabilirsiniz:
>>> for i in range(1, 20):
... kardiz.center(i)
...
'python'
'python'
'python'
'python'
'python'
'python'

288 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

' python'
' python '
' python '
' python '
' python '
' python '
' python '
' python '
' python '
' python '
' python '
' python '
' python '

Bu rnekte, karakter dizisinin her admda nasl ortaya doru kayd aka grlyor. Dikkat
ederseniz ktnn ilk alt satrnda karakter dizisinin konumu deimiyor. Ancak center()
metoduna verilen parametrenin deeri karakter dizisinin uzunluunu at anda karakter
dizisi ortaya doru ilerlemeye balyor.
center() metodu genellikle yukardaki gsterdiimiz ekilde tek bir parametre ile birlikte
kullanlr. Ancak bu metot aslnda bir parametre daha alr. u rnei inceleyelim:
>>> kardiz = "elma"
>>> kardiz.center(10, "-")

'---elma---'

Grdnz gibi, center() metoduna verdiimiz - deeri sayesinde elma karakteri


ortalanrken, sa ve sol taraftaki boluklara da - karakteri eklenmi oldu.

18.11 rjust(), ljust()

Bu metotlar da tpk bir nceki center() metodu gibi karakter dizilerini hizalama vazifesi
grr. rjust() metodu bir karakter dizisini saa yaslarken, ljust() metodu karakter dizisini
sola yaslar. Mesela u iki kod parasnn ktlarn inceleyin:
>>> for i in dir(""):
... print(i.ljust(20))

>>> for i in dir(""):


... print(i.rjust(20))

ljust() metodu bize zellikle karakter dizilerinin hizalama ilemlerinde yardmc oluyor. Bu
metot yardmyla karakter dizilerimizi sola yaslayp, sa tarafna da istediimiz karakterleri
yerletirebiliyoruz. Hemen bir rnek verelim:
>>> kardiz = "tel no"
>>> kardiz.ljust(10, ".")

'tel no....'

Burada olan ey u: ljust() metodu, kendisine verilen 10 parametresinin etkisiyle 10


karakterlik bir alan oluturuyor. Bu 10 karakterlik alann iine nce 6 karakterlik yer kaplayan
tel no ifadesini, geri kalan 4 karakterlik bolua ise . karakterini yerletiriyor. Eer
ljust() metoduna verilen say karakter dizisinin uzunluundan az yer tutarsa, karakter

18.11. rjust(), ljust() 289


Python 3 iin Trke Klavuz, Srm 3

dizisinin grnnde herhangi bir deiiklik olmayacaktr. rnein yukardaki rnekte


karakter dizimizin uzunluu 6. Dolaysyla kodumuzu u ekilde yazarsak bir sonu elde
edemeyiz:
>>> kardiz.ljust(5, ".")

'tel no'

Grdnz gibi, karakter dizisinde herhangi bir deiiklik olmad. ljust() metoduna
verdiimiz . karakterini grebilmemiz iin, verdiimiz say cinsli parametrenin en az
karakter dizisinin boyunun bir fazlas olmas gerekir:
>>> kardiz.ljust(7, ".")

'tel no.'

ljust() metoduyla ilgili basit bir rnek daha verelim:


>>> for i in "elma", "armut", "patlcan":
... i.ljust(10, ".")
...
'elma......'
'armut.....'
'patlcan..'

Grdnz gibi, bu metot karakter dizilerini k bir biimde sola hizalamamza yardmc
oluyor.
rjust() metodu ise, ljust() metodunun yapt iin tam tersini yapar. Yani karakter dizilerini
sola deil saa yaslar:
>>> for i in "elma", "armut", "patlcan":
... i.rjust(10, ".")
...
'......elma'
'.....armut'
'..patlcan'

ljust() ve rjust() metotlar, kullanclarnza gstereceiniz ktlarn dzgn grnmesini


salamak asndan olduka faydaldr.

18.12 zll()

Bu metot kimi yerlerde iimizi epey kolaylatrabilir. zfill() metodu yardmyla karakter
dizilerinin sol tarafna istediimiz sayda sfr ekleyebiliriz:
>>> a = "12"
>>> a.zfill(3)

'012'

Bu metodu yle bir i iin kullanabilirsiniz:


>>> for i in range(11):
... print(str(i).zfill(2))
00

290 Blm 18. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

01
02
03
04
05
06
07
08
09
10

Burada str() fonksiyonunu kullanarak, range() fonksiyonundan elde ettiimiz saylar birer
karakter dizisine evirdiimize dikkat edin. nk zfill() karakter dizilerinin bir metodudur.
Saylarn deil...

18.13 partition(), rpartition()

Bu metot yardmyla bir karakter dizisini belli bir lte gre e blyoruz. rnein:
>>> a = "istanbul"
>>> a.partition("an")

('ist', 'an', 'bul')

Eer partition() metoduna parantez iinde verdiimiz lt karakter dizisi iinde


bulunmuyorsa u sonula karlarz:
>>> a = "istanbul"
>>> a.partition("h")

('istanbul', '', '')

Gelelim rpartition() metoduna... Bu metot da partition() metodu ile ayn ii yapar, ama
yntemi biraz farkldr. partition() metodu karakter dizilerini soldan saa doru okur.
rpartition() metodu ise sadan sola doru. Peki bu durumun ne gibi bir sonucu vardr?
Hemen grelim:
>>> b = "istihza"
>>> b.partition("i")

('', 'i', 'stihza')

Grdnz gibi, partition() metodu karakter dizisini ilk i harnden bld. imdi ayn
ilemi rpartition() metodu ile yapalm:
>>> b.rpartition("i")

('ist', 'i', 'hza')

rpartition() metodu ise, karakter dizisini sadan sola doru okuduu iin ilk i harnden
deil, son i harnden bld karakter dizisini.
partition() ve rpartition() metotlar, ltn karakter dizisi iinde bulunmad
durumlarda da farkl tepkiler verir:

18.13. partition(), rpartition() 291


Python 3 iin Trke Klavuz, Srm 3

>>> b.partition("g")

('istihza', '', '')

>>> b.rpartition("g")

('', '', 'istihza')

Grdnz gibi, partition() metodu bo karakter dizilerini saa doru yaslarken,


rpartition() metodu sola doru yaslad.

18.14 encode()

Bu metot yardmyla karakter dizilerimizi istediimiz kodlama sistemine gre kodlayabiliriz.


Python 3.xte varsaylan karakter kodlamas utf-8 dir. Eer istersek u karakter dizisini utf-8
yerine cp1254 ile kodlayabiliriz:
>>> "ilek".encode("cp1254")

18.15 expandtabs()

Bu metot yardmyla bir karakter dizisi iindeki sekme boluklarn geniletebiliyoruz.


rnein:
>>> a = "elma\tbir\tmeyvedir"
>>> a.expandtabs(10)

'elma bir meyvedir'

Bylece bir metot grubunu daha geride brakm olduk. Grdnz gibi baz metotlar
sklkla kullanlabilme potansiyeli tarken, baz metotlar pek yle sk kullanlacakm gibi
grnmyor...
Sonraki blmde metotlar incelemeye devam edeceiz.

292 Blm 18. Karakter Dizilerinin Metotlar (Devam)


BLM 19

Karakter Dizilerinin Metotlar (Devam)

Karakter dizileri konusunun 4. blmne geldik. Bu blmde de karakter dizilerinin


metotlarn incelemeye devam edeceiz.

19.1 str.maketrans(), translate()

Bu iki metot birbiriyle balantl olduu ve genellikle birlikte kullanld iin, bunlar bir arada
greceiz.
Dilerseniz bu iki metodun ne ie yaradn anlatmaya almak yerine bir rnek zerinden bu
metotlarn grevini anlamay deneyelim.
yle bir vaka hayal edin: Bildiiniz gibi, internet zerinde bazen Trke karakterleri
kullanamyoruz. Byle durumlarda, elimizdeki bir metni, cmleyi veya kelimeyi Trke
karakter iermeyecek bir hale getirmemiz gerekebiliyor. rnein u cmleyi ele alalm:
Bildiiniz gibi, internet zerinde bazen Trke karakterleri kullanamyoruz.
te buna benzer bir cmleyi kimi zaman Trke karakterlerinden arndrmak zorunda
kalabiliyoruz. Eer elinizde Trke yazlm bir metin varsa ve sizin amacnz bu metin iinde
geen Trkeye zg karakterleri noktasz benzerleriyle deitirmek ise str.maketrans() ve
translate() metotlarndan yararlanabilirsiniz.
rneimiz u cmle idi:
Bildiiniz gibi, internet zerinde bazen Trke karakterleri kullanamyoruz.
Amacmz bu cmleyi u ekilde deitirmek:
Bildiginiz gibi, internet uzerinde bazen Turkce karakterleri kullanamiyoruz.
Bunun iin yle bir kod yazabilirsiniz:

kaynak = ""
hedef = "scoguiSCOGUI"

eviri_tablosu = str.maketrans(kaynak, hedef)

metin = "Bildiiniz gibi, internet zerinde bazen Trke karakterleri kullanamyoruz."

print(metin.translate(eviri_tablosu))

Bu kodlar altrdmzda yle bir kt elde ederiz:

293
Python 3 iin Trke Klavuz, Srm 3

Bildiginiz gibi, internet uzerinde bazen Turkce karakterleri kullanamiyoruz.

Grdnz gibi, kaynak adl karakter dizisi iinde belirttiimiz btn harer hedef adl
karakter dizisi iindeki harerle tek tek deitirildi. Bylece Trkeye zg karakterleri
() en yakn noktasz benzerleriyle (scoguiSCOGUI) deitirmi olduk.
Peki yukarda nasl bir sre iledi de biz istediimiz sonucu elde edebildik. Dilerseniz
yukardaki kodlara biraz daha yakndan bakalm. Mesela eviri_tablosu adl deikenin
ktsna bakarak str.maketrans() metodunun alttan alta neler kartrdn grelim:

kaynak = ""
hedef = "scoguiSCOGUI"

eviri_tablosu = str.maketrans(kaynak, hedef)

print(eviri_tablosu)

Bu kodlar altrdmzda yle bir kt alyoruz:


{214: 79, 231: 99, 220: 85, 199: 67, 304: 73, 305: 105,
286: 71, 246: 111, 351: 115, 252: 117, 350: 83, 287: 103}

Bu kt size tamamen anlamsz grnm olabilir. Ama aslnda son derece anlaml ve bir o
kadar da nemli bir ktdr bu. Gelin isterseniz bu ktnn yapsn biraz inceleyelim. (Buna
benzer bir kty sorted() metodunu incelerken de grmtk)
Grdnz gibi, tamamen saylardan oluan bir kt bu. Burada birbirlerinden virgl ile
ayrlm say iftleri gryoruz. Bu say iftlerini daha net grebilmek iin bu kty derli toplu
bir hale getirelim:
{214: 79,
231: 99,
220: 85,
199: 67,
304: 73,
305: 105,
286: 71,
246: 111,
351: 115,
252: 117,
350: 83,
287: 103}

Bu ekilde sanrm ktmz biraz daha anlam kazand. Grdnz gibi, iki nokta st ste
iaretinin solunda ve sanda baz saylar var. Tahmin edebileceiniz gibi, soldaki saylar
sadaki saylarla ilikili.
Peki btn bu saylar ne anlama geliyor ve bu saylar arasnda ne tr bir iliki var?
Teknik olarak, bilgisayarlarn temelinde saylar olduunu duymusunuzdur. Bilgisayarnzda
grdnz her karakter aslnda bir sayya karlk gelir. Zaten bilgisayarlar a, b, c, vb.
kavramlar anlayamaz. Bilgisayarlarn anlayabildii tek ey saylardr. Mesela siz klavyeden a
harni girdiinizde bilgisayar bunu 97 olarak alglar. Ya da siz i har girdiinizde, bilgisayarn
grd tek ey 105 saysdr... Bu durumu Pythondaki chr() adl zel bir fonksiyon
yardmyla teyit edebiliriz. Dikkatlice inceleyin:

294 Blm 19. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

>>> chr(97)

'a'

>>> chr(105)

'i'

>>> chr(65)

'A'

Grdnz gibi, gerekten de her say bir karaktere karlk geliyor. sterseniz bir de
yukardaki say grubundaki saylar denetleyelim:
for i in 214, 231, 220, 199, 304, 305, 286, 246, 351, 252, 350, 287:
print(i, chr(i))

Bu kodlar altrdmzda u kty elde ediyoruz:

214
231
220
199
304
305
286
246
351
252
350
287

Bu kt sayesinde baz eyler zihninizde yava yava akla kavuuyor olmal. Bu kt mesela
214 saysnn harne, 220 saysnn harne, 305 saysnn da harne karlk geldiini
gsteriyor.
Burada iki nokta iaretinin sol tarafnda kalan saylarn karakter karlklarn grdk. Bir de
iki nokta iaretinin sa tarafnda kalan saylara bakalm:
for i in 79, 99, 85, 67, 73, 105, 71, 111, 115, 117, 83, 103:
print(i, chr(i))

Bu da u kty verdi:
79 O
99 c
85 U
67 C
73 I
105 i
71 G
111 o
115 s
117 u
83 S
103 g

19.1. str.maketrans(), translate() 295


Python 3 iin Trke Klavuz, Srm 3

Burada da mesela 79 saysnn O harne, 85 saysnn U harne, 105 saysnn da i harne


karlk geldiini gryoruz.
Yukardaki ve yukardan bir nceki kodlarn ktlarn bir araya getirirseniz yle bir durumla
kar karya olduunuzu grrsnz:
O
c
U
C
I
i
G
o
s
u
S
g

Btn bu sylediklerimizden u sonu kyor:


eviri_tablosu = str.maketrans(kaynak, hedef) satr, kaynak ve hedef olarak
adlandrdmz karakter dizilerini birletirip, bu deikenler iindeki herbir karakteri
birbiriyle eletiriyor. Yani aadaki gibi bir ilem yapyor:
eviri_tablosu = {"": "O",
"": "c",
"": "U",
"": "C",
"": "I",
"": "i",
"": "G",
"": "o",
"": "s",
"": "u",
"": "S",
"": "g"}

Burada eviri_tablosu deikeni iinde gsterdiimiz biimin Pythondaki ad szlktr.


Szlkler de tpk karakter dizileri gibi bir veri tipidir. Bunlar da birka blm sonra ayrntl
bir biimde inceleyeceiz. Biz burada, baz eyleri anlamamz kolaylatraca iin szlk adl
veri tipini olduka genel bir biimde sizlere tanttk. Dediim gibi, bu veri tipinin ayrntlarn
daha sonra inceleyeceiz, ama yine de u noktada szlkleri kenarndan kesinden de olsa
tanmamz bizim iin faydal olacaktr.
Dediim gibi, yukarda eviri_tablosu adyla gsterdiimiz ey bir szlktr. Bu szln nasl
altn grmek iin yle bir kod yazalm:
eviri_tablosu = {"": "O",
"": "c",
"": "U",
"": "C",
"": "I",
"": "i",
"": "G",
"": "o",
"": "s",
"": "u",

296 Blm 19. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

"": "S",
"": "g"}

print(eviri_tablosu[""])

Bu kodlar bir dosyaya kaydedip altrrsanz yle bir kt alrsnz:


O

Grdnz gibi, szlk iinde geen adl eyi parantez iinde belirttiimiz zaman,
Python bize bu enin karsndaki deeri veriyor. Szlk iinde esinin karl O
har olduu iin de ktmz O oluyor. Bir de unlara bakalm:

eviri_tablosu = {"": "O",


"": "c",
"": "U",
"": "C",
"": "I",
"": "i",
"": "G",
"": "o",
"": "s",
"": "u",
"": "S",
"": "g"}

print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])

Bu kodlar altrdmzda ise yle bir kt alyoruz:


O
c
U
C
I
i
G
o
S
g

Grdnz gibi, szlk iinde iki nokta st ste iaretinin sol tarafnda grnen eleri
parantez iinde yazarak, iki nokta st ste iaretinin sa tarafndaki deerleri elde
edebiliyoruz.
Btn bu anlattklarmzdan sonra u satrlar gayet iyi anlam olmalsnz:

kaynak = ""
hedef = "scoguiSCOGUI"

19.1. str.maketrans(), translate() 297


Python 3 iin Trke Klavuz, Srm 3

eviri_tablosu = str.maketrans(kaynak, hedef)

Burada Python, kaynak ve hedef adl deikenler iindeki karakter dizilerini birer birer
eletirerek bize bir szlk veriyor. Bu szlkte:
"" harfi "s" harfine;
"" harfi "c" harfine;
"" harfi "o" harfine;
"" harfi "g" harfine;
"" harfi "u" harfine;
"" harfi "i" harfine;
"" harfi "S" harfine;
"" harfi "C" harfine;
"" harfi "O" harfine;
"" harfi "G" harfine;
"" harfi "U" harfine;
"" harfi "I" harfine

karlk geliyor...
Kodlarn geri kalannda ise u satrlar grmtk:
metin = "Bildiiniz gibi, internet zerinde bazen Trke karakterleri kullanamyoruz."

print(metin.translate(eviri_tablosu))

Burada da orijinal metnimizi tanmladktan sonra translate() adl metot yardmyla, eviri
tablosundaki e elemesi dorultusunda metnimizi tercme ediyoruz. Bu kodlarda
metin.translate(eviri_tablosu) satrnn yapt tek ey eviri_tablosu adl szlkteki
eleme kriterlerini metin adl karakter dizisine uygulamaktan ibarettir.
Karakter dizilerinin bu maketrans() adl metodu kullanm olarak gznze teki metotlardan
farkl grnm olabilir. Daha ak bir dille ifade etmek gerekirse, bu metodu bir karakter
dizisi zerine deil de str zerine uyguluyor olmamz, yani str.maketrans() yazyor olmamz
sizi artm olabilir. Eer anlamanz kolaylatracaksa;
eviri_tablosu = str.maketrans(kaynak, hedef)

satrn u ekilde de yazabilirsiniz:


eviri_tablosu = ''.maketrans(kaynak, hedef)

Yani maketrans() metodunu bo bir karakter dizisi zerine de uygulayabilirsiniz. Neticede


maketrans() karakter dizilerinin bir metodudur. Bu metot hangi karakter dizisi zerine
uygulandyla deil, parametre olarak hangi deerleri aldyla (bizim rneimizde kaynak
ve hedef ) ilgilenir. Dolaysyla bu metodu ilgili-ilgisiz her trl karakter dizisine
uygulayabilirsiniz:
eviri_tablosu = 'mahmut'.maketrans(kaynak, hedef)
eviri_tablosu = 'zalim dnya!'.maketrans(kaynak, hedef)

Ama tabii dikkat datmamak asndan en uygun hareket, bu karakter dizisini str zerine
uygulamak olacaktr:
eviri_tablosu = str.maketrans(kaynak, hedef)

Bu kk ayrntya da dikkati ektiimize gre yolumuza devam edebiliriz...

298 Blm 19. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

Yukarda verdiimiz rnek vastasyla str.maketrans() ve translate() adl metotlar epey


ayrntl bir ekilde incelemi olduk. Dilerseniz pratik olmas asndan bir rnek daha verelim:
istihza.com sitemizin forum yelerinden Barbaros Akkurt
http://www.istihza.com/forum/viewtopic.php?f=25&t=63 adresinde yle bir problemden
bahsediyor:
Ben on parmak Trke F klavye kullanyorum. Bunun iin, baz tu
kombinasyonlar ile veya sistem tepsisi zerindeki klavye simgesine tklayarak
Trke Q - Trke F deiimi yapyorum. Bazen bunu yapmay unutuyorum ve bir
metne bakarak yazyorsam gzm ekranda olmuyor. Bir paragraf yazp bitirdikten
sonra ekranda bir karakter salatas grnce ok bozuluyorum.
te byle bir durumda yukardaki iki metodu kullanarak o karakter salatasn dzeltebilirsiniz.
Karakter salatamz u olsun:
Bfjrk a kdhs yteua idjslyd bdcusldvdj ks?
Buna gre kodlarmz yazmaya balayabiliriz. ncelikle metnimizi tanmlayalm:
metin = "Bfjflrk a kdhs yteua idjslyd bdcusldvdj ks?"

imdi de srasyla q ve f klavye dzenlerini birer karakter dizisi haline getirelim:


q_klavye_dzeni = "qwertyuopasdfghjkli,zxcvbnm."
f_klavye_dzeni = "fgodrnhpqwuieatkmlyxjvczsb.,"

Burada amacmz yanllkla q klavye dzeninde yazld iin karman orman bir hale gelmi
metni dzgn bir ekilde f klavye dzenine dntrmek. Yani burada k noktamz
(kaynamz) q_klavye_dzeni iken, var noktamz (hedemiz) f_klavye_dzeni. Buna gre
eviri tablomuzu oluturabiliriz:
eviri_tablosu = str.maketrans(q_klavye_dzeni, f_klavye_dzeni)

Tpk bir nceki rnekte olduu gibi, burada da eviri_tablosu adl deikeni print()
fonksiyonunu kullanarak yazdrrsanz yle bir ktyla karlarsnz:
{231: 46,
287: 113,
44 : 120,
46 : 44,
305: 110,
246: 98,
351: 121,
97 : 117,
98 : 231,
99 : 118,
100: 101,
101: 287,
102: 97,
103: 252,
104: 116,
105: 351,
106: 107,
107: 109,
108: 108,
109: 115,
110: 122,

19.1. str.maketrans(), translate() 299


Python 3 iin Trke Klavuz, Srm 3

111: 104,
112: 112,
113: 102,
114: 305,
115: 105,
116: 111,
117: 114,
118: 99,
119: 103,
120: 246,
121: 100,
122: 106,
252: 119}

Tahmin edebileceiniz gibi, bu szlkte iki nokta st ste iaretinin solundaki saylar
q_klavye_dzeni adl deiken iindeki karakterleri; sandaki saylar ise f_klavye_dzeni adl
deiken iindeki karakterleri temsil ediyor.
Son olarak translate() metodu yardmyla szlkteki e elemesini metin adl deikenin
zerine uyguluyoruz:
print(metin.translate(eviri_tablosu))

Kodlar topluca grelim:


metin = "Bfjflrk a kdhs yteua idjslyd bdcusldvdj ks?"

q_klavye_dzeni = "qwertyuopasdfghjkli,zxcvbnm."
f_klavye_dzeni = "fgodrnhpqwuieatkmlyxjvczsb.,"

eviri_tablosu = str.maketrans(q_klavye_dzeni, f_klavye_dzeni)

print(metin.translate(eviri_tablosu))

Ne elde ettiniz?
Yukardaki iki rnekte de grdmz gibi, str.maketrans() metodu kaynak ve hedef
karakter dizilerini alp bunlar birletirerek bize bir szlk veri tipinde bir nesne veriyor. Yani
tpk input() fonksiyonunun bize bir karakter dizisi verdii gibi, str.maketrans() metodu da
bize bir szlk veriyor.
Eer isterseniz, szl str.maketrans() metoduna oluturtmak yerine, kendiniz de bir
szlk oluturarak str.maketrans() metoduna parametre olarak atayabilirsiniz. rnein:
metin = "Bfjflrk a kdhs yteua idjslyd bdcusldvdj ks?"

szlk = {"q": "f",


"w": "g",
"e": "",
"r": "",
"t": "o",
"y": "d",
"u": "r",
"": "n",
"o": "h",
"p": "p",
"": "q",
"": "w",

300 Blm 19. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

"a": "u",
"s": "i",
"d": "e",
"f": "a",
"g": "",
"h": "t",
"j": "k",
"k": "m",
"l": "l",
"": "y",
"i": "",
",": "x",
"z": "j",
"x": "",
"c": "v",
"v": "c",
"b": "",
"n": "z",
"m": "s",
"": "b",
"": ".",
".": ","}

eviri_tablosu = str.maketrans(szlk)
print(metin.translate(eviri_tablosu))

Burada birbiriyle eleecek karakterleri kendimiz yazp bir szlk oluturduk ve bunu
parametre olarak dorudan str.maketrans() metoduna verdik. Bu kodlarda kaynak ve
hedef diye iki ayr karakter dizisi tanmlamak yerine tek bir szlk oluturduumuz iin,
str.maketrans() metodunu iki parametreyle deil, tek parametreyle kullandmza dikkat
edin. Ayrca szl nasl oluturduumuzu da dikkatlice inceleyin.
Szlkteki e iftlerini byle alt alta yazmamzn nedeni zorunluluk deil, bir tercihtir.
stersek bu szl yle de tanmlayabilirdik:
szlk = {"q": "f", "w": "g", "e": "", "r": "", "t": "o", "y": "d", "u": "r",
"": "n", "o": "h", "p": "p", "": "q", "": "w", "a": "u", "s": "i",
"d": "e", "f": "a", "g": "", "h": "t", "j": "k", "k": "m", "l": "l",
"": "y", "i": "", ",": "x", "z": "j", "x": "", "c": "v", "v": "c",
"b": "", "n": "z", "m": "s", "": "b", "": ".", ".": ","}

Burada da e iftlerini yan yana yazdk. Bu iki yntemden hangisi size daha okunakl
geliyorsa onu tercih edebilirsiniz.
imdi size bir soru sormama izin verin. Acaba aadaki metin iinde geen btn sesli
hareri silin desem, nasl bir kod yazarsnz?
Bu programlama dili Guido Van Rossum adl Hollandal bir programc tarafndan
90l yllarn banda gelitirilmeye balanmtr. ou insan, isminin Python
olmasna bakarak, bu programlama dilinin, adn piton ylanndan aldn
dnr. Ancak zannedildiinin aksine bu programlama dilinin ad piton
ylanndan gelmez. Guido Van Rossum bu programlama dilini, The Monty Python
adl bir ngiliz komedi grubunun, Monty Pythons Flying Circus adl gsterisinden
esinlenerek adlandrmtr. Ancak her ne kadar gerek byle olsa da, Python
programlama dilinin pek ok yerde bir ylan gr ile temsil edilmesi neredeyse
bir gelenek halini almtr diyebiliriz.

19.1. str.maketrans(), translate() 301


Python 3 iin Trke Klavuz, Srm 3

Aklnza ilk olarak yle bir kod yazmak gelebilir:


metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir
programc tarafndan 90'l yllarn banda gelitirilmeye balanmtr.
ou insan, isminin Python olmasna bakarak, bu programlama dilinin, adn
piton ylanndan aldn dnr. Ancak zannedildiinin aksine bu
programlama dilinin ad piton ylanndan gelmez. Guido Van Rossum bu
programlama dilini, The Monty Python adl bir ngiliz komedi grubunun, Monty
Python's Flying Circus adl gsterisinden esinlenerek adlandrmtr. Ancak
her ne kadar gerek byle olsa da, Python programlama dilinin pek ok yerde
bir ylan figr ile temsil edilmesi neredeyse bir gelenek halini almtr
diyebiliriz."""

sesli_harfler = "aeiouAEIOU"

yeni_metin = ""

for i in metin:
if not i in sesli_harfler:
yeni_metin += i

print(yeni_metin)

Burada ncelikle metin adl bir deiken tanmlayarak metnimizi bu deiken iine
yerletirdik. Ardndan da Trkedeki sesli hareri ieren bir karakter dizisi tanmladk.
Daha sonra da yeni_metin adl bo bir karakter dizisi oluturduk. Bu karakter dizisi, orijinal
metnin, sesli harer ayklandktan sonraki halini barndracak. Biliyorsunuz, karakter dizileri
deitirilemeyen (immutable ) bir veri tipidir. Dolaysyla bir karakter dizisi iinde yaptmz
deiiklikleri koruyabilmek iin bu deiiklikleri baka bir deiken iinde tutmamz gerekiyor.
Bu kodlarn ardndan bir for dngs tanmlyoruz. Buna gre, metin iinde geen her
bir karaktere tek tek bakyoruz (for i in metin:) ve bu karakterler arasnda, sesli_harer
deikeni iinde gemeyenleri, yani btn sessiz hareri (if not i in sesli_harfler:) tek
tek yeni_metin adl deikene yolluyoruz (yeni_metin += i).
Son olarak da yeni_metin adl karakter dizisini ekrana basyoruz. Bylece orijinal metin
iindeki btn sesli hareri ayklam oluyoruz.
Yukardaki, gayet doru ve geerli bir yntemdir. Byle bir kod yazmanzn hibir sakncas
yok. Ama eer isterseniz ayn ii str.maketrans() ve translate() metotlar yardmyla da
halledebilirsiniz:
metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir
programc tarafndan 90'l yllarn banda gelitirilmeye balanmtr.
ou insan, isminin Python olmasna bakarak, bu programlama dilinin, adn
piton ylanndan aldn dnr. Ancak zannedildiinin aksine bu
programlama dilinin ad piton ylanndan gelmez. Guido Van Rossum bu
programlama dilini, The Monty Python adl bir ngiliz komedi grubunun, Monty
Python's Flying Circus adl gsterisinden esinlenerek adlandrmtr. Ancak
her ne kadar gerek byle olsa da, Python programlama dilinin pek ok yerde
bir ylan figr ile temsil edilmesi neredeyse bir gelenek halini almtr
diyebiliriz."""

silinecek = "aeiouAEIOU"

eviri_tablosu = str.maketrans('', '', silinecek)

302 Blm 19. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

print(metin.translate(eviri_tablosu))

Burada da ncelikle metnimizi bir karakter dizisi iine yerletirdik. Daha sonra da u kodu
yazdk:

silinecek = "aeiouAEIOU"

Bu kodlar yardmyla, metin iinden karmak istediimiz hareri tek tek belirledik.
Ardndan str.maketrans() fonksiyonumuzu yazarak eviri tablosunu oluturduk. Burada
ilk iki parametrenin bo birer karakter dizisi olduuna dikkat ediyoruz. lk iki parametreyi
bu ekilde yazmamzn nedeni u: Biz orijinal metin iindeki herhangi bir eyi deitirmek
istemiyoruz. Bizim amacmz orijinal metin iindeki sesli hareri silmek. Tabii o iki
parametreyi yazmasak da olmaz. O yzden o iki parametrenin yerine birer tane bo karakter
dizisi yerletiriyoruz.
Bu noktada eviri_tablosu adl deikeni yazdrarak neler olup bittiini daha net grebilirsiniz:
{214: None,
97 : None,
101: None,
65 : None,
105: None,
111: None,
304: None,
305: None,
220: None,
117: None,
246: None,
73 : None,
79 : None,
252: None,
85 : None,
69 : None}

Grdnz gibi, silinecek adl deiken iindeki btn karakterler None deeriyle eleiyor...
None hi, sfr, yokluk gibi anlamlara gelir. Dolaysyla Python, iki nokta st ste iaretinin
sol tarafndaki karakterlerle karlatnda bunlarn yerine birer adet yokluk koyuyor! Yani
sonu olarak bu karakterleri metinden silmi oluyor...
Bu kodlarda iki nokta st ste iaretinin solundaki karakterlerin None ile elemesini salayan
ey, str.maketrans() metoduna verdiimiz nc parametredir. Eer o parametreyi
yazmazsak, yani kodlarmz u ekle getirirsek eviri_tablosu deikeninin kts farkl
olacaktr:
metin = """Bu programlama dili Guido Van Rossum adl Hollandal bir
programc tarafndan 90'l yllarn banda gelitirilmeye balanmtr.
ou insan, isminin Python olmasna bakarak, bu programlama dilinin, adn
piton ylanndan aldn dnr. Ancak zannedildiinin aksine bu
programlama dilinin ad piton ylanndan gelmez. Guido Van Rossum bu
programlama dilini, The Monty Python adl bir ngiliz komedi grubunun, Monty
Python's Flying Circus adl gsterisinden esinlenerek adlandrmtr. Ancak
her ne kadar gerek byle olsa da, Python programlama dilinin pek ok yerde
bir ylan figr ile temsil edilmesi neredeyse bir gelenek halini almtr
diyebiliriz."""

silinecek = "aeiouAEIOU"

19.1. str.maketrans(), translate() 303


Python 3 iin Trke Klavuz, Srm 3

eviri_tablosu = str.maketrans('', '')

print(eviri_tablosu)

Bu kodlar altrdmzda yle bir kt alrz:


{}

Grdnz gibi, elde ettiimiz ey bo bir szlktr. Szlk bo olduu, yani deitirilecek
herhangi bir karakter olmad iin bu kodlar orijinal metin zerinde herhangi bir deiiklik
yapmaz.
sterseniz nc parametrenin ne ie yaradn ve nasl altn daha iyi anlayabilmek iin
daha basit bir rnek verelim:
metin = "Cem Ylmaz"

kaynak = "CY"
hedef = "cy"
silinecek = "ea "

eviri_tablosu = str.maketrans(kaynak, hedef, silinecek)

print(metin.translate(eviri_tablosu))

Burada C ve Y harerini srasyla c ve y hareriyle eletirdik. Bu nedenle orijinal metin


iindeki C ve Y hareri yerlerini srasyla c ve y harerine brakt. Silinecek karakterler
olarak ise e, , a ve boluk karakterlerini setik. Bylece Cem Ylmaz adl orijinal metin
iindeki boluk karakteri de silinerek, bu metin cmylmz karakter dizisine dnt.

19.2 isalpha()

Bu metot yardmyla bir karakter dizisinin alfabetik olup olmadn denetleyeceiz. Peki
alfabetik ne demek?
Eer bir karakter dizisi iinde yalnzca alfabe hareri (a, b, c gibi...) varsa o karakter dizisi
iin alfabetik diyoruz. Bir rnekle bunu dorulayalm:
>>> a = "kezban"
>>> a.isalpha()

True

Ama:
>>> b = "k3zb6n"
>>> b.isalpha()

False

304 Blm 19. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

19.3 isdigit()

Bu metot da isalpha() metoduna benzer. Bunun yardmyla bir karakter dizisinin saysal
olup olmadn denetleyebiliriz. Saylardan oluan karakter dizilerine say deerli karakter
dizileri ad verilir. rnein u bir say deerli karakter dizisidir:
>>> a = "12345"

Metodumuz yardmyla bunu dorulayabiliriz:


>>> a.isdigit()

True

Ama u karakter dizisi saysal deildir:


>>> b = "123445b"

Hemen kontrol edelim:


>>> b.isdigit()

False

19.4 isalnum()

Bu metot, bir karakter dizisinin alfanmerik olup olmadn denetlememizi salar. Peki
alfanmerik nedir?
Daha nce bahsettiimiz metotlardan hatrlayacaksnz:
Alfabetik karakter dizileri, alfabe harerinden oluan karakter dizileridir.
Saysal karakter dizileri, saylardan oluan karakter dizileridir.
Alfanmerik karakter dizileri ise bunun birleimidir. Yani say ve harerden oluan karakter
dizilerine alfanmerik karakter dizileri ad verilir. rnein u karakter dizisi alfanmerik bir
karakter dizisidir:
>>> a = "123abc"

sterseniz hemen bu yeni metodumuz yardmyla bunu dorulayalm:


>>> a.isalnum()

True

Eer denetleme sonucunda True alyorsak, o karakter dizisi alfanmeriktir. Bir de una
bakalm:
>>> b = "123abc>"
>>> b.isalnum()

False

b deikeninin tuttuu karakter dizisinde alfanmerik karakterlerin yansra (123abc ),


alfanmerik olmayan bir karakter dizisi de bulunduu iin (> ), b.isalnum() eklinde
gsterdiimiz denetlemenin sonucu False (yanl) olarak grnecektir.

19.3. isdigit() 305


Python 3 iin Trke Klavuz, Srm 3

Dolaysyla, bir karakter dizisi iinde en az bir adet alfanmerik olmayan bir karakter dizisi
bulunursa (bizim rneimizde ">"), o karakter dizisi alfanmerik olmayacaktr.

19.5 isdecimal()

Bu metot yardmyla bir karakter dizisinin ondalk say cinsinden olup olmadn denetliyoruz.
Mesela aadaki rnek ondalk say cinsinden bir karakter dizisidir:
>>> a = "123"
>>> a.isdecimal()

True

Ama u ise kayan noktal (oating-point ) say cinsinden bir karakter dizisidir:
>>> a = "123.3"
>>> a.isdecimal()

False

Dolaysyla a.isdecimal() komutu False kts verir...

19.6 isidentier()

Identier kelimesi Trkede tanmlayc anlamna gelir. Pythonda deikenler, fonksiyon


ve modl adlarna tanmlayc denir. te balkta grdmz isidentifier() metodu,
neyin tanmlayc olup neyin tanmlayc olamayacan denetlememizi salar. Hatrlarsanz
deikenler konusundan bahsederken, deiken ad belirlemenin baz kurallar olduunu
sylemitik. Buna gre, rnein, deiken adlar bir say ile balayamyordu. Dolaysyla yle
bir deiken ad belirleyemiyoruz:
>>> 1a = 12

Dediimiz gibi, deikenler birer tanmlaycdr. Dolaysyla bir deiken adnn geerli olup
olmadn isidentifier() metodu yardmyla denetleyebiliriz:
>>> "1a".isidentifier()

False

Demek ki "1a" ifadesini herhangi bir tanmlayc ad olarak kullanamyoruz. Yani bu ada sahip
bir deiken, fonksiyon ad veya modl ad oluturamyoruz. Ama mesela "liste1" ifadesi
geerli bir tanmlaycdr. Hemen denetleyelim:
>>> "liste1".isidentifier()

True

19.7 isnumeric()

Bu metot bir karakter dizisinin nmerik olup olmadn denetler. Yani bu metot yardmyla
bir karakter dizisinin say deerli olup olmadn denetleyebiliriz:

306 Blm 19. Karakter Dizilerinin Metotlar (Devam)


Python 3 iin Trke Klavuz, Srm 3

>>> "12".isnumeric()

True

>>> "dasd".isnumeric()

False

19.8 isspace()

Bu metot yardmyla bir karakter dizisinin tamamen boluklardan oluup olumadn


denetleyebiliriz. Eer karakter dizimiz boluklardan oluuyorsa bu metot True kts verecek,
ama eer karakter dizimizin iinde bir tane bile boluk harici karakter varsa bu metot False
kts verecektir:
>>> a = " "
>>> a.isspace()

True

>>> a = " "


>>> a.isspace()

True

>>> a = "" #karakter dizimiz tamamen bo. inde boluk karakteri bile yok...
>>> a.isspace()

False

>>> a = "fd"
>>> a.isspace()

False

19.9 isprintable()

Hatrlarsanz nceki derslerimizde \n, \t, \r ve buna benzer karakterlerden sz etmitik.


rnein \n karakterinin satr ba anlamna geldiini ve bu karakterin grevinin karakter
dizisini bir alt satra almak olduunu sylemitik. rnek verelim:
>>> print("birinci satr\nikinci satr")

birinci satr
ikinci satr

Bu rnekte \n karakterinin teki karakterlerden farkl olduunu gryorsunuz. Mesela


b karakteri komut ktsnda grnyor. Ama \n karakteri ktda grnmyor. \n
karakteri elbette yukardaki kodlar iinde belli bir ileve sahip. Ancak karakter dizisindeki
teki karakterlerden farkl olarak \n karakteri ekranda grnmyor. te Pythonda bunun
gibi, ekranda grnmeyen karakterlere baslmayan karakterler (non-printing characters )
ad verilir. b, c, z, x, =, ?, ! ve benzeri karakterler ise baslabilen karakterler

19.8. isspace() 307


Python 3 iin Trke Klavuz, Srm 3

(printable characters ) olarak adlandrlr. te balkta grdnz isprintable() metodu


da karakterlerin bu ynn sorgular. Yani bir karakterin baslabilen bir karakter mi yoksa
baslmayan bir karakter mi olduunu syler bize. rnein:
>>> karakter = "a"
>>> karakter.isprintable()

True

Demek ki a karakteri baslabilen bir karaktermi. Bir de una bakalm:


>>> karakter = "\n"
>>> karakter.isprintable()

False

Demek ki \n karakteri gerekten de baslamayan bir karaktermi.


Baslamayan karakterlerin listesini grmek iin http://www.asciitable.com/ adresini ziyaret
edebilirsiniz. Listedeki ilk 32 karakter (0 dan balayarak 32 ye kadar olan karakterler) ve
listedeki 127. karakter baslamayan karakterlerdir.

308 Blm 19. Karakter Dizilerinin Metotlar (Devam)


BLM 20

Karakter Dizilerini Biimlendirmek

Bu blme gelinceye kadar, Pythonda karakter dizilerinin biimlendirilmesine ilikin epey


sz syledik. Ancak bu konu ile ilgili bilgilerimiz hem ok dank, hem de ok yzeysel.
te bu blmde amacmz, daha nce farkl yerlerde dile getirdiimiz bu nemli konuya ait
bilgi krntlarn bir araya toplayp, karakter dizisi biimlendirme konusunu, Python bilgimiz
elverdii lde ayrntl bir ekilde ele almak olacak.
u ana kadar yaptmz rneklere bakarak, programlama maceranz boyunca karakter
dizileriyle bol bol har neir olacanz anlam olmalsnz. Bundan sonra yazdnz
programlarda da karakter dizilerinin size pek ok farkl biimlerde geldiine tank olacaksnz.
Farkl farkl biimlerde elinize ulaan bu karakter dizilerini, muhtemelen, sadece alt alta ve
rastgele bir ekilde ekrana yazdrmakla yetinmeyeceksiniz. Bu karakter dizilerini, yazdnz
programlarda kullanabilmek iin, programnza uygun ekillerde biimlendirmeniz gerekecek.
Dilerseniz neden bahsettiimizi daha net bir ekilde anlatabilmek iin ok basit bir rnek
verelim.
Diyelim ki, yazdnz bir programda kullanmak zere, kullancdan isim bilgisi almanz
gerekiyor. Programnzn ileyii gereince, eer isim 5 karakterse veya bundan kkse
ismin tamam grntlenecek, ama eer isim 5 karakterden bykse 5 karakteri aan ksm
yerine nokta iareti koyulacak. Yani eer isim Frat ise bu ismin tamam grntlenecek.
Ama eer isim mesela Abdullah ise, o zaman bu isim Abdul... eklinde grntlenecek.
Bu amaca ulamak iin ilk denememizi yapalm:
isim = input("isminiz: ")

if len(isim) <= 5:
print(isim[:5])
else:
print(isim[:5], "...")

Buradan elde ettiimiz kt ihtiyacmz ksmen karlyor. Ama kt tam istediimiz gibi deil.
nk normalde isme bitiik olmas gereken nokta iareti, isimden bir boluk ile ayrlm.
Yani biz yle bir kt isterken:
Abdul...

yle bir kt elde ediyoruz:


Abdul ...

Bu sorunu u ekilde halledebiliriz:

309
Python 3 iin Trke Klavuz, Srm 3

isim = input("isminiz: ")

if len(isim) <= 5:
print(isim[:5])
else:
print(isim[:5] + "...")

veya:
isim = input("isminiz: ")

if len(isim) <= 5:
print(isim[:5])
else:
print(isim[:5], "...", sep="")

Yukardaki gibi basit durumlarda klasik karakter dizisi birletirme yntemlerini kullanarak
iinizi halledebilirsiniz. Ama daha karmak durumlarda, farkl kaynaklardan gelen karakter
dizilerini ihtiyalarnza gre bir araya getirmek, karakter dizisi birletirme yntemleri ile pek
mmkn olmayacak veya ok zor olacaktr.
Mesela yle bir durum dnn:
Yazdnz programda kullancya bir parola soruyorsunuz. Amacnz bu parolann,
programnzda belirlediiniz ltlere uyup uymadn tespit etmek. Eer kullanc tarafndan
belirlenen parola uygunsa ona u kty gstermek istiyorsunuz (parolann b5tY6g olduunu
varsayalm):
Girdiiniz parola (b5tY6g) kurallara uygun bir paroladr!

Bu kty elde etmek iin yle bir kod yazabilirsiniz:


parola = input("parola: ")

print("Girdiiniz parola (" + parola + ") kurallara uygun bir paroladr!")

Grdnz gibi, sadece karakter dizisi birletirme yntemlerini kullanarak istediimiz kty
elde ettik, ama farkettiyseniz bu defa iler biraz da olsa zorlat.
Bir de uzun ve karmak bir metnin iine dardan deerler yerletirmeniz gereken yle bir
metinle kar karya olduunuzu dnn:
Sayn .........

.... tarihinde yapm olduunuz, ........ hakkndaki bavurunuz incelemeye alnmtr.

Size .... ign iinde cevap verilecektir.

Sayglarmzla,

......

Byle bir metin iine dardan deer yerletirmek iin karakter dizisi birletirme
yntemlerine bavurmak iinizi epey zorlatracaktr.
te klasik karakter dizisi birletirme ilemlerinin yetersiz kald veya ileri bsbtn
zorlatrd bu tr durumlarda Pythonn size sunduu karakter dizisi biimlendirme

310 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

aralarndan yararlanabilirsiniz.
Bunun iin biz bu blmde iki farkl yntemden sz edeceiz:
1. % iareti ile biimlendirme
2. format() metodu ile biimlendirme.
% iareti ile biimlendirme, karakter dizisi biimlendirmenin eski yntemidir. Bu yntem
arlkl olarak Pythonn 3.x srmlerinden nce kullanlyordu. Ama Pythonn 3.x
srmlerinde de bu yntemi kullanma imkanmz var. Her ne kadar bu yntem Python3te
geerliliini korusa da muhtemelen ileride dilden tamamen kaldrlacak. Ancak hem etrafta
bu yntemle yazlm eski programlar olmas, hem de bu yntemin halen geerliliini
korumas nedeniyle bu yntemi (kendimiz kullanmayacak bile olsak) mutlaka renmemiz
gerekiyor.
format() metodu ise Pythonn 3.x srmleri ile dile dahil olan bir zelliktir. Pythonn 2.x
srmlerinde bu metodu kullanamazsnz. Dilin geleceinde bu metot olduu iin, yeni
yazlan kodlarda format() metodunu kullanmak daha akllca olacaktr.
Biz bu sayfalarda yukarda adn andmz her iki yntemi de inceleyeceiz. lk olarak %
iareti ile biimlendirmeden sz edelim.

20.1 % areti ile Biimlendirme (Eski Yntem)

Daha nce de sylediimiz gibi, Python programlama dilinin 3.x srmlerinden nce, bir
karakter dizisini biimlendirebilmek iin % iaretinden yararlanyorduk. Bununla ilgili basit
bir rnek verelim:
parola = input("parola: ")

print("Girdiiniz parola (%s) kurallara uygun bir paroladr!" %parola)

Bu program altrp parola girdiinizde, yazdnz parola ktda parantez iinde


grnecektir.
Yukardaki yapy incelediimizde iki nokta gzmze arpyor:
1. lk olarak, karakter dizisinin iinde bir % iareti ve buna bitiik olarak yazlm bir s har
gryoruz.
2. kincisi, karakter dizisinin dnda %parola gibi bir ifade daha var.
Rahatlkla tahmin edebileceiniz gibi, bu ifadeler birbiriyle dorudan balantldr. Dilerseniz
bu yapy aklamaya gemeden nce bir rnek daha verelim. Bu rnek sayesinde benim
aklamama gerek kalmadan karakter dizisi biimlendirme mantn derhal kavrayacanz
zannediyorum:
print("%s ve %s iyi bir ikilidir!" %("Python", "Django"))

Dediim gibi, bu basit rnek karakter dizilerinin nasl biimlendirildiini gayet ak bir ekilde
gsteriyor. Dilerseniz yapy yle bir inceleyelim:
1. Pythonda %s yaps, karakter dizisi iinde bir yer tutma vazifesi grr.
2. %s yaps bir anlamda deikenlere benzer. Tpk deikenlerde olduu gibi, %s
yapsnn deeri deiebilir.

20.1. % areti ile Biimlendirme (Eski Yntem) 311


Python 3 iin Trke Klavuz, Srm 3

3. Bir karakter dizisi iindeki her %s ifadesi iin, karakter dizisi dnda bu ifadeye karlk
gelen bir deer olmaldr. Python, karakter dizisi iinde geen her %s ifadesinin yerine,
karakter dizisi dndaki her bir deeri tek tek yerletirir. Bizim rneimizde karakter
dizisi iindeki ilk %s ifadesinin karakter dizisi dndaki karl Python ; karakter dizisi
iindeki ikinci %s ifadesinin karakter dizisi dndaki karl ise Django dur.
4. Eer karakter dizisi iindeki %s iaretlerinin says ile karakter dizisi dnda bu
iaretlere karlk gelen deerlerin says birbirini tutmazsa Python bize bir hata mesaj
gsterecektir. Mesela:
>>> print("Benim adm %s, soyadm %s" %"istihza")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: not enough arguments for format string

Grdnz gibi bu kodlar hata verdi. nk karakter dizisi iindeki iki adet %s ifadesine
karlk, karakter dizisinin dnda tek bir deer var (istihza ). Halbuki bizim yle bir kod
yazmamz gerekiyordu:
>>> isim = "istihza"
>>> print("%s adl kiinin mekan www.%s.com adresidir." %(isim, isim))

Bu defa herhangi bir hata mesaj almadk. nk bu kodlarda, olmas gerektii gibi, karakter
dizisi iindeki iki adet %s ifadesine karlk, darda da iki adet deer var.
Eer karakter dizisi iinde tek bir %s ifadesi varsa, karakter dizisi dnda buna karlk
gelen deeri gsterirken, bu deeri parantez iine almamza gerek yok. Ama eer karakter
dizisi iinde birden fazla %s iareti varsa, bunlara karlk gelen deerleri parantez iinde
gsteriyoruz. Mesela yukardaki parola rneinde, karakter dizisinin iinde tek bir %s ifadesi
var. Dolaysyla karakter dizisi dnda bu ifadeye karlk gelen parola deikenini parantez
iine almyoruz. Ama Python ve Django rneinde karakter dizisi iinde iki adet %s
ifadesi yer ald iin, karakter dizisi dnda bu ifadelere karlk gelen Python ve Django
kelimelerini parantez iinde gsteriyoruz.
Btn bu anlattklarmz sindirebilmek iin dilerseniz bir rnek verelim:
kardiz = "istihza"

for sra, karakter in enumerate(kardiz, 1):


print("%s. karakter: '%s'" %(sra, karakter))

Grdnz gibi, istihza adl karakter dizisi iindeki her bir harn srasn ve harn kendisini
uygun bir dzen iinde ekrana yazdrdk. Karakter srasnn ve karakterin kendisinin cmle
iinde gelecei yerleri %s iaretleri ile gsteriyoruz. Python da her bir deeri, ilgili konumlara
tek tek yerletiriyor.
Hatrlarsanz nceki derslerimizde basit bir hesap makinesi rnei vermitik. te imdi
rendiklerimizi o programa uygularsak karakter dizisi biimlendiricileri zerine epey pratik
yapm oluruz:
giri = """
(1) topla
(2) kar
(3) arp
(4) bl
(5) karesini hesapla

312 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

(6) karekk hesapla


"""
print(giri)

a = 1

while a == 1:
soru = input("Yapmak istediiniz ilemin numarasn girin (kmak iin q): ")

if soru == "q":
print("klyor...")
a = 0

elif soru == "1":


say1 = int(input("Toplama ilemi iin ilk sayy girin: "))
say2 = int(input("Toplama ilemi iin ikinci sayy girin: "))

#lk %s'ye karlk gelen deer : say1


#kinci %s'ye karlk gelen deer: say2
#nc %s'ye karlk gelen deer: say1 + say2
print("%s + %s = %s" %(say1, say2, say1 + say2))

elif soru == "2":


say3 = int(input("karma ilemi iin ilk sayy girin: "))
say4 = int(input("karma ilemi iin ikinci sayy girin: "))
print("%s - %s = %s" %(say3, say4, say3 - say4))

elif soru == "3":


say5 = int(input("arpma ilemi iin ilk sayy girin: "))
say6 = int(input("arpma ilemi iin ikinci sayy girin: "))
print("%s x %s = %s" %(say5, say6, say5 * say6))

elif soru == "4":


say7 = int(input("Blme ilemi iin ilk sayy girin: "))
say8 = int(input("Blme ilemi iin ikinci sayy girin: "))
print("%s / %s = %s" %(say7, say8, say7 / say8))

elif soru == "5":


say9 = int(input("Karesini hesaplamak istediiniz sayy girin: "))

#lk %s'ye karlk gelen deer : say9


#kinci %s'ye karlk gelen deer: say9 ** 2
print("%s saysnn karesi = %s" %(say9, say9 ** 2))

elif soru == "6":


say10 = int(input("Karekkn hesaplamak istediiniz sayy girin: "))
print("%s saysnn karekk = %s" %(say10, say10 ** 0.5))

else:
print("Yanl giri.")
print("Aadaki seeneklerden birini giriniz:", giri)

Bu arada, grdnz gibi, Pythonda biim dzenleyici olarak kullanlan simge ayn zamanda
yzde (% ) anlamna da geliyor. O halde size yle bir soru soraym: Acaba 0 dan 100 e kadar
olan saylarn bana birer yzde iareti koyarak bu saylar nasl gsterirsiniz? %0, %1, %10,
%15 gibi... nce yle bir ey deneyelim:

20.1. % areti ile Biimlendirme (Eski Yntem) 313


Python 3 iin Trke Klavuz, Srm 3

>>> for i in range(100):


... print("%s" %i)
...

Bu kodlar tabii ki sadece 0 dan 100 e kadar olan saylar ekrana dkmekle yetinecektir.
Saylarn banda % iaretini gremeyeceiz.
Bir de yle bir ey deneyelim:
>>> for i in range(100):
... print("%%s" %i)
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: not all arguments converted during string formatting

Bu defa da hata mesaj aldk. Halbuki doru cevap u olmalyd:


>>> for i in range(100):
... print("%%%s" %i)
...

Burada % iaretini arka arkaya iki kez kullanarak bir adet % iareti elde ettik. Daha sonra da
normal bir ekilde %s biimini kullandk. Yani adet % iaretini yan yana getirmi olduk.
Btn bu rneklerden sonra, karakter dizisi biimlendiricilerinin iimizi ne kadar
kolaylatrdn grm olmalsnz. stediimiz etkiyi elde etmek iin karakter dizisi
biimlendiricilerini kullanmak, karakter dizilerini birletirme ilemlerinden yararlanmaya
gre ok daha esnek bir yntemdir. Hatta baz durumlarda karakter dizisi biimlendiricilerini
kullanmak makul tek yntemdir.
Yukarda verdiimiz rnekler, %s ile biimlendirme konusunun en temel ynlerini gsteriyor.
Ama aslnda bu arac kullanarak ok daha karmak biimlendirme ilemleri de yapabiliriz.
Yani yukardaki rneklerde %s yapsn en basit ekilde mesela yle kullandk:
>>> print("Karakter dizilerinin toplam %s adet metodu vardr" %len(dir(str)))

Ama eer istersek bundan daha karmak biimlendirme ilemleri de gerekletirebiliriz. u


rnee bakn:
>>> for i in dir(str):
... print("%15s" %i)

Grdnz gibi % ile s iaretleri arasna bir say yerletirdik. Bu say, biimlendirilecek
karakter dizisinin toplam ka karakterlik yer kaplayacan gsteriyor. Durumu daha net
grebilmeniz iin yle bir rnek verelim:
>>> print("|%15s|" %"istihza")

| istihza|

Karakter dizisinin bana ve sonuna eklediimiz | iaretleri sayesinde karakter dizisinin nasl
ve ne ekilde hizalandn daha belirgin bir ekilde grebiliyoruz. Aslnda yukardaki rnein
yapt i size hi yabanc deil. Ayn etkiyi, karakter dizisi metotlarndan rjust() ile de
yapabileceimizi biliyorsunuz:

314 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

>>> print("istihza".rjust(15))

Aynen yukardaki kty rjust() metodunu kullanarak elde etmek iin ise yle bir ey
yazabilirsiniz:
>>> print("|%s|" %"istihza".rjust(15))

| istihza|

Yukardaki rnekte istihza karakter dizisini saa doru yasladk. Sola yaslamak iin ise
negatif saylardan yararlanabilirsiniz:
>>> print("|%-15s|" %"istihza")

|istihza |

Tpk biraz nce verdiimiz rnekteki gibi, ayn etkiyi ljust() metoduyla da elde edebilirsiniz:
>>> print("|%s|" %"istihza".ljust(15))

|istihza |

Grdnz gibi, %s yapsn farkl ekillerde kullanarak epey karmak ktlar elde
edebiliyoruz. Ama aslnda karakter dizisi biimlendiricilerini kullanarak yapabileceklerimiz
bunlarla da snrl deildir. Mesela size yle bir soru sorduumu dnn: Acaba aadaki
ierie sahip bir HTML ablonunu nasl elde edebiliriz?
<html>
<head>
<title> {{ sayfa bal }} </title>
</head>

<body>
<h1> {{ birinci seviye balk }} </h1>
<p>Web sitemize hogeldiniz! Konumuz: {{ konu }}</p>
</body>
</html>

Burada btn deikenler tek bir deere sahip olacak. rnein deikenimiz Python
Programlama Dili ise yukardaki ablon yle bir HTML sayfas retecek:
<html>
<head>
<title> Python Programlama Dili </title>
</head>

<body>
<h1> Python Programlama Dili </h1>
<p>Web sitemize hogeldiniz! Konumuz: Python Programlama Dili</p>
</body>
</html>

Aklnza ilk olarak yle bir zm gelmi olabilir:


sayfa = """
<html>
<head>
<title> %s </title>

20.1. % areti ile Biimlendirme (Eski Yntem) 315


Python 3 iin Trke Klavuz, Srm 3

</head>

<body>
<h1> %s </h1>
<p>Web sitemize hogeldiniz! Konumuz: %s</p>
</body>
</html>
"""

print(sayfa % ("Python Programlama Dili",


"Python Programlama Dili",
"Python Programlama Dili"))

Bu gayet makul ve doru bir zmdr. Ancak grdnz gibi yukardaki kodlarda bizi
rahatsz eden bir nokta var. Bu kodlarda ayn karakter dizisini (Python Programlama
Dili ) kez tekrar ediyoruz. En batan beri sylediimiz gibi, kod yazarken tekrarlardan
olabildiince kanmaya almamz programmzn performansn artracaktr. Burada da
tekrardan kanmak amacyla yle bir kod yazmay tercih edebiliriz. Dikkatlice inceleyin:
sayfa = """
<html>
<head>
<title> %(dil)s </title>
</head>

<body>
<h1> %(dil)s </h1>
<p>Web sitemize hogeldiniz! Konumuz: %(dil)s</p>
</body>
</html>
"""

print(sayfa % {"dil": "Python Programlama Dili"})

Grdnz gibi, yukardaki kodlar bizi ayn karakter dizisini tekrar tekrar yazma
zahmetinden kurtard. Peki ama nasl? Gelin isterseniz bu yapy daha iyi anlayabilmek iin
daha basit bir rnek verelim:
print("depoda %(miktar)s kilo %(rn)s kald" %{"miktar": 25,
"rn": "elma"})

Burada yle bir yapyla kar karyayz:


"%(deiken_ad)s" % {"deiken_ad": "deiken_deeri"}

{deiken_ad: deiken_deeri} yapsyla nceki derslerimizde karlamtnz.


Dolaysyla bu yapnn temel olarak ne ie yaradn biliyorsunuz. Hatta bu yapnn
adnn szlk olduunu da renmitiniz. te burada, szlk adl veri tipinden yararlanarak
deiken adlar ile deiken deerlerini eletirdik. Bylece ayn eyleri tekrar tekrar
yazmamza gerek kalmad. Ayrca yukardaki rnekte deerleri srasna gre deil, ismine
gre ardmz iin, karakter dizisi iindeki deerlerin srasn takip etme zahmetinden de
kurtulmu olduk.
Bylece % yapsnn tm temel ayrntlarn renmi olduk. Artk % iaretinin baka ynlerini
incelemeye balayabiliriz.

316 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

20.1.1 Biimlendirme Karakterleri

Biraz nce, Pythonda eski usul karakter dizisi biimlendirme yntemi olan % iareti
zerine en temel bilgileri edindik. Buraya kadar rendiklerimiz, yazdmz programlarda
genellikle yolumuzu yordammz bulmamza yetecektir. Ama isterseniz imdi karakter
dizisi biimlendirme konusunu biraz daha derinlemesine ele alalm. Mesela Pythondaki
biimlendirme karakterlerinin neler olduunu inceleyelim.

nceki rneklerden de grdnz gibi, Pythonda biim dzenleme ilemleri iin %s adl
bir yapdan faydalanyoruz. Bu yapy yle bir masaya yatrdmzda aslnda bu yapnn
iki paradan olutuunu grebiliriz. Bu paralar % ve s karakterleridir. Burada grdmz
paralardan % sabit, s ise deikendir. Yani % sabit deerini baz harerle birlikte kullanarak,
farkl karakter dizisi biimlendirme ilemleri gerekletirebiliriz.
Biz nceki sayfalarda verdiimiz rneklerde bu simgeyi s haryle birlikte kullandk. rnein:
>>> print("Benim adm %s" %"istihza")

Bu kodlardaki s karakteri ngilizce string, yani karakter dizisi ifadesinin ksaltmasdr.


Esasnda en yaygn ift de budur. Yani etraftaki Python programlarnda yaygn olarak %s
yapsn grrz. Ancak Pythonda % biim dzenleyicisiyle birlikte kullanlabilecek tek
karakter s deildir. Daha nce de dediimiz gibi, s karakteri string, yani karakter dizisi
ifadesinin ksaltmasdr. Yani aslnda %s yaps Pythonda zel olarak karakter dizilerini temsil
eder.
Peki bu ne demek oluyor?
Bir karakter dizisi iinde %s yapsn kullandmzda, darda buna karlk gelen deerin de
bir karakter dizisi veya karakter dizisine evrilebilecek bir deer olmas gerekir. Pythonda her
ey bir karakter dizisi olarak temsil edilebilir. Dolaysyla btn ilemlerinizde % iaretini s
karakteri ile birlikte kullanabilirsiniz. Ama baz zel durumlarda % iaretini s dnda baka
harerle birlikte kullanmanz da gerekebilir.
Biz % yaps ile ilgili verdiimiz ilk rneklerde bu yapnn s karakteri ile birlikte kullanln
gsteren pek ok rnek verdiimiz iin % ile s birliktelii zerinde daha fazla durmayacaz.
Bunun yerine, % ile birlikte kullanlan teki karakterleri inceleyeceiz. O halde yola koyulalm.

Bir nceki balkta grdmz s har nasl karakter dizilerini temsil ediyorsa, d har de
saylar temsil eder. sterseniz kk bir rnekle aklamaya alalm durumu:
>>> print("ubat ay bu yl %d gn ekiyor" %28)

ubat ay bu yl 28 gn ekiyor.

Grdnz gibi, % iaretiyle birlikte bu defa s yerine d harni kullandk. Buna uygun olarak
da d tarafta 28 saysn kullandk. Peki yukardaki ifadeyi yle de yazamaz mydk?
>>> print("ubat ay bu yl %s gn ekiyor" %28)

20.1. % areti ile Biimlendirme (Eski Yntem) 317


Python 3 iin Trke Klavuz, Srm 3

Elbette yazabilirdik. Bu kod da bize doru kt verecektir. nk daha nce de dediimiz gibi,
s har karakter dizilerini ve karakter dizisine evrilebilen deerleri temsil eder. Pythonda
saylar karakter dizisine evrilebildii iin %s gibi bir yapy hata almadan kullanabiliyoruz.
Ama mesela yle bir ey yazamayz:
>>> print("ubat ay bu yl %d gn ekiyor" %"yirmi sekiz")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: %d format: a number is required, not str

Grdnz gibi bu defa hata aldk. nk d har yalnzca say deerleri temsil edebilir. Bu
hare birlikte karakter dizilerini kullanamayz.
Dorusunu sylemek gerekirse, d har aslnda tam say (integer ) deerleri temsil eder. Eer
bu harn kullanld bir karakter dizisinde deer olarak mesela bir kayan noktal say (oat )
verirsek, bu deer tamsayya evrilecektir. Bunun ne demek olduunu hemen bir rnekle
grelim:
>>> print("%d" %13.5)

13

Grdnz gibi, %d ifadesi, 13.5 saysnn ondalk ksmn ktda gstermiyor. nk d


har sadece tamsaylar temsil etme ilevi gryor.
Burada yle bir soru aklnza gelmi olabilir: Acaba %d ifadesi ile hi uramasak, bunun
yerine her yerde %s ifadesini kullansak olmaz m?.
ou zaman olur, ama mesela yle bir durum dnn: Yazdnz programda kullancdan
sadece tam say girmesini istiyor olabilirsiniz. Yani mesela kullancnn ondalk say girmesi
halinde, siz bu saynn sadece tam say ksmn almak istiyor olabilirsiniz. rnein kullanc
23.8 gibi bir say girmise, siz bu sayda ihtiyacnz olan 23 ksmn almak isteyebilirsiniz. te
bu %d iaretinden yararlanarak, kullancnn girdii ondalk saynn sadece tam say ksmn
ekebilirsiniz:
say = input("say: ")

print("%d" %float(say))

Elbette Pythonda bir ondalk saynn sadece taban ksmn almann baka yntemleri de
vardr. Ama yukarda verdiimiz rnek bir ondalk saynn sadece tabann almann gayet
basit ve etkili bir yoludur.
%s yapsn anlatrken gsterdiimiz ileri dzey biimlendirme tekniklerini %d ile de
kullanabilirsiniz. rnein:
>>> print("|%7d|" %23)

| 23|

>>> print("|%-7d|" %23)

|23 |

veya:

318 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

>>> print("%(say)d" % {"say": 23})

23

%s yapsna ek olarak, saynn kaplayaca alandaki boluklara birer 0 da yerletirebilirsiniz:


>>> print("%05d" %23)

00023

...veya:
>>> print("%.5d" %23)

00023

Hatta hem saynn kaplayaca boluk miktarn hem de bu boluklarn ne kadarnn 0 ile
doldurulacan da belirleyebilirsiniz:
>>> print("%10.5d" %23)

00023

Burada 23 saysnn toplam 10 bolukluk bir yer kaplamasn ve bu 10 adet boluun 5


tanesinin iine 0 saylarnn ve 23 saysnn sdrlmasn istedik.
Bir de una bakalm:
>>> print("%010.d" %23)

0000000023

Burada ise 23 saysnn toplam 10 bolukluk bir yer kaplamasn ve bu 10 adet bolua 23
says yerletirildikten sonra arta kalan ksmn 0 saylar ile doldurulmasn istedik.
Bu arada, son rnekte yaptmz eyi, daha nce rendiimiz zfill() metoduyla da
yapabileceimizi biliyorsunuz:
>>> "23".zfill(10)

'0000000023'

Yukardaki kullanmlar ilk bakta gznze kark grnm olabilir. Ama eer yeterince
pratik yaparsanz, aslnda bu biimlerin hi de o kadar karmak olmadn anlarsnz.
sterseniz bu biimlerle neler yapabileceimizi yle bir ksaca tarif edelim:
d har, % iaretiyle birlikte kullanldnda saylar temsil eder. Bu iki karakterin en temel
kullanm yledir:
>>> "%d" %10

'10'

d har ile % iareti arasna bir pozitif veya negatif say getirerek, temsil edilecek saynn
toplam ka boluktan oluan bir alan iine yerletirileceini belirleyebiliyoruz:
>>> "%5d" %10

' 10'

20.1. % areti ile Biimlendirme (Eski Yntem) 319


Python 3 iin Trke Klavuz, Srm 3

Burada 10 saysn toplam 5 bolukluk bir alan iine yerletirdik. Grdnz gibi, bir pozitif
say kullandmzda, saymz kendisine ayrlan alan iinde saa yaslanyor. Eer bu sayy sola
yaslamak istersek negatif saylardan yararlanabiliriz:
>>> "%-5d" %10

'10 '

Eer saa yasladmz bir saynn sol tarafn sfrla doldurmak istersek, hizalama miktarn
belirtmek iin kullandmz saynn soluna bir sfr ekleyebiliriz:
>>> "%05d" %10

'00010'

Ayn etkiyi u ekilde de elde edebilirsiniz:


>>> "%.5d" %10

'00010'

Eer nokta iaretinden nce bir say belirtirseniz, karakter dizisi o belirttiiniz say kadar saa
yaslanacaktr. Yani:
>>> "%10.5d" %10

' 00010'

... veya sola:


>>> "%-10.5d" %10

'00010 '

Her iki ekilde de, karakter dizisini toplam 10 boluktan oluan bir alan iine yerletirmi
olduk. Bu toplam alann 5 bolukluk ksm saynn kendisi ve saynn soluna gelecek 0 lar
arasnda paylatrld.
Grdnz gibi, biimlendirme mantnn aslnda o kadar da korkulacak bir yan yok. Kendi
kendinize yukardakilere benzer rnekler yaparak bu yapy daha iyi bir ekilde anlamaya
alabilirsiniz.

Bu harf de integer, yani tam say kelimesinin ksaltmasdr. Kullanm ve ilev olarak, d
harnden hi bir fark yoktur.

Bu harf octal (sekizli) kelimesinin ksaltmasdr. Adndan da anlalaca gibi, sekizli dzendeki
saylar temsil eder. Dolaysyla bu har kullanarak onlu dzendeki bir sayy sekizli dzendeki
karlna dntrebilirsiniz. rnein:
>>> print("%i saysnn sekizli dzendeki karl %o saysdr." %(10, 10))

10 saysnn sekizli dzendeki karl 12 saysdr.

320 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

Not: %d yapsn anlatrken gsterdiimiz ileri dzey biimlendirme tekniklerinin tamamn


%o ile de kullanabilirsiniz.

Bu harf hexadecimal, yani onaltl dzendeki saylar temsil eder. Dolaysyla bu har
kullanarak onlu dzendeki bir sayy onaltl dzendeki karlna evirebilirsiniz:
>>> print("%i saysnn onaltl dzendeki karl %x saysdr." %(20, 20))

20 saysnn onaltl dzendeki karl 14 saysdr.

Buradaki x kk harf olarak kullanldnda, onaltl dzende hare gsterilen saylar da


kk hare temsil edilecektir:
>>> print("%i saysnn onaltl dzendeki karl %x saysdr." %(10, 10))

10 saysnn onaltl dzendeki karl a saysdr.

Not: %d yapsn anlatrken gsterdiimiz ileri dzey biimlendirme tekniklerinin tamamn


%x ile de kullanabilirsiniz.

Bu da tpk x harnde olduu gibi, onaltl dzendeki saylar temsil eder. Ancak bunun fark,
hare gsterilen onaltl saylar byk hare temsil etmesidir:
>>> print("%i saysnn onaltl dzendeki karl %X saysdr." %(10, 10))

10 saysnn onaltl dzendeki karl A saysdr.

Not: %d yapsn anlatrken gsterdiimiz ileri dzey biimlendirme tekniklerinin tamamn


%X ile de kullanabilirsiniz.

Pythonda karakter dizilerini biimlendirirken s harnden sonra en ok kullanlan harf f


hardir. Bu harf ngilizcedeki oat, yani kayan noktal say kelimesinin ksaltmasdr.
Adndan da anlalaca gibi, karakter dizileri iindeki kayan noktal saylar temsil etmek iin
kullanlr.
>>> print("Dolar %f TL olmu..." %1.4710)

Dolar 1.471000 TL olmu...

Bu kt sizi biraz artm olabilir. nk grdnz gibi, ktda bizim eklemediimiz


haneler var.
Pythonda bir karakter dizisi iindeki sayy %f yaps ile kayan noktal sayya evirdiimizde
noktadan sonra ntanml olarak 6 hane yer alacaktr. Yani mesela:

20.1. % areti ile Biimlendirme (Eski Yntem) 321


Python 3 iin Trke Klavuz, Srm 3

>>> print("%f" %10)

10.000000

Grdnz gibi, gerekten de 10 tam says %f yaps ile kayan noktal sayya
dntrldnde noktadan sonra 6 adet sfra sahip oluyor.
Baka bir rnek daha verelim:
>>> print("%f"%23.6)

23.600000

Bu rnek, %f yapsnn, kayan noktal saylarn noktadan sonraki hane saysn da 6 ya


tamamladn gsteriyor. Ama elbette biz istersek, daha nce rendiimiz teknikleri
kullanarak, noktadan sonra ka hane olacan belirleyebiliriz:
>>> print("%.2f" % 10)

10.00

%f yapsnda, % ile f arasna .2 gibi bir ifade yerletirerek noktadan sonra 2 hane olmasn
saladk.

Not: Daha nce gsterdiimiz ileri dzey biimlendirme tekniklerini %f ile de


kullanabilirsiniz.

Bu harf de Pythondaki nemli karakter dizisi biimlendiricilerinden biridir. Bu harf tek bir
karakteri temsil eder:
>>> print("%c" %"a")

Ama:
>>> print("%c" %"istihza")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: %c requires int or char

Grdnz gibi, c har sadece tek bir karakteri kabul ediyor. Karakter says birden fazla
olduunda bu komut hata veriyor.
c harnin bir baka zellii de ASCII tablosunda saylara karlk gelen karakterleri de
gsterebilmesidir:
>>> print("%c" %65)

ASCII tablosunda 65 says A harne karlk geldii iin yukardaki komutun kts A harni
gsteriyor. Eer isterseniz c harni kullanarak btn ASCII tablosunu ekrana dkebilirsiniz:

322 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

>>> for i in range(128):


... print("%s ==> %c" %(i, i))

Not: %s yapsn anlatrken gsterdiimiz ileri dzey biimlendirme tekniklerinin tamamn


%c ile de kullanabilirsiniz.

Bylece Pythonda % iareti kullanarak nasl biimlendirme yapabileceimizi renmi olduk.


Dilerseniz pratik olmas asndan, karakter dizisi biimlendiricilerinin kullanmn gsteren
bir rnek vererek bu blm noktalayalm.
Dikkatlice inceleyin:
for sra, karakter in enumerate(dir(str)):
if sra % 3 == 0:
print("\n", end="")
print("%-20s" %karakter, end="")

Burada, grdnz gibi, karakter dizisi metotlarn bir tablo grnm iinde ekrana
yazdrdk. u satrlar yardmyla tablodaki stun saysn 3 olarak belirledik:
if sra % 3 == 0:
print("\n", end="")

Burada modls ilecini nasl kullandmza ok dikkat edin. sra deikeninin deerini 3 e
bldmzde kalan deerin 0 olduu her sayda satr bana geiyoruz. Bylece her 3.
stunda bir satr aa geilmi oluyor.
Bununla ilgili bir rnek daha verelim:
for i in range(20):
print("%5d%5o%5x" %(i, i, i))

Burada 0 dan 20 ye kadar olan saylarn onlu, sekizli ve onaltl dzendeki karlklarn bir
tablo grnm iinde ekrana kt verdik. Bu arada, eer isterseniz yukardaki kodlar yle
de yazabileceinizi biliyorsunuz:
for i in range(20):
print("%(deger)5d%(deger)5o%(deger)5x" %({"deger": i}))

Burada da, tablomuzu biimlendirmek iin szlk adn verdiimiz yapdan yararlandk.

20.2 format() Metodu ile Biimlendirme (Yeni Yntem)

En bata da sylediimiz gibi, % iaretini kullanarak karakter dizisi biimlendirme eskide


kalm bir yntemdir. Bu yntem arlkl olarak Pythonn 2.x srmlerinde kullanlyordu.
Her ne kadar bu yntemi Pythonn 3.x srmlerinde de kullanmak mmkn olsa da yeni
yazlan kodlarda bu yntem yerine biraz sonra greceimiz format() metodunu kullanmak
ok daha akllca olacaktr. nk muhtemelen % ile biimlendirme yntemi, ileriki bir Python
srmnde dilden tamamen kaldrlacak. Bu yzden bu eski metoda fazla bel balamamak
gerekiyor.
Daha nceki derslerimizde verdiimiz rnekler sayesinde format() metodunun temel olarak
nasl kullanlacan biliyoruz. Ama isterseniz biz yine de btnlk asndan format()
metodunun temel kullanmn burada tekrar ele alalm.

20.2. format() Metodu ile Biimlendirme (Yeni Yntem) 323


Python 3 iin Trke Klavuz, Srm 3

format() metodunu en basit ekilde yle kullanyoruz:


>>> print("{} ve {} iyi bir ikilidir!".format("Django", "Python"))

Django ve Python iyi bir ikilidir!

Grdnz gibi, eski yntemdeki % iaretine karlk, yeni yntemde {} iaretini


kullanyoruz.
ok basit bir rnek daha verelim:
isim = input("sminiz: ")
print("Merhaba {}. Naslsn?".format(isim))

Elbette bu rnei u ekilde de yazabilirdik:


isim = input("sminiz: ")
print("Merhaba", isim + ".", "Naslsn?")

Burada format() metodunu ve biim dzenleyicileri hi kullanmadan, sadece karakter


dizilerini birletirerek istediimiz kty elde ettik. Ama siz de gryorsunuz; karakter
dizilerini birletirmekle uraacamza format() metodunu kullanmak hem daha pratiktir,
hem de bu ekilde yazdmz kodlar daha okunakl olur.
Yukardaki rnekte format() metodunu tek bir parametre ile birlikte kullandk (isim ). Bu
parametre (tpk eski % iaretinde olduu gibi), karakter dizisi iindeki {} iaretine karlk
geliyor.
Bu konuyu daha iyi anlayabilmek iin bir rnek daha verelim:
kalk = input("Kalk yeri: ")
var = input("Var yeri: ")
isim_soyisim = input("sim ve soyisim: ")
bilet_says = input("Bilet says: ")

print("""{} noktasndan {} noktasna, 14:30 hareket saatli


sefer iin {} adna {} adet bilet ayrlmtr!""".format(kalk,
var,
isim_soyisim,
bilet_says))

Grdnz gibi, {} iaretleri karakter dizisi iinde bir yer tutma grevi gryor. Tutulan bu
yerlere nelerin geleceini format() metodunun parametreleri vastasyla belirliyoruz.
Elbette eer isterseniz yukardaki rnei u ekilde de yazabilirsiniz:
kalk = input("Kalk yeri: ")
var = input("Var yeri: ")
isim_soyisim = input("sim ve soyisim: ")
bilet_says = input("Bilet says: ")

metin = "{} noktasndan {} noktasna, 14:30 hareket saatli \


sefer iin {} adna {} adet bilet ayrlmtr!"

print(metin.format(kalk, var, isim_soyisim, bilet_says))

Ancak yaygn olarak kullanlan yntem, karakter dizisini herhangi bir deikene atamadan,
dorudan format() metoduna balamaktr. Elbette hangi yntem kolaynza geliyorsa onu

324 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

tercih etmekte zgrsnz. Ama zellikle biimlendirilecek karakter dizisinin ok uzun olduu
durumlarda, yukardaki gibi, karakter dizisini nce bir deikene atayp, sonra da bu deiken
zerine format() metodunu uygulamak daha mantkl olabilir.
Verdiimiz bu rnei, her zaman olduu gibi, format() metoduna bavurmadan yazmak da
mmkndr:
kalk = input("Kalk yeri: ")
var = input("Var yeri: ")
isim_soyisim = input("sim ve soyisim: ")
bilet_says = input("Bilet says: ")

print(kalk, "noktasndan", var, "noktasna, 14:30 hareket saatli \


sefer iin", isim_soyisim, "adna", bilet_says, "adet bilet ayrlmtr!")

Tpk daha nce verdiimiz rnekte olduu gibi, burada da format() metodunu kullanmak
karakter dizilerini birletirme yntemine gre daha mantkl ve kolay grnyor. Ayrca
bir karakter dizisi karmaklatka bu karakter dizisini sadece karakter dizisi birletirme
yntemleriyle biimlendirmeye almak bir sre sonra tam bir eziyet halini alabilir. O
yzden, Ben format() metodunu renmesem de olur, diye dnmeyin sakn. Mesela yle
bir program format() metodu kullanmadan yazmaya almak hi akl kr deildir:
kodlama = "utf-8"
site_ad = "Python Programlama Dili"
dosya = open("deneme.html", "w", encoding=kodlama)
ierik = """
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset={}" />
<title>{}</title>
</head>

<body>
<h1>istihza.com web sitesine ho geldiniz!</h1>
<p><b>{}</b> iin bir Trke belgelendirme projesi...</p>
</body>

</html>
"""

print(ierik.format(kodlama, site_ad, site_ad), file=dosya)

dosya.close()

Burada u satrn bir ksm hari btn kodlar anlayabilecek dzeydesiniz:


dosya = open("deneme.html", "w", encoding=kodlama)

Bu kodlarla, deneme.html adl bir dosya oluturduumuzu biliyorsunuz. Daha nceki


derslerimizde birka kez grdmz open() fonksiyonu Pythonda dosya oluturmamza
imkan veriyor. Bu fonksiyon iinde kullandmz parametrenin ilk ikisi size tandk
gelecektir. lk parametre dosyann adn, ikinci parametre ise bu dosyann hangi kipte
alacan gsteriyor. Burada kullandmz w parametresi deneme.html adl dosyann
yazma kipinde alacan gsteriyor. Bu fonksiyona atadmz encoding parametresi ise
oluturulacak dosyann kodlama biimini gsteriyor. Bu da Trke karakterlerin dosyada
dzgn grntlenebilmesi asndan nem tayor.

20.2. format() Metodu ile Biimlendirme (Yeni Yntem) 325


Python 3 iin Trke Klavuz, Srm 3

Kme parantezlerini, yukardaki rneklerde grld ekilde ii bo olarak kullanabilirsiniz.


Byle bir durumda Python, karakter dizisi iindeki kme parantezleriyle, karakter dizisi
dndaki deerleri teker teker ve srasyla eletirecektir. Ama isterseniz kme parantezleri
iine birer say yazarak, karakter dizisi dndaki deerlerin hangi srayla kullanlacan
belirleyebilirsiniz. rnein:

>>> "{0} {1}".format("Frat", "zgl")

'Frat zgl'

Kme parantezleri iinde say kullanabilme imkan sayesinde deerlerin srasn istediiniz
gibi dzenleyebilirsiniz:

>>> "{1} {0}".format("Frat", "zgl")

'zgl Frat'

Hatta bu zellik sayesinde deerleri bir kez yazp, birden fazla sayda tekrar edebilirsiniz:

>>> "{0} {1} ({1} {0})".format("Frat", "zgl")

'Frat zgl (zgl Frat)'

Dolaysyla, {} iaretleri iinde elerin srasn da belirterek, biraz nce verdiimiz HTML
sayfas rneini u ekilde yazabilirsiniz:
kodlama = "utf-8"
site_ad = "Python Programlama Dili"
dosya = open("deneme.html", "w", encoding=kodlama)
ierik = """
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset={0}" />
<title>{1}</title>
</head>

<body>
<h1>istihza.com web sitesine ho geldiniz!</h1>
<p><b>{1}</b> iin bir Trke belgelendirme projesi...</p>
</body>

</html>
"""

print(ierik.format(kodlama, site_ad), file=dosya)

dosya.close()

Grdnz gibi, elerin sra numarasn belirtmemiz sayesinde, karakter dizisi iinde iki kez
ihtiya duyduumuz site_ad adl deikeni format() metodu iinde iki kez yazmak zorunda
kalmadk.
Yukardaki rnekler bize, format() metodunun parametrelerine sra numarasna gre
eriebileceimizi gsteriyor. Biz ayn zamanda bu metodun parametrelerine isme gre de
eriebiliriz. ok basit bir rnek:

326 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

print("{dil} dersleri".format(dil="python"))

Bu yntemi kullanarak, ayn deikeni birka farkl yerde kullanabilirsiniz:


sayfa = """
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{konu}</title>
</head>

<body>
<h1>istihza.com web sitesine ho geldiniz!</h1>
<p><b>{konu}</b> iin bir Trke belgelendirme projesi...</p>
</body>

</html>
"""

print(sayfa.format(konu="Python Programlama Dili"))

format() metodunun yetenekleri yukarda gsterdiimiz eylerle snrl deildir. Tpk eski
biimlendirme ynteminde olduu gibi, {} iaretleri arasnda baz saylar kullanarak, karakter
dizileri zerinde hizalama ilemleri de yapabiliriz.
Dikkatlice bakn:
>>> print("{:>15}".format("istihza"))

istihza

Bu gsterim gznze olduka yabanc ve kark gelmi olabilir. Ama aslnda hi de yle
anlalmaz bir yan yoktur bu kodlarn. Grdnz gibi, burada ncelikle : adl bir iaretten
yararlanyoruz. Bu iaretin ardndan > adl baka bir iaret gryoruz. Son olarak da 15
saysn kullanyoruz.
: iareti, bir biimlendirme ilemi yapacamz gsteriyor. > iareti ise bu biimlendirmenin
bir hizalama ilemi olacan haber veriyor. En sondaki 15 says ise bu hizalama ileminin 15
karakterlik bir alan ile ilgili olduunu sylyor. Bu ekilde karakter dizisini 15 karakterlik bir
alan iine yerletirip karakter dizisini saa yasladk. Yukardaki kty daha iyi anlayabilmek
iin kodlar yle de yazabilirsiniz:
>>> print("|{:>15}|".format("istihza"))

| istihza|

Grdnz gibi, karakter dizimiz, kendisine ayrlan 15 karakterlik alan iinde saa yaslanm
vaziyette duruyor.
Eer ayn karakter dizisini sola yaslamak isterseniz yle bir ey yazabilirsiniz:
>>> print("|{:<15}|".format("istihza"))

|istihza |

Bu defa < adl iaretten yararlandmza dikkat edin.

20.2. format() Metodu ile Biimlendirme (Yeni Yntem) 327


Python 3 iin Trke Klavuz, Srm 3

Yukardaki yntemi kullanarak, karakter dizilerini sola veya saa yaslamann yansra,
kendilerine ayrlan alan iinde ortalayabilirsiniz de:
>>> print("|{:^15}|".format("istihza"))

| istihza |

Grdnz gibi, python3 ile gelen format() metodunu hizalama ilemleri iin kullanrken
farkl iaretten yararlanyoruz:
> saa yaslama
< sola yaslama
^ ortalama
Yukardaki iaretler, yaptklar ii artrdklar iin, bunlar aklda tutmak ok zor olmasa
gerek. Mesela rnek olmas asndan, eski biimlendirme ynteminin son ksmnda
verdiimiz u rnei:
for sra, karakter in enumerate(dir(str)):
if sra % 3 == 0:
print("\n", end="")
print("%-20s" %karakter, end="")

... bir de yeni format() metoduyla yazalm:


for sra, karakter in enumerate(dir(str)):
if sra % 3 == 0:
print("\n", end="")
print("{:<20}".format(karakter), end="")

Bu rnei inceleyerek, eski ile yeni yntem arasnda nelerin deitiini, neyin neye karlk
geldiini grebilirsiniz.

20.2.1 Biimlendirme Karakterleri

Hatrlarsanz Python2de geerli olan eski biimlendirme ynteminde % karakteri ile baz
hareri birlikte kullanarak karakter dizileri zerinde biimlendirme ve dntrme ilemleri
yapabiliyorduk. Ayn ey Python3 ile birlikte gelen bu format() metodu iin de geerlidir. Yani
benzer hareri kullanarak format() metodu ile de karakter dizileri zerinde biimlendirme
ve dntrme ilemleri yapabiliriz.
format() metodu ile birlikte u hareri kullanabiliyoruz:

Bu harf karakter dizilerini temsil eder.


Yalnz bu biimlendirici karakterlerin {} iaretleri iindeki kullanm ilk bakta gznze biraz
kark gelebilir:
>>> print("{:s}".format("karakter dizisi"))

karakter dizisi

328 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

Bu arada, hareri {} yapsnn iinde nasl kullandmza dikkat edin. Grdnz


gibi biimlendirme karakterini kullanrken, karakterin sol tarafna bir adet : iareti de
yerletiriyoruz. Bir rnek verelim:
print("{:s} ve {:s} iyi bir ikilidir!".format("Python", "Django"))

Yalnz, s har karakter dizilerini temsil ettii iin, {} iaretleri arasnda bu har
kullandmzda, format() metodunun alabilecei parametreyi karakter dizisiyle
snrlandrm oluruz. Dolaysyla bu har kullandktan sonra format() metodu iinde
sadece karakter dizilerini kullanabiliriz. Eer say kullanrsak Python bize bir hata mesaj
gsterecektir:
>>> print("{:s}".format(12))

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
ValueError: Unknown format code 's' for object of type 'int'

Bu yzden, eer amacnz format() metoduna parametre olarak karakter dizisi vermekse, {}
iaretleri iinde herhangi bir harf kullanmamak daha akllca olabilir:
print("{} ve {} iyi bir ikilidir!".format("Python", "Django"))

Bu harf 0 ile 256 aras saylarn ASCII tablosundaki karlklarn temsil eder:
>>> print("{:c}".format(65))

Bu harf saylar temsil eder:


>>> print("{:d}".format(65))

65

Eer say dnda bir deer kullanrsanz Python size bir hata mesaj gsterir:
>>> print("{:d}".format("65"))

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'd' for object of type 'str'

Bu harf onlu dzendeki saylar sekizli dzendeki karlklarna evirir:


>>> print("{:o}".format(65))

101

20.2. format() Metodu ile Biimlendirme (Yeni Yntem) 329


Python 3 iin Trke Klavuz, Srm 3

Bu harf onlu dzendeki saylar onaltl dzendeki karlklarna evirir:


>>> print("{:x}".format(65))

41

Tpk x harnde olduu gibi, bu harf de onlu dzendeki saylar onaltl dzendeki
karlklarna evirir:
>>> "{:X}".format(65)

'41'

Peki x ile X har arasnda ne fark var? Fark udur: x ; onaltl dzende hare gsterilen saylar
kk harf eklinde temsil eder. X iareti bu saylar byk harf eklinde temsil eder. Bu ikisi
arasndaki fark daha net grmek iin yle bir kod yazabilirsiniz:
>>> for i in range(20):
... print("{:x}{:10X}".format(i, i))
...
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
a A
b B
c C
d D
e E
f F
10 10
11 11
12 12
13 13

Grdnz gibi gerekten de x har onaltl dzende harerle gsterilen saylar kk harf
olarak; X har ise byk harf olarak temsil ediyor.

Bu iaret, onlu dzendeki saylar ikili dzendeki karlklarna evirir:


>>> "{:b}".format(2)

'10'

330 Blm 20. Karakter Dizilerini Biimlendirmek


Python 3 iin Trke Klavuz, Srm 3

Bu iaret, eski biimlendirme yntemini anlatrken gsterdiimiz f iaretiyle benzer bir ileve
sahiptir:
print("{:.2f}".format(50))

50.00

: iaretini , iareti (basamak ayrac) ile birlikte kullanarak, saylar basamaklarna


ayrabilirsiniz:
>>> "{:,}".format(1234567890)

'1,234,567,890'

Bylece Pythonda karakter dizisi biimlendirmenin hem eski hem de yeni yntemini, u ana
kadarki Python bilgimiz elverdii lde ayrntl bir ekilde incelemi olduk. Buradaki bilgileri
kullanarak bol bol rnek yapmak bu konuyu daha iyi anlamanza yardmc olacaktr.

20.2. format() Metodu ile Biimlendirme (Yeni Yntem) 331


BLM 21

Listeler ve Demetler

Bu blme gelene kadar yalnzca iki farkl veri tipi grmtk. Bunlardan biri karakter dizileri,
teki ise saylard. Ancak tabii ki Pythondaki veri tipleri yalnzca bu ikisiyle snrl deildir.
Pythonda karakter dizileri ve saylarn dnda, baka amalara hizmet eden, baka veri tipleri
de vardr. te biz bu blmde iki farkl veri tipi daha reneceiz. Bu blmde ele alacamz
veri tiplerinin ad liste (list ) ve demet (tuple ).
Bu blmde birer veri tipi olarak listeler ve demetlerden sz etmenin yansra liste
ve demetlerin metotlarndan da bahsedeceiz. Listelerle demetleri rendikten sonra
Pythondaki hareket imkannzn bir hayli genilediine tank olacaksnz.
Python programlama diline yeni balayan biri, karakter dizilerini rendikten sonra bu dilde
her eyi karakter dizileri yardmyla halledebileceini zannedebilir. O yzden yeni bir veri
tipi ile karlatnda (rnein listeler veya demetler), bu yeni veri tipi ona anlamsz ve
gereksizmi gibi grnebilir. Aslnda daha nce de sylediimiz gibi, bir programlama dilini
yeni renenlerin genel sorunudur bu. renci, bir programlama dilini oluturan minik
paralar renirken, rencinin zihni bu paralarn ne iine yarayaca konusunda pheyle
dolar. Sanki gereksiz eylerle vakit kaybediyormu gibi hissedebilir. En nemli ve en byk
programlarn, bu minik paralarn sistematik bir ekilde birletirilmesiyle ortaya kacak
olmas rencinin kafasna yatmayabilir. Halbuki en karmak programlarn bile kaynak
kodlarn incelediinizde grecekleriniz karakter dizileri, listeler, demetler, saylar ve buna
benzer baka veri tiplerinden ibarettir. Nasl en lezzetli yemekler birka basit malzemenin
bir araya gelmesi ile ortaya kyorsa, en abidevi programlar da ilk bakta birbiriyle ilgisiz
grnen ok basit paralarn incelikli bir ekilde birletirilmesinden oluur.
O halde bu noktada, Python programlama diline yeni balayan hemen herkesin sorduu o
soruyu soralm kendimize: Neden farkl veri tipleri var? Bu veri tiplerinin hepsine gerekten
ihtiyacm olacak m?
Bu soruyu baka bir soruyla cevaplamaya alalm: Acaba neden farkl giysi tipleri var?
Neden kot pantolon, kuma pantolon, tirt, gmlek ve buna benzer ayrmlara ihtiya
duyuyoruz? Bu sorunun cevab ok basit: nk farkl durumlara farkl giysi trleri
uygundur!
rnein ev tayacaksanz, herhalde kuma pantolon ve gmlek giymezsiniz zerinize. Buna
benzer bir ekilde i grmesine giderken de kot pantolon ve tirt doru bir tercih
olmayabilir. te buna benzer sebeplerden, programlama dillerinde de belli durumlarda
belli veri tiplerini kullanmanz gerekir. rnein bir durumda karakter dizilerini kullanmak
uygunken, baka bir durumda listeleri veya demetleri kullanmak daha mantkl olabilir. Zira
her veri tipinin kendine has gl ve zayf yanlar vardr. Veri tiplerini ve bunlarn ayrntlarn
rendike, hangi veri tipinin hangi sorun iin daha kullanl olduunu kestirebilecek duruma

332
Python 3 iin Trke Klavuz, Srm 3

geleceinizden hi kukunuz olmasn.


Biz bu blmde listeleri ve demetleri olabildiince ayrntl bir ekilde inceleyeceiz. O yzden
bu veri tiplerini incelerken konuyu birka farkl blme ayracaz.
Listeleri ve demetleri incelemeye listelerden balayalm...

21.1 Listeler

Giri blmnde de deindiimiz gibi, listeler Pythondaki veri tiplerinden biridir. Tpk
karakter dizileri ve saylar gibi...

21.1.1 Liste Tanmlamak

Listeleri tanmaya, bu veri tipini nasl tanmlayacamz renerek balayalm.


Hatrlarsanz bir karakter dizisi tanmlayabilmek iin yle bir yol izliyorduk:
>>> kardiz = "karakter dizisi"

Yani herhangi bir eyi karakter dizisi olarak tanmlayabilmek iin yapmamz gereken tek ey
o eyi trnak iine almakt. Herhangi bir eyi (tek, ift veya ) trnak iine aldmzda
karakter dizimizi tanmlam oluyoruz. Liste tanmlamak iin de buna benzer bir ey
yapyoruz. Dikkatlice bakn:
>>> liste = ["e1", "e2", "e3"]

Grdnz gibi, liste tanmlamak da son derece kolay. Bir liste elde etmek iin, eleri
birbirinden virglle ayrp, bunlarn hepsini keli parantezler iine alyoruz.
Karakter dizilerini anlatrken, herhangi bir nesnenin karakter dizisi olup olmadndan emin
olmak iin type() fonksiyonundan yararlanabileceimizi sylemitik. Eer bir nesne type()
fonksiyonuna <class str> cevab veriyorsa o nesne bir karakter dizisidir. Listeler iin de buna
benzer bir sorgulama yapabiliriz:
>>> liste = ["e1", "e2", "e3"]
>>> type(liste)

<class 'list'>

Bu ktdan anlyoruz ki, liste veri tipi type() fonksiyonuna <class list> cevab veriyor.
Dolaysyla, eer bir nesne type() fonksiyonuna <class list> cevab veriyorsa o nesnenin
bir liste olduunu rahatlkla syleyebiliriz.
Yukarda tanmladmz liste adl listeye baktmzda dikkatimizi bir ey ekiyor olmal. Bu
listeye yle bir baktmzda, aslnda bu listenin, iinde adet karakter dizisi barndrdn
gryoruz. Gerekten de listeler, bir veya daha fazla veri tipini iinde barndran kapsayc bir
veri tipidir. Mesela u listeye bir bakalm:
>>> liste = ["Ahmet", "Mehmet", 23, 65, 3.2]

Grdnz gibi, liste iinde hem karakter dizileri (Ahmet, Mehmet ), hem de saylar (23,
65, 3.2 ) var.
Dahas, listelerin iinde baka listeler de bulunabilir:

21.1. Listeler 333


Python 3 iin Trke Klavuz, Srm 3

>>> liste = ["Ali", "Veli", ["Aye", "Nazan", "Zeynep"], 34, 65, 33, 5.6]

Bu liste adl deikenin tipini sorgularsak yle bir kt alacamz biliyorsunuz:


>>> type(liste)

<class 'list'>

Bir de unu deneyelim:


for e in liste:
print("{} adl enin veri tipi: {}".format(e, type(e)))

Bu kodlar altrdmzda da yle bir kt alyoruz:


Ali adl enin veri tipi: <class 'str'>
Veli adl enin veri tipi: <class 'str'>
['Aye', 'Nazan', 'Zeynep'] adl enin veri tipi: <class 'list'>
34 adl enin veri tipi: <class 'int'>
65 adl enin veri tipi: <class 'int'>
33 adl enin veri tipi: <class 'int'>
5.6 adl enin veri tipi: <class 'float'>

Bu kodlar bize unu gsteriyor: Farkl eleri bir araya getirip bunlar keli parantezler iine
alrsak liste adl veri tipini oluturmu oluyoruz. Bu listenin eleri farkl veri tiplerine ait
olabilir. Yukardaki kodlarn da gsterdii gibi, liste iinde yer alan Ali ve Veli eleri birer
karakter dizisi; [Aye, Nazan, Zeynep] adl e bir liste; 34, 65 ve 33 eleri birer tam
say; 5.6 esi ise bir kayan noktal saydr. te farkl veri tiplerine ait bu elerin hepsi bir
araya gelerek liste denen veri tipini oluturuyor. Yukardaki rnekten de grdnz gibi, bir
listenin iinde baka bir liste de yer alabiliyor. rnein burada listemizin elerinden biri,
[Aye, Nazan, Zeynep] adl baka bir listedir.
Hatrlarsanz karakter dizilerinin belirleyici zellii trnak iaretleri idi. Yukardaki rneklerden
de grdnz gibi listelerin belirleyici zellii de keli parantezlerdir. Mesela:
>>> karakter = ""

Bu bo bir karakter dizisidir. u ise bo bir liste:


>>> liste = []

Tpk karakter dizilerinde olduu gibi, listelerle de iki ekilde karlaabilirsiniz:


1. Listeyi kendiniz tanmlam olabilirsiniz.
2. Liste size baka bir kaynaktan gelmi olabilir.
Yukardaki rneklerde bir listeyi kendimizin nasl tanmlayacamz rendik. Peki listeler
bize baka hangi kaynaktan gelebilir?
Hatrlarsanz karakter dizilerinin metotlarn sralamak iin dir() adl bir fonksiyondan
yararlanmtk.
Mesela karakter dizilerinin bize hangi metotlar sunduunu grmek iin bu fonksiyonu yle
kullanmtk:
>>> dir(str)

Bu komut bize u kty vermiti:

334 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',


'__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__',
'__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__',
'__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
'__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__',
'__subclasshook__', 'capitalize', 'center', 'count', 'encode', 'endswith',
'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha',
'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable',
'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition',
'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase',
'title', 'translate', 'upper', 'zfill']

Artk bu kt size ok daha anlaml geliyor olmal. Grdnz gibi ktmz keli parantezler
arasnda yer alyor. Yani aslnda yukardaki kt bir liste. Dilerseniz bunu nasl teyit
edebileceinizi biliyorsunuz:
>>> komut = dir(str)
>>> type(komut)

<class 'list'>

Grdnz gibi, tpk input() fonksiyonundan gelen verinin bir karakter dizisi olmas gibi,
dir() fonksiyonundan gelen veri tipi de bir listedir.
dir() fonksiyonu dnda, baka bir eyin daha bize liste verdiini biliyoruz. Bu ey, karakter
dizilerinin split() adl metodudur:
>>> kardiz = "stanbul Bykehir Belediyesi"
>>> kardiz.split()

['stanbul', 'Bykehir', 'Belediyesi']

Gryorsunuz, split() metodunun kts da keli parantezler iinde yer alyor. Demek ki
bu kt da bir listedir.
Peki bir fonksiyonun bize karakter dizisi mi, liste mi yoksa baka bir veri tipi mi verdiini
bilmenin ne faydas var?
Her zaman sylediimiz gibi, Pythonda o anda elinizde olan verinin tipini bilmeniz son derece
nemlidir. Aksi halde o veriyi nasl evirip evireceinizi, o veriyle neler yapabileceinizi
bilemezsiniz. Mesela stanbul Bykehir Belediyesi ifadesini ele alalm. Bu ifadeyle ilgili
size yle bir soru sorduumu dnn: Acaba bu ifadenin ilk harni nasl alrz?
Eer bu ifade size input() fonksiyonundan gelmise, yani bir karakter dizisiyse
uygulayacanz yntem farkl, split() metoduyla gelmise, yani liste ise uygulayacanz
yntem farkl olacaktr.
Eer bu ifade bir karakter dizisi ise ilk har u ekilde alabilirsiniz:
>>> kardiz = "stanbul Bykehir Belediyesi"
>>> kardiz[0]

''

Ama eer bu ifade bir liste ise yukardaki yntem size farkl bir sonu verir:

21.1. Listeler 335


Python 3 iin Trke Klavuz, Srm 3

>>> liste = kardiz.split()


>>> liste[0]

'stanbul'

nk stanbul Bykehir Belediyesi adl karakter dizisinin ilk esi karakteridir, ama
[stanbul, Bykehir, Belediyesi] adl listenin ilk esi karakteri deil, stanbul
kelimesidir.
Grdnz gibi, bir nesnenin hangi veri tipine ait olduunu bilmek o nesneyle neleri nasl
yapabileceimizi dorudan etkiliyor. O yzden programlama almalarnz esnasnda veri
tiplerine kar her zaman uyank olmalsnz.

Not: Pythonda bir nesnenin hangi veri tipine ait olduunu bilmenin neden
bu kadar nemli olduunu gerek bir rnek zerinde grmek isterseniz
istihza.com/forum/viewtopic.php?f=43&t=62 adresindeki tartmay inceleyebilirsiniz.

Her ne kadar karakter dizileri ve listeler iki farkl veri tipi olsa ve bu iki veri tipinin birbirinden
ok farkl ynleri ve yetenekleri olsa da, bu iki veri tipi arasnda nemli benzerlikler de
vardr. rnein karakter dizilerini ilerken rendiimiz pek ok fonksiyonu listelerle birlikte
de kullanabilirsiniz. Mesela karakter dizilerini incelerken rendiimiz len() fonksiyonu
listelerin boyutunu hesaplamada da kullanlabilir:
>>> diller = ["ngilizce", "Franszca", "Trke", "talyanca", "spanyolca"]
>>> len(diller)

Karakter dizileri karakterlerden oluan bir veri tipi olduu iin len() fonksiyonu karakter dizisi
iindeki karakterlerin saysn veriyor. Listeler ise baka veri tiplerini bir araya toplayan bir veri
tipi olduu iin len() fonksiyonu liste iindeki veri tiplerinin saysn sylyor.
len() fonksiyonu dnda, range() fonksiyonuyla listeleri de birlikte kullanabilirsiniz. Mesela
herhangi bir kaynaktan size unlar gibi iki eli listeler geliyor olabilir:
[0, 10]
[6, 60]
[12, 54]
[67, 99]

Bu iki eli listeleri tek bir liste iinde topladmz dnrsek yle bir kod yazabiliriz:
saylar = [[0, 10], [6, 60], [12, 54], [67, 99]]

for i in saylar:
print(*range(*i))

Eer ilk bakta bu kod gznze anlalmaz grndyse bu kodu paralara ayrarak
inceleyebilirsiniz.
Burada ncelikle bir for dngs oluturduk. Bu sayede saylar adl listedeki elerin
zerinden tek tek geebileceiz. Eer dng iinde sadece eleri ekrana yazdryor olsaydk
yle bir kodumuz olacakt:
for i in saylar:
print(i)

336 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

Bu kod bize yle bir kt verecektir:


[0, 10]
[6, 60]
[12, 54]
[67, 99]

range() fonksiyonunun nasl kullanldn hatrlyorsunuz. Yukardaki listelerde grnen ilk


saylar range() fonksiyonunun ilk parametresi, ikinci saylar ise ikinci parametresi olacak.
Yani her dngde yle bir ey elde etmemiz gerekiyor:
range(0, 10)
range(6, 60)
range(12, 54)
range(67, 99)

Aslnda kodlarmz yle yazarak yukardaki kty elde edebilirdik:


saylar = [[0, 10], [6, 60], [12, 54], [67, 99]]

for i in saylar:
print(range(i[0], i[1]))

Yukardaki aklamalarda grdnz gibi, i deikeninin kts ikier eli bir liste oluyor.
te burada yaptmz ey, bu ikier eli listelerin ilk esini (i[0]) range() fonksiyonunun
ilk parametresi, ikinci esini (i[1]) ise range() fonksiyonunun ikinci parametresi olarak
atamaktan ibaret. Ancak ilk derslerimizden hatrlayacanz gibi, bunu yapmann daha ksa
bir yolu var. Bildiiniz gibi, elerden oluan dizileri ayrtrmak iin yldz iaretinden
yararlanabiliyoruz. Dolaysyla yukardaki kodlar yle yazmak daha pratik olabilir:
saylar = [[0, 10], [6, 60], [12, 54], [67, 99]]

for i in saylar:
print(range(*i))

Grdnz gibi, i deikeninin soluna bir yldz ekleyerek bu deiken iindeki deerleri
ayrtrdk ve yle bir kt elde ettik:
range(0, 10)
range(6, 60)
range(12, 54)
range(67, 99)

Hatrlarsanz, range(0, 10) gibi bir kod yazdmzda Python bize 0 ile 10 arasndaki saylar
dorudan gstermiyordu. Aralktaki saylar grmek iin range() fonksiyonunun ktsn bir
dng iine almalyz:
for i in range(0, 10):
print(i)

range(0, 10) ktsn grmek iin dng kurmak yerine yine yldz iaretinden
yararlanabiliyoruz. rnein:
>>> print(*range(0, 10))

0 1 2 3 4 5 6 7 8 9

Ayn eyi yukardaki kodlara da uygularsak yle bir ey elde ederiz:

21.1. Listeler 337


Python 3 iin Trke Klavuz, Srm 3

saylar = [[0, 10], [6, 60], [12, 54], [67, 99]]

for i in saylar:
print(*range(*i))

Grdnz gibi, yldz iaretini hem i deikenine, hem de range() fonksiyonuna ayr ayr
uygulayarak istediimiz sonucu elde ettik.
Bu arada, yukardaki rnek bize listeler hakknda nemli bir bilgi de verdi. Karakter dizilerinin
elerine erimek iin nasl kardiz[e_sras] gibi bir formlden yararlanyorsak,
listelerin elerine erimek iin de ayn ekilde liste[e_sras] gibi bir formlden
yararlanabiliyoruz.
Listelerin elerine nasl ulaacamzn ayrntlarn biraz sonra greceiz. Ama biz imdi
listelere ilikin nemli bir fonksiyonu inceleyerek yolumuza devam edelim.

21.1.2 list() Fonksiyonu

Yukardaki rneklerden de grdnz gibi liste oluturmak iin eleri belirleyip bunlar
keli parantezler iine almamz yeterli oluyor. Bu yntemin dnda, liste oluturmann bir
yntemi daha bulunur. Mesela elimizde yle bir karakter dizisi olduunu dnelim:
>>> alfabe = "abcdefghijklmnoprstuvyz"

Sorumuz u olsun: Acaba bu karakter dizisini listeye nasl eviririz?


Karakter dizilerini anlatrken split() adl bir metottan sz etmitik. Bu metot karakter
dizilerini belli bir lte gre blmemizi salyordu. split() metoduyla elde edilen verinin
bir liste olduunu biliyorsunuz. rnein:
>>> isimler = "ahmet mehmet cem"

>>> isimler.split()

['ahmet', 'mehmet', 'cem']

Ancak split() metodunun bir karakter dizisini blp bize bir liste verebilmesi iin karakter
dizisinin belli bir lte gre blnebilir durumda olmas gerekiyor. Mesela yukardaki isimler
adl karakter dizisi belli bir lte gre blnebilir durumdadr. Neden? nk karakter dizisi
iindeki her para arasnda bir boluk karakteri var. Dolaysyla split() metodu bu karakter
dizisini boluklardan blebiliyor. Ayn ey u karakter dizisi iin de geerlidir:
>>> isimler = "elma, armut, ilek"

Bu karakter dizisini oluturan her bir para arasnda bir adet virgl ve bir adet boluk
karakteri var. Dolaysyla biz bu karakter dizisini split() metodunu kullanarak virgl +
boluk karakteri ltne gre blebiliriz:
>>> isimler.split(", ")

['elma', 'armut', 'ilek']

Ancak blmn banda tanmladmz alfabe adl karakter dizisi biraz farkldr:
>>> alfabe = "abcdefghijklmnoprstuvyz"

338 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, bu karakter dizisi tek bir paradan oluuyor. Dolaysyla bu karakter dizisini
elerine blmemizi salayacak bir lt yok. Yani bu karakter dizisini u ekilde blemeyiz:
>>> alfabe.split()

['abcdefghijklmnoprstuvyz']

Elbette bu karakter dizisini isterseniz farkl ekillerde blebilirsiniz. Mesela:


>>> alfabe.split("i")

['abcdefgh', 'jklmnoprstuvyz']

Grdnz gibi, biz burada alfabe karakter dizisini i harnden blebildik. Ama istediimiz
ey bu deil. Biz aslnda yle bir kt elde etmek istiyoruz:
['a', 'b', 'c', '', 'd', 'e', 'f', 'g', '', 'h', '', 'i', 'j',
'k', 'l', 'm', 'n', 'o', '', 'p', 'r', 's', '', 't', 'u', '',
'v', 'y', 'z']

Yani bizim amacmz, alfabe karakter dizisi iindeki her bir eyi birbirinden ayrmak. te
Trk alfabesindeki harerden oluan bu karakter dizisini, list() adl bir fonksiyondan
yararlanarak istediimiz ekilde blebiliriz:
>>> harf_listesi = list(alfabe)
>>> print(harf_listesi)

['a', 'b', 'c', '', 'd', 'e', 'f', 'g', '', 'h', '', 'i', 'j',
'k', 'l', 'm', 'n', 'o', '', 'p', 'r', 's', '', 't', 'u', '',
'v', 'y', 'z']

Bylece list() fonksiyonu yardmyla bu karakter dizisini tek hamlede listeye evirmi olduk.
Peki bir karakter dizisini neden listeye evirme ihtiyac duyarz? u anda listelerle ilgili
pek ok eyi henz bilmediimiz iin ilk bakta bu evirme ilemi gznze gereksizmi
gibi grnebilir, ama ilerleyen zamanda sizin de greceiniz gibi, baz durumlarda listeleri
maniple etmek karakter dizilerini maniple etmeye kyasla ok daha kolaydr. O yzden
kimi zaman karakter dizilerini listeye evirmek durumunda kalabilirsiniz.
list() fonksiyonunun yapt ii, daha nce rendiimiz str(), int() ve float()
fonksiyonlarnn yapt ile kyaslayabilirsiniz. list() fonksiyonu da tpk str(), int() ve
float() fonksiyonlar gibi bir dntrme fonksiyonudur. rnein int() fonksiyonunu
kullanarak say deerli karakter dizilerini sayya dntrebiliyoruz:
>>> k = "123"
>>> int(k)

123

Bu dntrme ilemi sayesinde saylar zerinde aritmetik ilem yapma imkanmz olabiliyor.
te list() fonksiyonu da buna benzer bir amaca hizmet eder. Mesela input()
fonksiyonundan gelen bir karakter dizisi ile toplama karma yapabilmek iin nasl bu
karakter dizisini nce sayya dntrmemiz gerekiyorsa, baz durumlarda bu karakter
dizisini (veya baka veri tiplerini) listeye evirmemiz de gerekebilir. Byle bir durumda list()
fonksiyonunu kullanarak farkl veri tiplerini rahatlkla listeye evirebiliriz.
Yukardaki ilevlerinin dnda, list() fonksiyonu bo bir liste oluturmak iin de
kullanlabilir:

21.1. Listeler 339


Python 3 iin Trke Klavuz, Srm 3

>>> li = list()
>>> print(li)

[]

Yukardaki kodlardan grdnz gibi, bo bir liste oluturmak iin liste = [] koduna
alternatif olarak list() fonksiyonundan da yararlanabilirsiniz.
list() fonksiyonunun nemli bir grevi de range() fonksiyonunun, say araln ekrana
basmasn salamaktr. Bildiiniz gibi, range() fonksiyonu tek bana bir say araln ekrana
dkmez. Bu fonksiyon bize yalnzca yle bir kt verir:
>>> range(10)

range(0, 10)

Bu say araln ekrana dkmek iin range() fonksiyonu zerinde bir for dngs kurmamz
gerekir:
>>> for i in range(10):
... print(i)
...
0
1
2
3
4
5
6
7
8
9

Bu blmde verdiimiz rneklerde ayn ii yle de yapabileceimizi renmitik:


>>> print(*range(10))

0 1 2 3 4 5 6 7 8 9

Bu grevi yerine getirmenin nc bir yolu da list() fonksiyonunu kullanmaktr:


>>> list(range(10))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Aslnda burada yaptmz ey range(10) ifadesini bir listeye dntrmekten ibarettir.


Burada range trnde bir veriyi list trnde bir veriye dntryoruz:
>>> type(range(10))

<class 'range'>

>>> li = list(range(10))
>>> type(li)

<class 'list'>

Grdnz gibi, yukardaki yntem de aralktaki saylar ekrana dkyor. Yalnz dikkat
ederseniz bu yntemin ktlar aslnda grn olarak birbirlerinden ince farklarla

340 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

ayrlyor. Yazdnz programda nasl bir ktya ihtiyacnz olduuna bal olarak yukardaki
yntemlerden herhangi birini tercih edebilirsiniz.
Bylece Pythonda listelerin ne olduunu ve bu veri tipinin nasl oluturulacan renmi
olduk. O halde bir adm daha atarak listelerin baka zelliklerine deinelim.

21.1.3 Listelerin elerine Erimek

Tpk karakter dizilerinde olduu gibi, listelerde de her enin bir sras vardr. Hatrlarsanz
karakter dizilerinin elerine u ekilde ulayorduk:
>>> kardiz = "python"
>>> kardiz[0]

'p'

Bu blmdeki birka rnekte de grdnz gibi, listelerin elerine ularken de ayn


yntemi kullanabiliyoruz:
>>> meyveler = ["elma", "armut", "ilek", "kiraz"]
>>> meyveler[0]

'elma'

Yalnz yntem ayn olsa da yukardaki iki kt arasnda baz farklar olduunu da gzden
karmayn. Bir karakter dizisinin 0. esini aldmzda o karakter dizisinin ilk karakterini
alm oluyoruz. Bir listenin 0. esini aldmzda ise o listenin ilk esini alm oluyoruz.
Sayma yntemi olarak ise karakter dizileri ve listelerde ayn mantk geerli. Hem listelerde
hem de karakter dizilerinde Python saymaya 0 dan balyor. Yani karakter dizilerinde olduu
gibi, listelerde de ilk enin sras 0.
Eer bu listenin elerinin hepsine tek tek ulamak isterseniz for dngsnden
yararlanabilirsiniz:
meyveler = ["elma", "armut", "ilek", "kiraz"]

for meyve in meyveler:


print(meyve)

Bu listedeki eleri numaralandrmak da mmkn:


meyveler = ["elma", "armut", "ilek", "kiraz"]

for e_sras in range(len(meyveler)):


print("{}. {}".format(e_sras, meyveler[e_sras]))

...veya enumerate() fonksiyonunu kullanarak yle bir ey de yazabiliriz:


for sra, e in enumerate(meyveler, 1):
print("{}. {}".format(sra, e))

Dediimiz gibi, liste elerine ulamak iin kullandmz yntem, karakter dizilerinin
elerine ulamak iin kullandmz yntemle ayn. Aslnda karakter dizileri ile listeler
arasndaki benzerlik bununla snrl deildir. Benzerlikleri birka rnek zerinde gsterelim:

21.1. Listeler 341


Python 3 iin Trke Klavuz, Srm 3

>>> meyveler = ["elma", "armut", "ilek", "kiraz"]


>>> meyveler[-1]

'kiraz'

Karakter dizilerinde olduu gibi, e srasn eksi deerli bir say yaptmzda liste eleri
sondan baa doru okunuyor. Dolaysyla meyveler[-1] komutu bize meyveler adl listenin
son esini veriyor.
>>> meyveler[0:2]

['elma', 'armut']

Karakter dizileri konusunu ilerken rendiimiz dilimleme yntemi listeler iin de aynen
geerlidir. Orada rendiimiz dilimleme kurallarn listelere de uygulayabiliyoruz. rnein
liste elerini ters evirmek iin yle bir kod yazabiliyoruz:
>>> meyveler[::-1]

['kiraz', 'ilek', 'armut', 'elma']

Bu blmn banda da sylediimiz gibi, liste adl veri tipi, iinde baka bir liste de
barndrabilir. Buna yle bir rnek vermitik:
>>> liste = ["Ali", "Veli", ["Aye", "Nazan", "Zeynep"], 34, 65, 33, 5.6]

Bu listedeki eler unlardr:


Ali
Veli
['Aye', 'Nazan', 'Zeynep']
34
65
33
5.6

Grdnz gibi, bu liste iinde [Aye, Nazan, Zeynep] gibi bir liste daha var. Bu liste ana
listenin elerinden biridir ve bu da teki eler gibi tek elik bir yer kaplar. Yani:
>>> len(liste)

Bu ktdan anlyoruz ki, listemiz toplam 7 eden oluuyor. Listenin 2. srasnda yer alan
listenin kendisi eden olutuu halde bu e ana liste iinde sadece tek elik bir yer
kaplyor. Yani 2. sradaki listenin eleri tek tek saylmyor. Peki byle bir liste iindeki gml
listenin elerini elde etmek istersek ne yapacaz? Yani mesela ie gemi listenin tamamn
deil de, rnein sadece Aye esini almak istersek ne yapmamz gerekiyor? Dikkatlice
bakn:
>>> liste[2][0]

'Aye'

Nazan esini almak iin:

342 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

>>> liste[2][1]

'Nazan'

Zeynep esini almak iin:


>>> liste[2][2]

'Zeynep'

Grdnz gibi, i ie gemi listelerin elerini almak olduka basit. Yapmamz gereken
tek ey, gml listenin nce ana listedeki konumunu, ardndan da almak istediimiz enin
gml listedeki konumunu belirtmektir.
stersek gml listeyi ayr bir liste olarak da alabiliriz:
>>> yeni_liste = liste[2]
>>> yeni_liste

['Aye', 'Nazan', 'Zeynep']

Bylece bu listenin elerine normal bir ekilde ulaabiliriz:


>>> yeni_liste[0]

'Aye'

>>> yeni_liste[1]

'Nazan'

>>> yeni_liste[2]

'Zeynep'

Eer bir listenin elerine erimeye alrken, varolmayan bir sra says belirtirseniz Python
size bir hata mesaj gsterecektir:
>>> liste = range(10)
>>> print(len(liste))

10

Burada range() fonksiyonundan yararlanarak 10 eli bir liste tanmladk. Bu listenin son
esinin u formle gre bulunabileceini karakter dizileri konusundan hatrlyor olmalsnz:
>>> liste[len(liste)-1]

Demek ki bu listenin son esi 9 says imi... Bir de unu deneyelim:


>>> liste[10]

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
IndexError: range object index out of range

21.1. Listeler 343


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, listemizde 10. e diye bir ey olmad iin Python bize IndexError tipinde
bir hata mesaj gsteriyor. nk bu listenin son esinin sras len(liste)-1, yani 9 dur.

21.1.4 Listelerin elerini Deitirmek

Hatrlarsanz karakter dizilerinden sz ederken bunlarn deitirilemez (immutable ) bir veri


tipi olduunu sylemitik. Bu zellikten tr, bir karakter dizisi zerinde deiiklik yapmak
istediimizde o karakter dizisini yeniden oluturuyoruz. rnein:
>>> kardiz = "istihza"
>>> kardiz = "" + kardiz[1:]
>>> kardiz

'stihza'

Listeler ise deitirilebilen (mutable ) bir veri tipidir. Dolaysyla listeler zerinde dorudan
deiiklik yapabiliriz. Bir liste zerinde deiiklik yapabilmek iin o listeyi yeniden
tanmlamamza gerek yok. u rnei dikkatlice inceleyin:
>>> renkler = ["krmz", "sar", "mavi", "yeil", "beyaz"]
>>> print(renkler)

['krmz', 'sar', 'mavi', 'yeil', 'beyaz']

>>> renkler[0] = "siyah"


>>> print(renkler)

['siyah', 'sar', 'mavi', 'yeil', 'beyaz']

Liste elerini nasl deitirdiimize ok dikkat edin. Yukardaki rnekte renkler adl listenin
0. esini deitirmek istiyoruz. Bunun iin yle bir forml kullandk:
renkler[e_sras] = yeni_e

rnek olmas asndan, ayn listenin 2. srasndaki mavi adl eyi mor yapalm bir de:
>>> renkler[2] = "mor"
>>> print(renkler)

['siyah', 'sar', 'mor', 'yeil', 'beyaz']

Grdnz gibi, listeler zerinde deiiklik yapmak son derece kolay. Srf bu zellik bile,
neden baz durumlarda listelerin karakter dizileri yerine tercih edilebileceini gsterecek
gtedir.
Liste elerini deitirmeye alrken, eer var olmayan bir sra numarasna atfta
bulunursanz Python size IndexError tipinde bir hata mesaj gsterecektir:
>>> renkler[10] = "pembe"

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range

Sra numaralarn kullanarak listeler zerinde daha ilgin ilemler de yapabilirsiniz. Mesela u
rnee bakn:

344 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

>>> liste = [1, 2, 3]


>>> liste[0:len(liste)] = 5, 6, 7
>>> print(liste)

[5, 6, 7]

Burada liste adl listenin btn elerini bir rpda deitirdik. Peki bunu nasl yaptk?
Yukardaki rnei u ekilde yazarsak biraz daha aklayc olabilir:
>>> liste[0:3] = 5, 6, 7

Bu kodlarla yaptmz ey, listenin 0. ve 3. esi arasnda kalan btn elerin yerine 5, 6 ve
7 elerini yerletirmekten ibarettir.
Karakter dizilerinden hatrlayacanz gibi, eer sra numaras bir karakter dizisinin ilk esine
karlk geliyorsa o sra numarasn belirtmeyebiliriz. Ayn ekilde eer sra numaras bir
karakter dizisinin son esine karlk geliyorsa o sra numarasn da belirtmeyebiliriz. Bu
kural listeler iin de geerlidir. Dolaysyla yukardaki rnei yle de yazabilirdik:
>>> liste[:] = 5, 6, 7

Sra numaralarn kullanarak gerekten son derece enteresan ilemler yapabilirsiniz. Sra
numaralar ile neler yapabileceinizi grmek iin kendi kendinize ve hayal gcnz
zorlayarak baz denemeler yapmanz tavsiye ederim.

21.1.5 Listeye e Eklemek

Listeler byyp klebilen bir veri tipidir. Yani Pythonda bir listeye istediiniz kadar e
ekleyebilirsiniz. Diyelim ki elimizde yle bir liste var:
>>> liste = [2, 4, 5, 7]

Bu listeye yeni bir e ekleyebilmek iin yle bir kod yazabiliriz:


>>> liste + [8]

[2, 4, 5, 7, 8]

Bu rnek, bize listeler hakknda nemli bir bilgi veriyor. Pythonda + iareti kullanarak bir
listeye e ekleyecekseniz, eklediiniz enin de liste olmas gerekiyor. Mesela bir listeye
dorudan karakter dizilerini veya saylar ekleyemezsiniz:
>>> liste + 8

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "int") to list

>>> liste + "8"

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "str") to list

Listelere + iareti ile ekleyeceiniz elerin de bir liste olmas gerekiyor. Aksi halde Python
bize bir hata mesaj gsteriyor.

21.1. Listeler 345


Python 3 iin Trke Klavuz, Srm 3

21.1.6 Listeleri Birletirmek

Baz durumlarda elinize farkl kaynaklardan farkl listeler gelebilir. Byle bir durumda bu
farkl listeleri tek bir liste halinde birletirmeniz gerekebilir. Tpk karakter dizilerinde olduu
gibi, listelerde de birletirme ilemleri iin + ilecinden yararlanabilirsiniz.
Diyelim ki elimizde yle iki adet liste var:
>>> derlenen_diller = ["C", "C++", "C#", "Java"]
>>> yorumlanan_diller = ["Python", "Perl", "Ruby"]

Bu iki farkl listeyi tek bir liste haline getirmek iin yle bir kod yazabiliriz:
>>> programlama_dilleri = derlenen_diller + yorumlanan_diller

['C', 'C++', 'C#', 'Java', 'Python', 'Perl', 'Ruby']

Bu ilemin sonucunu grelim:


>>> print(programlama_dilleri)

Grdnz gibi, derlenen_diller ve yorumlanan_diller adl listelerin elerini


programlama_dilleri adl tek bir liste iinde topladk.
Programclk maceranz boyunca listeleri birletirmenizi gerektiren pek ok farkl durumla
karlaabilirsiniz. rnein yle bir durum dnn: Diyelim ki kullanc tarafndan girilen
saylarn ortalamasn hesaplayan bir program yazmak istiyorsunuz. Bunun iin yle bir kod
yazabilirsiniz:
saylar = 0

for i in range(10):
saylar += int(input("not: "))

print(saylar/10)

Bu program kullancnn 10 adet say girmesine izin verip, program knda, girilen saylarn
ortalamasn verecektir.
Peki girilen saylarn ortalamas ile birlikte, hangi saylarn girildiini de gstermek isterseniz
nasl bir kod yazarsnz?
Eer byle bir eyi karakter dizileri ile yazmaya kalkrsanz epey eziyet ekersiniz. Ama yle
bir kod yardmyla istediiniz eyi basit bir ekilde elde edebilirsiniz:
saylar = 0
notlar = []

for i in range(10):
veri = int(input("{}. not: ".format(i+1)))
saylar += veri
notlar += [veri]

print("Girdiiniz notlar: ", *notlar)


print("Not ortalamanz: ", saylar/10)

Burada kullancdan gelen verileri her dngde tek tek notlar adl listeye gnderiyoruz.
Bylece programn sonunda, kullancdan gelen veriler bir liste halinde elimizde bulunmu

346 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

oluyor.
Bu arada, yukardaki kodlarda dikkatinizi bir ey ekmi olmal. Kullancdan gelen verileri
notlar adl listeye gnderirken yle bir kod yazdk:
notlar += [veri]

Buradaki [veri] ifadesine dikkat edin. Bu kod yardmyla kullancdan gelen veri adl
deikeni liste haline getiriyoruz. Bu yntem bizim iin yeni bir ey. Peki neden burada
list() fonksiyonundan yararlanmadk?
Bunu anlamak iin list() fonksiyonunun alma mantn anlamamz gerekiyor.
Elinizde yle bir karakter dizisi olduunu dnn:
>>> alfabe = "abcdefghijklmnoprstuvyz"

Diyelim ki siz bu karakter dizisindeki btn eleri tek tek bir listeye atmak istiyorsunuz. Bu
i iin list() fonksiyonunu kullanabileceimizi daha nce sylemitik:
>>> liste = list(alfabe)

Peki list() fonksiyonu bu karakter dizisinin elerini listeye atarken nasl bir yntem izliyor?
Aslnda list() fonksiyonunun yapt i una edeerdir:
liste = []
alfabe = "abcdefghijklmnoprstuvyz"

for harf in alfabe:


liste += harf

print(liste)

list() fonksiyonu da tam olarak byle alr. Yani bir karakter dizisi zerinde dng kurarak,
o karakter dizisinin her bir esini tek tek bir listeye atar.
for dnglerini ilerken, bu dngnn saylar zerinde almayacan sylemitik. nk
saylar, karakter dizilerinin aksine, zerinde dng kurulabilen bir veri tipi deildir. Bunu bir
rnek zerinde tekrar grelim:
>>> for i in 12345:
... print(i)
...

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

Grdnz gibi, 12345 says zerinde dng kuramyoruz. Ayn hata mesajn list()
fonksiyonunda da grrsnz:
>>> list(12345)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable

Dediimiz gibi, tpk for dngsnde olduu gibi, list() fonksiyonu da ancak, zerinde
dng kurulabilen nesneler zerinde alabilir. Mesela:

21.1. Listeler 347


Python 3 iin Trke Klavuz, Srm 3

>>> list("12345")

['1', '2', '3', '4', '5']

Bu bilgilerin nda, yukarda yazdmz kodlarn u ekilde yazlmas halinde Pythonn bize
hata mesaj gstereceini syleyebiliriz:
notlar = []

for i in range(10):
veri = int(input("{}. not: ".format(i+1)))
notlar += list(veri)

print("Girdiiniz notlar: ", *notlar)

Kullancdan gelen veri deerini int() fonksiyonuyla sayya dntrdmz iin ve saylar
da zerinde dng kurulabilen bir veri tipi olmad iin list() fonksiyonuna parametre
olarak atanamaz.
Peki kullancdan gelen veri deerini sayya dntrmeden, karakter dizisi biiminde list()
fonksiyonuna parametre olarak verirsek ne olur? Bu durumda list() fonksiyonu alr, ama
istediimiz gibi bir sonu vermez. u kodlar dikkatlice inceleyin:
notlar = []

for i in range(10):
veri = input("{}. not: ".format(i+1))
notlar += list(veri)

print("Girdiiniz notlar: ", *notlar)

Bu kodlar altrdnzda, tek haneli saylar dzgn bir ekilde listeye eklenir, ancak ift ve
daha fazla haneli saylar ise listeye para para eklenir. rnein 234 saysn girdiinizde
listeye 2, 3 ve 4 saylar tek tek eklenir. nk, yukarda da dediim gibi, list() fonksiyonu,
aslnda karakter dizileri zerine bir for dngs kurar. Yani:
>>> for i in "234":
... print(i)

2
3
4

Dolaysyla listeye 234 says bir btn olarak deil de, para para eklendii iin istediiniz
sonucu alamam olursunuz.
Peki bu sorunun stesinden nasl geleceiz? Aslnda bu sorunun zm ok basittir. Eer bir
verinin listeye para para deil de, bir btn olarak eklenmesini istiyorsanz [] iaretlerinden
yararlanabilirsiniz. Tpk u rnekte olduu gibi:
liste = []

while True:
say = input("Bir say girin: (kmak iin q) ")

if say == "q":
break

348 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

say = int(say)

if say not in liste:


liste += [say]
print(liste)
else:
print("Bu sayy daha nce girdiniz!")

Grdnz gibi, kullanc tarafndan ayn verinin birden fazla girilmesini nlemek iin de
listelerden yararlanabiliyoruz.
Yalnz burada unu syleyelim: Gerek programlarda listelere e eklemek veya listeleri
birletirmek gibi ilemler iin yukardaki gibi + ilecinden yararlanmayacaz. Yukarda
gsterdiimiz yntem de doru olmakla birlikte, bu i iin genellikle liste metotlarndan
yararlanlr. Bu metotlar birazdan greceiz.

21.1.7 Listeden e karmak

Bir listeden e silmek iin del adl ifadeden yararlanabilirsiniz. rnein:


>>> liste = [1, 5, 3, 2, 9]
>>> del liste[-1]
>>> liste

[1, 5, 3, 2]

21.1.8 Listeleri Silmek

Pythonda listeleri tamamen silmek de mmkndr. rnein:


>>> liste = [1, 5, 3, 2, 9]
>>> del liste
>>> liste

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
NameError: name 'liste' is not defined

21.1.9 Listeleri Kopyalamak

Diyelim ki, yazdnz bir programda, varolan bir listeyi kopyalamak, yani ayn listeden bir tane
daha retmek istiyorsunuz. Mesela elimizde yle bir liste olsun:
>>> li1 = ["elma", "armut", "erik"]

Amacmz bu listeden bir tane daha oluturmak. lk olarak aklnza yle bir yntem gelmi
olabilir:
>>> li2 = li1

Gerekten de bu yntem bize ayn elere sahip iki liste verdi:

21.1. Listeler 349


Python 3 iin Trke Klavuz, Srm 3

>>> print(li1)

["elma", "armut", "erik"]

>>> print(li2)

["elma", "armut", "erik"]

Gelin imdi ilk listemiz olan li1 zerinde bir deiiklik yapalm. Mesela bu listenin elma olan
ilk esini karpuz olarak deitirelim:
>>> li1[0] = "karpuz"
>>> print(li1)

["karpuz", "armut", "erik"]

Grdnz gibi, li1 adl listenin ilk esini baaryla deitirdik. imdi u noktada, li2 adl
br listemizin durumunu kontrol edelim:
>>> print(li2)

["karpuz", "armut", "erik"]

O da ne! Biz biraz nce li1 zerinde deiiklik yapmtk, ama grne gre bu deiiklikten
li2 de etkilenmi. Muhtemelen beklediiniz ey bu deildi. Yani siz li2 listesinin ieriinin
ayn kalp, deiiklikten yalnzca li1 listesinin etkilenmesini istiyordunuz. Biraz sonra bu
isteinizi nasl yerine getirebileceinizi gstereceiz. Ama nce dilerseniz, bir liste zerindeki
deiiklikten teki listenin de neden etkilendiini anlamaya alalm.
Hatrlarsanz, listelerin deitirilebilir (mutable ) bir veri tipi olduunu sylemitik. Listeler
bu zellikleriyle karakter dizilerinden ayrlyor. Zira biraz nce li1 ve li2 zerinde yaptmz
ilemin bir benzerini karakter dizileri ile yaparsak farkl bir sonu alrz. Dikkatlice bakn:
>>> a = "elma"

Burada, deeri elma olan a adl bir karakter dizisi tanmladk. imdi bu karakter dizisini
kopyalayalm:
>>> b = a

>>> a

'elma'

>>> b

'elma'

Bylece ayn deere sahip iki farkl karakter dizimiz olmu oldu.
imdi a adl karakter dizisi zerinde deiiklik yapalm. Ama biz biliyoruz ki, bir karakter
dizisini deitirmenin tek yolu, o karakter dizisini yeniden tanmlamaktr:
>>> a = "E" + a[1:]

>>> a

'Elma'

350 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

Burada yaptmz eyin bir deiiklik olmadna dikkatinizi ekmek isterim. nk aslnda
biz burada varolan a adl deiken zerinde bir deiiklik yapmak yerine, yine a ad tayan
baka bir deiken oluturuyoruz.
Peki bu deiiklikten br karakter dizisi etkilendi mi?
>>> b

'elma'

Grdnz gibi, bu deiiklik teki karakter dizisini etkilememi. Bunun sebebinin, karakter
dizilerinin deitirilemeyen (immutable ) bir veri tipi olmas olduunu sylemitik.
Gelin isterseniz bu olgunun derinlerine inelim biraz...
Yukarda a ve b adl iki deiken var. Bunlarn kimliklerini kontrol edelim:
>>> id(a)

15182784

>>> id(b)

15181184

Grdnz gibi, bu iki deiken farkl kimlik numaralarna sahip. Bu durumu u ekilde de
teyit edebileceimizi biliyorsunuz:
>>> id(a) == id(b)

False

Demek ki gerekten de id(a) ile id(b) birbirinden farklym. Yani aslnda biz ayn nesne
zerinde bir deiiklik yapmak yerine, farkl bir nesne oluturmuuz.
Bu sonu bize, bu iki karakter dizisinin bellekte farkl konumlarda saklandn gsteriyor.
Dolaysyla Python, bir karakter dizisini kopyaladmzda bellekte ikinci bir nesne daha
oluturuyor. Bu nedenle birbirinden kopyalanan karakter dizilerinin biri zerinde yaplan
herhangi bir ilem brn etkilemiyor. Ama listelerde (ve deitirilebilir btn veri
tiplerinde) durum farkl. imdi u rneklere dikkatlice bakn:
>>> liste1 = ["ahmet", "mehmet", "zlem"]

Bu listeyi kopyalayalm:
>>> liste2 = liste1

Elimizde ayn elere sahip iki liste var:


>>> liste1

['ahmet', 'mehmet', 'zlem']

>>> liste2

['ahmet', 'mehmet', 'zlem']

Bu listelerin kimlik numaralarn kontrol edelim:

21.1. Listeler 351


Python 3 iin Trke Klavuz, Srm 3

>>> id(liste1)

14901376

>>> id(liste2)

14901376

>>> id(liste1) == id(liste2)

True

Grdnz gibi, liste1 ve liste2 adl listeler ayn kimlik numarasna sahip. Yani bu iki nesne
birbiriyle ayn. Dolaysyla birinde yaptnz deiiklik brn de etkiler. Eer birbirinden
kopyalanan listelerin birbirini etkilemesini istemiyorsanz, nnzde birka seenek var.
lk seenee gre yle bir kod yazabilirsiniz:
nce zgn listemizi oluturalm:
>>> liste1 = ["ahmet", "mehmet", "zlem"]

imdi bu listeyi kopyalayalm:


>>> liste2 = liste1[:]

Burada liste1 i kopyalarken, listeyi batan sona dilimlediimize dikkat edin.


Bakalm liste1 deki deiiklik brn de etkiliyor mu:
>>> liste1[0] = "veli"
>>> liste1

['veli', 'mehmet', 'zlem']

>>> liste2

['ahmet', 'mehmet', 'zlem']

Grdnz gibi, liste1 de yaptmz deiiklik liste2 ye yansmad. Demek ki yntemimiz ie


yaram.
Ayn ii yapmak iin kullanabileceimiz ikinci yntem ise list() fonksiyonunu kullanmaktr:
nce zgn listemizi grelim:
>>> liste1 = ["ahmet", "mehmet", "zlem"]

imdi bu listeyi kopyalayalm:


>>> liste2 = list(liste1)

Artk elimizde birbirinin kopyas durumunda iki farkl liste var:


>>> liste2

['ahmet', 'mehmet', 'zlem']

>>> liste1

352 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

['ahmet', 'mehmet', 'zlem']

imdi liste2 zerinde bir deiiklik yapalm:


>>> liste2[0] = 'veli'

liste2 yi kontrol edelim:


>>> liste2

['veli', 'mehmet', 'zlem']

Bakalm liste1 bu deiiklikten etkilenmi mi:


>>> liste1

['ahmet', 'mehmet', 'zlem']

Grdnz gibi, her ey yolunda. Dilerseniz bu nesnelerin birbirinden farkl olduunu id()
fonksiyonu araclyla teyit edebileceinizi biliyorsunuz.
Listeleri kopyalamann nc bir yntemi daha var. Bu yntemi de bir sonraki blmde liste
metotlarn incelerken ele alacaz.

21.1.10 Liste reteleri (List Comprehensions)

imdi Pythondaki listelere ilikin ok nemli bir konuya deineceiz. Bu konunun ad liste
reteleri. ngilizcede buna List Comprehension ad veriliyor.
Adndan da anlalaca gibi, liste retelerinin grevi liste retmektir. Basit bir rnek ile liste
reteleri konusuna giri yapalm:
liste = [i for i in range(1000)]

Burada 0dan 1000e kadar olan saylar tek satrda bir liste haline getirdik. Bu kodlarn sz
dizimine ok dikkat edin. Aslnda yukardaki kod u ekilde de yazlabilir:
liste = []

for i in range(1000):
liste += [i]

Burada nce liste adl bo bir liste tanmladk. Daha sonra 0 ile 1000 aralnda btn saylar
bu bo listeye teker teker gnderdik. Bylece elimizde 0dan 1000e kadar olan saylar tutan
bir liste olmu oldu. Ayn i iin liste retelerini kullandmzda ise bu etkiyi ok daha ksa
bir yoldan halletmi oluyoruz. Liste retelerini kullandmz kodu tekrar nmze alalm:
liste = [i for i in range(1000)]

Grdnz gibi, burada nceden bo bir liste tanmlamamza gerek kalmad. Ayrca bu
kodlarda for dngsnn parantezler iine alnarak nasl sadeletirildiine de dikkatinizi
ekmek isterim. u kod:
for i in range(1000):
liste += [i]

21.1. Listeler 353


Python 3 iin Trke Klavuz, Srm 3

Liste retelerini kullandmzda u koda dnyor:


[i for i in range(1000)]

Pek ok durumda liste reteleri br seeneklere kyasla bir alternatif olma ilevi grr.
Yani liste reteleri ile elde edeceiniz sonucu baka aralarla da elde edebilirsiniz. Mesela
yukardaki kodlarn yapt ilevi yerine getirmek iin baka bir seenek olarak list()
fonksiyonundan da yararlanabileceimizi biliyorsunuz:
liste = list(range(1000))

Bu basit rneklerde liste retelerini kullanmann erdemi pek gze arpmyor. Ama baz
durumlarda liste reteleri teki alternatiere kyasla ok daha pratik bir zm sunar.
Byle durumlarda baka seeneklere bavurup yolunuzu uzatmak yerine liste retelerini
kullanarak iinizi ksa yoldan halledebilirsiniz.
rnein 0 ile 1000 arasndaki ift saylar listelemek iin liste retelerini kullanmak,
alternatierine gre daha makul bir tercih olabilir:
liste = [i for i in range(1000) if i % 2 == 0]

Ayn ii for dngs ile yapmak iin yle bir kod yazmamz gerekir:
liste = []
for i in range(1000):
if i % 2 == 0:
liste += [i]

Grdnz gibi, liste reteleri bize ayn ii daha ksa bir yoldan halletme imkan tanyor. Bu
arada for dngsnn ve bu dng iinde yer alan if deyiminin liste reteleri iinde nasl
grndne dikkat ediyoruz.
Liste reteleri ile ilgili bir rnek daha verelim. Mesela elinizde yle bir liste olduunu
dnn:
liste = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]

Burada i ie gemi 4 adet liste var. Bu listenin btn elerini tek bir listeye nasl alabiliriz?
Yani yle bir kty nasl elde ederiz?
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

for dnglerini kullanarak yle bir kod yazabiliriz:


liste = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]

tm = []

for i in liste:
for z in i:
tm += [z]

354 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

print(tm)

Liste reteleri ise daha ksa bir zm sunar:


liste = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]]

tm = [z for i in liste for z in i]


print(tm)

Bu liste reteci gerekten de bize ksa bir zm sunuyor, ama bu tip i ie gemi for
dnglerinden oluan liste retelerinde bazen okunakllk sorunu ortaya kabilir. Yani bu
tr i ie gemi for dnglerinden oluan liste retelerini anlamak, alternatif yntemlere
gre daha zor olabilir.
Baz durumlarda ise liste reteleri bir sorunun zm iin tek makul yol olabilir. Diyelim
ki bir X.O.X Oyunu (Tic Tac Toe ) yazyorsunuz. Bu oyunda oyuncular oyun tahtas zerine X
veya O iaretlerinden birini yerletirecek. Oyuncunun bu oyunu kazanabilmesi iin, X veya
O iaretlerinden birisinin oyun tahtas zerinde belli konumlarda bulunmas gerekiyor. Yani
mesela X iaretinin oyunu kazanabilmesi iin bu iaretin oyun tahtas zerinde u ekilde bir
dizilime sahip olmas gerekir:
O X O

___ X O

___ X ___

Bu dizilime gre oyunu X iareti kazanr. Peki X iaretinin, oyunu kazanmasn salayacak bu
dizilime ulatn nasl tespit edeceksiniz?
Bunun iin ncelikle oyun tahtas zerinde hangi dizilim ekillerinin galibiyeti getireceini
gsteren bir liste hazrlayabilirsiniz. Mesela yukardaki gibi 3x3 boyutundaki bir oyun
tahtasnda X iaretinin oyunu kazanabilmesi iin u dizilimlerden herhangi birine sahip olmas
gerekir:
[0, 0], [1, 0], [2, 0]

X ___ ___

X ___ ___

X ___ ___

[0, 1], [1, 1], [2, 1]

___ X ___

___ X ___

___ X ___

21.1. Listeler 355


Python 3 iin Trke Klavuz, Srm 3

[0, 2], [1, 2], [2, 2]

___ ___ X

___ ___ X

___ ___ X

[0, 0], [0, 1], [0, 2]

X X X
___ ___ ___

___ ___ ___

[1, 0], [1, 1], [1, 2]

___ ___ ___

X X X
___ ___ ___

[2, 0], [2, 1], [2, 2]

___ ___ ___

___ ___ ___

X X X

[0, 0], [1, 1], [2, 2]

X ___ ___

___ X ___

___ ___ X

[0, 2], [1, 1], [2, 0]

___ ___ X

___ X ___

X ___ ___

Ayn dizilimler O iareti iin de geerlidir. Dolaysyla bu kazanma ltlerini yle bir liste
iinde toplayabilirsiniz:
kazanma_ltleri = [[[0, 0], [1, 0], [2, 0]],
[[0, 1], [1, 1], [2, 1]],
[[0, 2], [1, 2], [2, 2]],
[[0, 0], [0, 1], [0, 2]],

356 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

[[1, 0], [1, 1], [1, 2]],


[[2, 0], [2, 1], [2, 2]],
[[0, 0], [1, 1], [2, 2]],
[[0, 2], [1, 1], [2, 0]]]

Oyun srasnda X veya O iaretlerinin ald konumu bu kazanma ltleri ile karlatrarak
oyunu kimin kazandn tespit edebilirsiniz. Yani kazanma_ltleri adl liste iindeki, i ie
gemi listelerden herhangi biri ile oyunun herhangi bir aamasnda tamamen eleen iaret,
oyunu kazanm demektir.
Bir sonraki blmde bu bahsettiimiz X.O.X Oyununu yazacaz. O zaman bu srecin nasl
ilediini daha ayrntl bir ekilde inceleyeceiz. imdilik yukardaki durumu temsil eden basit
bir rnek vererek liste retelerinin kullanmn incelemeye devam edelim.
rnein elinizde, yukarda bahsettiimiz kazanma ltlerini temsil eden yle bir liste
olduunu dnn:
liste1 = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12],
[13, 14, 15],
[16, 17, 18],
[19, 20, 21],
[22, 23, 24],
[25, 26, 27],
[28, 29, 30],
[31, 32, 33]]

Bir de yle bir liste:


liste2 = [1, 27, 88, 98, 50, 9, 28, 45, 54, 66, 61, 23, 10, 33,
22, 12, 6, 99, 63, 26, 87, 25, 77, 5, 16, 93, 99, 44,
59, 69, 34, 10, 60, 92, 61, 44, 5, 3, 23, 99, 79, 51,
89, 63, 53, 31, 76, 41, 49, 10, 88, 63, 55, 43, 40, 71,
16, 49, 78, 41, 35, 97, 33, 76, 25, 81, 15, 99, 64, 20,
33, 6, 89, 81, 44, 53, 59, 75, 27, 15, 64, 36, 72, 78,
34, 36, 20, 41, 41, 75, 56, 30, 86, 46, 9, 42, 21, 64,
26, 52, 77, 65, 64, 12, 38, 1, 35, 20, 73, 71, 37, 35,
72, 38, 100, 52, 16, 49, 79]

Burada amacnz liste1 iinde yer alan i ie gemi listelerden hangisinin liste2 iindeki
saylarn alt kmesi olduunu, yani liste2 iindeki saylarn, liste1 iindeki l listelerden
hangisiyle birebir eletiini bulmak. Bunun iin yle bir kod yazabiliriz:
for i in liste1:
ortak = [z for z in i if z in liste2]
if len(ortak) == len(i):
print(i)

Bu kodlar ilk bakta gznze ok karmak gelmi olabilir. Ama aslnda hi de karmak
deildir bu kodlar. imdi bu kodlar Trkeye evirelim:
1. satr: liste1 adl listedeki her bir eye i adn verelim
2. satr: i iindeki, liste2 de de yer alan her bir eye de z adn verelim ve bunlar ortak adl
bir listede toplayalm.

21.1. Listeler 357


Python 3 iin Trke Klavuz, Srm 3

3. satr: eer ortak adl listenin uzunluu i deikeninin uzunluu ile aynysa
4. satr: i yi ekrana basalm ve bylece alt kmeyi bulmu olalm.
Eer bu satrlar anlamakta zorluk ekiyorsanz okumaya devam edin. Biraz sonra vereceimiz
rnek programda da bu kodlar grecek ve bu kodlarn ne ie yaradn orada daha iyi
anlayacaksnz.

21.1.11 rnek Program: X.O.X Oyunu

u ana kadar Python programlama dili hakknda epey bilgi edindik. Buraya kadar
rendiklerimizi kullanarak ie yarar programlar yazabiliyoruz. Belki farkndasnz, belki de
deilsiniz, ama zellikle listeler konusunu renmemiz bize ok ey kazandrd.
Bir nceki blmde, bir X.O.X Oyunu yazacamzdan sz etmi ve bu oyunun Pythonla nasl
yazlabileceine dair baz ipular da vermitik. te bu blmde, Python programlama dilinde
imdiye kadar rendiklerimizi kullanarak bu oyunu yazacaz.
Yazacamz oyunun ngilizce ad Tic Tac Toe. Bu oyunun ne olduunu ve kurallarn
bir nceki blmde kabataslak bir ekilde vermitik. Eer isterseniz oyun kurallarna
wikipedia.org/wiki/ocuk_oyunlar#X_O_X_OYUNU adresinden de bakabilirsiniz.
Oyunu ve kurallarn bildiinizi varsayarak kodlamaya balayalm.
Burada ilk yapmamz gereken ey, zerinde oyun oynanacak tahtay izmek olmal. Amacmz
yle bir grnt elde etmek:
___ ___ ___

___ ___ ___

___ ___ ___

Bu tahtada oyuncu soldan saa ve yukardan aaya doru iki adet konum bilgisi girecek ve
oyunu oynayan kiinin girecei bu konumlara X ve O hareri iaretlenecek.
Byle bir grnt oluturmak iin pek ok farkl yntem kullanlabilir. Ama oyuncunun her
konum bilgisi giriinde, X veya O iaretini tahta zerinde gstereceimiz iin tahta zerinde
oyun boyunca srekli birtakm deiiklikler olacak. Bildiiniz gibi karakter dizileri, zerinde
deiiklik yapmaya msait bir veri tipi deil. Byle bir grev iin listeler daha uygun bir ara
olacaktr. O yzden tahtay oluturmada listeleri kullanmay tercih edeceiz.
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]

Grdnz gibi, burada i ie gemi adet listeden oluan bir liste var. print(tahta)
komutunu kullanarak bu listeyi ekrana yazdrrsanz listenin yaps daha belirgin bir ekilde
ortaya kacaktr:
[['___', '___', '___'], ['___', '___', '___'], ['___', '___', '___']]

Oyun tahtasn oluturduumuza gre, imdi yapmamz gereken ey bu oyun tahtasn


dzgn bir ekilde oyuncuya gstermek olmal. Dediimiz gibi, oyuncu yle bir kt grmeli:
___ ___ ___

___ ___ ___

358 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

___ ___ ___

Bu grnty elde etmek iin u kodlar yazyoruz:


print("\n"*15)

for i in tahta:
print("\t".expandtabs(30), *i, end="\n"*2)

Bu kodlarda bilmediiniz hibir ey yok. Burada grdnz her eyi nceki derslerde
renmitiniz.
Yukardaki kodlar yazarken tamamen, elde etmek istediimiz grntye odaklanyoruz.
Mesela print("\n"*15) kodunu yazmamzn nedeni, oyun tahtas iin ekranda bo bir alan
oluturmak. Bu etkiyi elde etmek iin 15 adet yeni satr karakteri bastk ekrana. Bu kodla elde
edilen etkiyi daha iyi grebilmek iin bu kodu programdan karmay deneyebilirsiniz.
Alttaki satrda ise bir for dngs tanmladk. Bu dngnn amac tahta adl listedeki __
elerini dzgn bir ekilde oyuncuya gsterebilmek. Oyun tahtasnn, ekran (yaklak olarak
da olsa) ortalamasn istiyoruz. O yzden, tahta elerine soldan girinti verebilmek iin
print() fonksiyonunun ilk parametresini "\t".expandtabs(30) eklinde yazdk. Karakter
dizilerinin expandtabs() adl metodunu nceki derslerimizden hatrlyor olmalsnz. Bu
metodu kullanarak sekme (TAB) karakterlerini geniletebiliyorduk. Burada da \t karakterini
bu metot yardmyla genileterek liste elerini sol batan girintiledik.
print() fonksiyonunun ikinci parametresi ise *i. Bu parametrenin ne i yaptn anlamak
iin yle bir kod yazalm:
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]

for i in tahta:
print(i)

Bu kodlar altrdmzda yle bir kt elde ederiz:


['___', '___', '___']
['___', '___', '___']
['___', '___', '___']

Grdnz gibi, i ie gemi adet listeden oluan tahta adl liste iindeki bu i listeler
ekrana dkld. Bir de una bakn:
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]

for i in tahta:
print(*i)

Bu kodlar altrldnda u kty verir:


___ ___ ___
___ ___ ___
___ ___ ___

21.1. Listeler 359


Python 3 iin Trke Klavuz, Srm 3

Bu defa liste yapsn deil, listeyi oluturan elerin kendisini gryoruz. Yldz iaretinin,
birlikte kullanld eler zerinde nasl bir etkiye sahip olduunu yine nceki derslerimizden
hatrlyorsunuz. Mesela u rnee bakn:
kardiz = "istihza"

for i in kardiz:
print(i, end=" ")
print()

Bu kodlar u kty veriyor:


i s t i h z a

Ayn kty basite u ekilde de elde edebileceimizi biliyorsunuz:


kardiz = "istihza"
print(*kardiz)

te oyun tahtasn ekrana dkmek iin kullandmz kodda da benzer bir ey yaptk. Yldz
iareti yardmyla, tahta adl listeyi oluturan i ie gemi listeleri liste dna karp dzgn
bir ekilde kullancya gsterdik.
print() fonksiyonu iindeki son parametremiz u: end="\n"*2
Bu parametrenin ne ie yaradn kolaylkla anlayabildiinizi zannediyorum. Bu parametre
de istediimiz kty elde etmeye ynelik bir abadan ibarettir. tahta adl liste iindeki i ie
gemi listelerin her birinin sonuna ikier adet \n karakteri yerletirerek, ktdaki satrlar
arasnda yeterli miktarda aralk braktk. Eer oyun tahtasndaki satrlarn biraz daha aralkl
olmasn isterseniz bu parametredeki 2 arpann artrabilirsiniz. Mesela: end="\n"*3
imdi yapmamz gereken ey, oyundaki kazanma ltlerini belirlemek. Hatrlarsanz bu
konuya bir nceki blmde deinmitik. O yzden aada syleyeceklerimizin bir blmne
zaten ainasnz. Burada nceden sylediimiz baz eylerin yeniden zerinden geeceiz.
Dediim gibi, kodlarn bu blmnde, hangi durumda oyunun biteceini ve kazanann kim
olacan tespit edebilmemiz gerekiyor. Mesela oyun srasnda yle bir grnt ortaya
karsa hemen oyunu durdurup O KAZANDI! gibi bir kt verebilmemiz lazm:
O O O

___ X X

___ ___ ___

Veya yle bir durumda X KAZANDI! diyebilmeliyiz:


X O ___

X O O

X ___ ___

Yukardaki iki rnek zerinden dnecek olursak, herhangi bir iaretin u konumlarda
bulunmas o iaretin kazandn gsteriyor:
yukardan aaya 0; soldan saa 0
yukardan aaya 1; soldan saa 0
yukardan aaya 2; soldan saa 0

360 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

veya:
yukardan aaya 0; soldan saa 0
yukardan aaya 0; soldan saa 1
yukardan aaya 0; soldan saa 2

te bizim yapmamz gereken ey, bir iaretin oyun tahtas zerinde hangi konumlarda
bulunmas halinde oyunun biteceini tespit etmek. Yukardaki rnekleri gz nne alarak
bunun iin yle bir liste hazrlayabiliriz:
kazanma_ltleri = [[[0, 0], [1, 0], [2, 0]],
[[0, 0], [0, 1], [0, 2]]]

Burada iki adet listeden oluan, kazanma_ltleri adl bir listemiz var. Liste iinde, her biri
er eden oluan u listeleri gryoruz:
[[0, 0], [1, 0], [2, 0]]
[[0, 0], [0, 1], [0, 2]]

Bu listeler de kendi iinde ikier eli baz listelerden oluuyor. Mesela ilk liste iinde u
listeler var:
[0, 0], [1, 0], [2, 0]

kinci liste iinde ise u listeler:


[0, 0], [0, 1], [0, 2]

Burada her bir liste iindeki ilk say oyun tahtasnda yukardan aaya doru olan dzlemi;
ikinci say ise soldan saa doru olan dzlemi gsteriyor.
Tabii ki oyun iindeki tek kazanma lt bu ikisi olmayacak. teki kazanma ltlerini de tek
tek tanmlamalyz:
kazanma_ltleri = [[[0, 0], [1, 0], [2, 0]],
[[0, 1], [1, 1], [2, 1]],
[[0, 2], [1, 2], [2, 2]],
[[0, 0], [0, 1], [0, 2]],
[[1, 0], [1, 1], [1, 2]],
[[2, 0], [2, 1], [2, 2]],
[[0, 0], [1, 1], [2, 2]],
[[0, 2], [1, 1], [2, 0]]]

te X veya O iaretleri kazanma_ltleri adl listede belirtilen koordinatlarda bulunduunda,


ilgili iaretin oyunu kazandn ilan edip oyundan kabileceiz.
Yukardaki aklamalardan da anlayacanz gibi, X ve O iaretlerinin oyun tahtasndaki
konumu, oyunun gidiat asndan nem tayor. O yzden u ekilde iki farkl liste daha
tanmlamamzda fayda var:
x_durumu = []
o_durumu = []

Bu deikenler srasyla X iaretinin ve O iaretinin oyun iinde aldklar konumlar


kaydedecek. Bu konumlarla, bir nceki admda tanmladmz kazanma ltlerini
karlatrarak oyunu kimin kazandn tespit edebileceiz.
Grdnz gibi, oyunda iki farkl iaret var: X ve O. Dolaysyla oynama sras srekli
olarak bu iki iaret arasnda deimeli. Mesela oyuna 0 iareti ile balanacaksa, 0 iaretinin

21.1. Listeler 361


Python 3 iin Trke Klavuz, Srm 3

yerletirilmesinden sonra srann X iaretine gemesi gerekiyor. X iareti de yerletirildikten


sonra sra tekrar 0 iaretine gemeli ve oyun sresince bu byle devam edebilmeli.
Bu sreklilii salamak iin yle bir kod yazabiliriz:
sra = 1

while True:
if sra % 2 == 0:
iaret = "X".center(3)
else:
iaret = "O".center(3)

sra += 1

print()
print("ARET: {}\n".format(iaret))

Burada saylarn tek veya ift olma zelliinden yararlanarak X ve O iaretleri arasnda gei
yaptk. nce sra adl bir deiken tanmlayp bunun deerini 1 olarak belirledik. while
dngsnde ise bu deikenin deerini her defasnda 1 artrdk. Eer saynn deeri iftse
iaret X; tekse O olacak. Bu arada X ve O adl karakter dizilerini, center() metodu yardmyla
ortaladmza dikkat edin.
Yukardaki kodlar bu ekilde altrdnzda X ve O harerinin ok hzl bir ekilde ekrandan
getiini greceksiniz. Eer ekranda son hz akp giden bu verileri yavalatmak ve neler olup
bittiini daha net grmek isterseniz yukardaki kodlar yle yazabilirsiniz:
from time import sleep

sra = 1

while True:
if sra % 2 == 0:
iaret = "X".center(3)
else:
iaret = "O".center(3)
sra += 1

print()
print("ARET: {}\n".format(iaret))
sleep(0.3)

Bu kodlarda henz renmediimiz paralar var. Ama imdilik bu bilmediiniz paralara


deil, sonuca odaklann. Burada yaptmz ey, while dngs iinde her bir print()
fonksiyonu arasna 0.3 saniyelik duraklamalar eklemek. Bylece programn ak yavalam
oluyor. Biz de iaret deikeninin her dngde bir X, bir O oluunu daha net bir ekilde
grebiliyoruz.

Not: Asl program iinde X ve O karakterlerinin geiini zellikle yavalatmamza gerek


kalmayacak. Programn ilerleyen satrlarnda input() fonksiyonu yardmyla kullancdan veri
girii isteyeceimiz iin X ve Olarn ak zaten doal olarak duraklam olacak.

while dngmz yazmaya devam edelim:

362 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

x = input("yukardan aaya [1, 2, 3]: ".ljust(30))


if x == "q":
break

y = input("soldan saa [1, 2, 3]: ".ljust(30))


if y == "q":
break

x = int(x)-1
y = int(y)-1

Burada X veya O iaretlerini tahta zerinde uygun yerlere yerletirebilmek iin kullancnn
konum bilgisi girmesini istiyoruz. x deikeni yukardan aaya doru olan dzlemdeki
konumu, y deikeni ise soldan saa doru olan dzlemdeki konumu depolayacak. Oyunda
kullancnn girebilecei deerler 1, 2 veya 3 olacak. Mesela oyuncu O iareti iin yukardan
aaya 1; soldan saa 2 deerini girmise yle bir grnt elde edeceiz:
___ O ___

___ ___ ___

___ ___ ___

Burada ljust() metotlarn, kullancya gsterilecek verinin dzgn bir ekilde hizalanmas
amacyla kullandk.
Eer kullanc x veya y deikenlerinden herhangi birine q cevab verirse oyundan kyoruz.
Yukardaki kodlarn son iki satrnda ise kullancdan gelen karakter dizilerini birer sayya
dntryoruz. Bu arada, bildiiniz gibi Python saymaya 0dan balyor. Ama insanlar
asndan doal olan saymaya 1den balamaktr. O yzden mesela kullanc 1 saysn
girdiinde Pythonn bunu 0 olarak alglamasn salamamz gerekiyor. Bunun iin x ve y
deerlerinden 1 karyoruz.
Kullancdan gerekli konum bilgilerini aldmza gre, bu bilgilere dayanarak X ve O
iaretlerini oyun tahtas zerine yerletirebiliriz. imdi u kodlar dikkatlice inceleyin:
print("\n"*15)

if tahta[x][y] == "___":
tahta[x][y] = iaret
if iaret == "X".center(3):
x_durumu += [[x, y]]
elif iaret == "O".center(3):
o_durumu += [[x, y]]
sra += 1
else:
print("\nORASI DOLU! TEKRAR DENEYN\n")

Burada ncelikle 15 adet satr ba karakteri basyoruz. Bylece oyun tahtas iin ekranda bo
bir alan oluturmu oluyoruz. Bu satr tamamen gzel bir grnt elde etmeye ynelik bir
uygulamadr. Yani bu satr yazmasanz da programnz alr. Veya siz kendi zevkinize gre
daha farkl bir grnm elde etmeye alabilirsiniz.
kinci satrda grdmz if tahta[x][y] == "___": kodu, oyun tahtas zerindeki bir
konumun halihazrda bo mu yoksa dolu mu olduunu tespit etmemizi salyor. Amacmz
oyuncunun ayn konuma iki kez giri yapmasn engellemek. Bunun iin tahta zerinde x ve

21.1. Listeler 363


Python 3 iin Trke Klavuz, Srm 3

y konumlarna denk gelen yerde ___ iaretinin olup olmadna bakmamz yeterli olacaktr.
Eer baklan konumda ___ iareti varsa oras bo demektir. O konuma iaret koyulabilir.
Ama eer o konumda ___ iareti yoksa X veya O iaretlerinden biri var demektir. Dolaysyla
o konuma iaret koyulamaz. Byle bir durumda kullancya ORASI DOLU! TEKRAR DENEYN
uyarsn gsteriyoruz.
Oyun tahtas zerinde deiiklik yapabilmek iin nasl bir yol izlediimize dikkat edin:
tahta[x][y] = iaret

Mesela oyuncu yukardan aaya 1; soldan saa 2 saysn girmise, kullancdan gelen
saylardan 1 kardmz iin, Python yukardaki kodu yle deerlendirecektir:
tahta[0][1] = iaret

Yani tahta adl liste iindeki ilk listenin ikinci srasna ilgili iaret yerletirilecektir.
Ayrca yukardaki kodlarda u satrlar da gryoruz:
if iaret == "X".center(3):
x_durumu += [[x, y]]
elif iaret == "O".center(3):
o_durumu += [[x, y]]

Eer iaret sras Xte ise oyuncunun girdii konum bilgilerini x_durumu adl deikene,
eer iaret sras Oda ise konum bilgilerini o_durumu adl deikene yolluyoruz. Oyunu
hangi iaretin kazandn tespit edebilmemiz asndan bu kodlar byk nem tayor.
x_durumu ve o_durumu deikenlerini kazanma_ltleri adl liste ile karlatrarak oyunu
kimin kazandna karar vereceiz.
Bu arada, oyunun en banda tanmladmz sra adl deikeni if blou iinde artrdmza
dikkat edin. Bu sayede, kullancnn yanllkla ayn konuma iki kez iaret yerletirmeye
almas halinde iaret sras deimeyecek. Yani mesela o anda sra Xte ise ve oyuncu yanl
bir konum girdiyse sra yine Xte olacak. Eer sra deikenini if blou iine yazmazsak, yanl
konum girildiinde iaret sras Oa geecektir.
sterseniz imdiye kadar yazdmz kodlar yle bir topluca grelim:
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]

print("\n"*15)

for i in tahta:
print("\t".expandtabs(30), *i, end="\n"*2)

kazanma_ltleri = [[[0, 0], [1, 0], [2, 0]],


[[0, 1], [1, 1], [2, 1]],
[[0, 2], [1, 2], [2, 2]],
[[0, 0], [0, 1], [0, 2]],
[[1, 0], [1, 1], [1, 2]],
[[2, 0], [2, 1], [2, 2]],
[[0, 0], [1, 1], [2, 2]],
[[0, 2], [1, 1], [2, 0]]]

x_durumu = []
o_durumu = []

364 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

sra = 1
while True:
if sra % 2 == 0:
iaret = "X".center(3)
else:
iaret = "O".center(3)

print()
print("ARET: {}\n".format(iaret))

x = input("yukardan aaya [1, 2, 3]: ".ljust(30))


if x == "q":
break

y = input("soldan saa [1, 2, 3]: ".ljust(30))


if y == "q":
break

x = int(x)-1
y = int(y)-1

print("\n"*15)

if tahta[x][y] == "___":
tahta[x][y] = iaret
if iaret == "X".center(3):
x_durumu += [[x, y]]
elif iaret == "O".center(3):
o_durumu += [[x, y]]
sra += 1
else:
print("\nORASI DOLU! TEKRAR DENEYN\n")

Grdnz gibi epey kod yazmz. Kodlarmz topluca incelediimize gre yazmaya devam
edebiliriz:
for i in tahta:
print("\t".expandtabs(30), *i, end="\n"*2)

Bu kodlarn ne ie yaradnz biliyorsunuz. Oyun tahtasnn son durumunu kullancya


gstermek iin kullanyoruz bu kodlar.
Sra geldi oyunun en nemli ksmna. Bu noktada oyunu kimin kazandn belirlememiz
gerekiyor. Dikkatlice inceleyin:
for i in kazanma_ltleri:
o = [z for z in i if z in o_durumu]
x = [z for z in i if z in x_durumu]
if len(o) == len(i):
print("O KAZANDI!")
quit()
if len(x) == len(i):
print("X KAZANDI!")
quit()

Bu kodlar anlayabilmek iin en iyi yol uygun yerlere print() fonksiyonlar yerletirerek
ktlar incelemektir. Mesela bu kodlar yle yazarak o ve x deikenlerinin deerlerini

21.1. Listeler 365


Python 3 iin Trke Klavuz, Srm 3

izleyebilirsiniz:
for i in kazanma_ltleri:
o = [z for z in i if z in o_durumu]
x = [z for z in i if z in x_durumu]
print("o: ", o)
print("x: ", x)
if len(o) == len(i):
print("O KAZANDI!")
quit()
if len(x) == len(i):
print("X KAZANDI!")
quit()

Bu kodlar iindeki en nemli eler o ve x adl deikenlerdir. Burada, o_durumu


veya x_durumu adl listelerdeki deerlerle kazanma_ltleri adl listedeki deerleri
karlatrarak, ortak deerleri o veya x deikenlerine yolluyoruz. Eer ortak e says 3e
ularsa (if len(o) == len(i): veya if len(x) == len(i):), bu sayy yakalayan ilk iaret
hangisiyse oyunu o kazanm demektir.
Kodlarmzn son hali yle oldu:
tahta = [["___", "___", "___"],
["___", "___", "___"],
["___", "___", "___"]]

print("\n"*15)

for i in tahta:
print("\t".expandtabs(30), *i, end="\n"*2)

kazanma_ltleri = [[[0, 0], [1, 0], [2, 0]],


[[0, 1], [1, 1], [2, 1]],
[[0, 2], [1, 2], [2, 2]],
[[0, 0], [0, 1], [0, 2]],
[[1, 0], [1, 1], [1, 2]],
[[2, 0], [2, 1], [2, 2]],
[[0, 0], [1, 1], [2, 2]],
[[0, 2], [1, 1], [2, 0]]]

x_durumu = []
o_durumu = []

sra = 1
while True:
if sra % 2 == 0:
iaret = "X".center(3)
else:
iaret = "O".center(3)

print()
print("ARET: {}\n".format(iaret))

x = input("yukardan aaya [1, 2, 3]: ".ljust(30))


if x == "q":
break

y = input("soldan saa [1, 2, 3]: ".ljust(30))

366 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

if y == "q":
break

x = int(x)-1
y = int(y)-1

print("\n"*15)

if tahta[x][y] == "___":
tahta[x][y] = iaret
if iaret == "X".center(3):
x_durumu += [[x, y]]
elif iaret == "O".center(3):
o_durumu += [[x, y]]
sra += 1
else:
print("\nORASI DOLU! TEKRAR DENEYN\n")

for i in tahta:
print("\t".expandtabs(30), *i, end="\n"*2)

for i in kazanma_ltleri:
o = [z for z in i if z in o_durumu]
x = [z for z in i if z in x_durumu]

if len(o) == len(i):
print("O KAZANDI!")
quit()
if len(x) == len(i):
print("X KAZANDI!")
quit()

Grdnz gibi, sadece u ana kadar rendiimiz bilgileri kullanarak bir oyun yazabilecek
duruma geldik. Burada kk paralar birletirerek bir btne nasl ulatmz zellikle
grmenizi isterim. Dikkat ederseniz, yukardaki programda sadece karakter dizileri, saylar,
listeler ve birka fonksiyon var. Nasl sadece 7 nota ile mzik aheserleri meydana
getirilebiliyorsa, yalnzca 4-5 veri tipi ile de dnyay ayaa kaldracak programlar da yazlabilir.
Listeleri temel olarak incelediimize gre biraz da demetlerden sz edebiliriz.

21.2 Demetler

Demetler, zellikle grn olarak listelere ok benzeyen bir veri tipidir. Bu veri tipi de, tpk
listeler gibi, farkl veri tiplerini iinde barndran kapsayc bir veri tipidir.

21.2.1 Demet Tanmlamak

Demet tanmlamann birka farkl yolu vardr. Nasl karakter dizilerinin ayrt edici zellii
trnak iaretleri, listelerin ayrt edici zellii ise keli parantez iaretleri ise, demetlerin ayrt
edici zellii de normal parantez iaretleridir. Dolaysyla bir demet tanmlamak iin normal
parantez iaretlerinden yararlanacaz:

21.2. Demetler 367


Python 3 iin Trke Klavuz, Srm 3

>>> demet = ("ahmet", "mehmet", 23, 45)

>>> type(demet)

<class 'tuple'>

Grdnz gibi, karakter dizilerinin type() sorgusuna str, listelerin ise list cevab vermesi
gibi, demetler de type() sorgusuna tuple cevab veriyor.
Yalnz, dediimiz gibi Pythonda demet tanmlamann birden fazla yolu vardr. Mesela
yukardaki demeti yle de tanmlayabiliriz:
>>> demet = "ahmet", "mehmet", 23, 45

Grdnz gibi, parantez iaretlerini kullanmadan, eleri yalnzca virgl iareti ile
ayrdmzda da elde ettiimiz ey bir demet oluyor.
Demet oluturmak iin tuple() adl bir fonksiyondan da yararlanabilirsiniz. Bu fonksiyon,
liste oluturan list() fonksiyonuna ok benzer:
>>> tuple('abcdefg')

('a', 'b', 'c', 'd', 'e', 'f', 'g')

Bu fonksiyonu kullanarak baka veri tiplerini demete dntrebilirsiniz:


>>> tuple(["ahmet", "mehmet", 34, 45])

('ahmet', 'mehmet', 34, 45)

Burada, [ahmet, mehmet, 34, 45] adl bir listeyi tuple() fonksiyonu yardmyla demete
dntrdk.

21.2.2 Tek eli bir Demet Tanmlamak

Tek eli bir karakter dizisi oluturabilmek iin u yolu izliyorduk hatrlarsanz:
>>> kardiz = 'A'

Bu tek eli bir karakter dizisidir. Bir de tek eli bir liste tanmlayalm:
>>> liste = ['ahmet']

Bu da tek eli bir listedir. Gelin bir de tek eli bir demet oluturmaya alalm:
>>> demet = ('ahmet')

Bu ekilde tek eli bir demet oluturduunuzu zannediyorsunuz, ama aslnda


oluturduunuz ey basit bir karakter dizisinden ibaret! Gelin kontrol edelim:
>>> type(demet)

<class 'str'>

Python programlama dilinde tek eli bir demet oluturma ilemi biraz tuhaftr. Eer tek
eye sahip bir demet oluturacaksak yle bir ey yazmalyz:

368 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

>>> demet = ('ahmet',)

veya:
>>> demet = 'ahmet',

Grdnz gibi, tek eli bir demet tanmlarken, o tek enin yanna bir tane virgl iareti
yerletiriyoruz. Bylece demet tanmlamak isterken, yanllkla alelade bir ekilde ahmet adl
bir karakter dizisini demet adl bir deikene atamam oluyoruz...

21.2.3 Demetlerin elerine Erimek

Eer bir demet iinde yer alan herhangi bir eye erimek isterseniz, karakter dizileri ve
listelerden hatrladnz yntemi kullanabilirsiniz:
>>> demet = ('elma', 'armut', 'kiraz')
>>> demet[0]

'elma'

>>> demet[-1]

'kiraz'

>>> demet[:2]

('elma', 'armut')

Grdnz gibi, daha nce rendiimiz indeksleme ve dilimleme kurallar aynen demetler
iin de geerli.

21.2.4 Demetlerle Listelerin Birbirinden Fark

En bata da sylediimiz gibi, demetlerle listeler birbirine ok benzer. Ama demetlerle


listelerin birbirinden ok nemli baz farklar da vardr. Bu iki veri tipi arasndaki en
nemli fark, listelerin deitirilebilir (mutable ) bir veri tipi iken, demetlerin deitirilemez
(immutable ) bir veri tipi olmasdr. Yani tpk karakter dizileri gibi, demetler de bir kez
tanmlandktan sonra bunlarn zerinde deiiklik yapmak mmkn deildir:
>>> demet = ('elma', 'armut', 'kiraz')
>>> demet[0] = 'karpuz'

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Grdnz gibi, demetin herhangi bir esini deitirmeye altmzda Python bize bir
hata mesaj gsteriyor.
Bu bakmdan, eer programn ak esnasnda zerinde deiiklik yapmayacanz veya
deiiklik yaplmasn istemediiniz birtakm veriler varsa ve eer siz bu verileri liste benzeri
bir tayc iine yerletirmek istiyorsanz, listeler yerine demetleri kullanabilirsiniz. Ayrca
demetler zerinde ilem yapmak listelere kyasla daha hzldr. Dolaysyla, performans
avantaj nedeniyle de listeler yerine demetleri kullanmak isteyebilirsiniz.

21.2. Demetler 369


Python 3 iin Trke Klavuz, Srm 3

Tahmin edebileceiniz gibi, tpk karakter dizilerinde olduu gibi, nceden tanmlanm
bir demetin zerinde deiiklik yapabilmek iin, rnein bir demetle baka bir demeti
birletirmek iin o demeti yeniden tanmlamak da mmkndr:
>>> demet = ('ahmet', 'mehmet')
>>> demet = demet + ('selin',)

Eer sadece demet + (selin,) demi olsaydk zgn demet zerinde herhangi bir
deiiklik yapm olmayacaktk. Siz bu olguya karakter dizilerinden de ainasnz. O yzden,
zgn demet zerinde herhangi bir deiiklik yapabilmek iin, daha dorusu zgn demet
zerinde bir deiiklik yapm gibi grnebilmek iin, zgn demeti sfrdan tanmlamamz
gerekiyor...
Burada ayrca ahmet ve mehmet elerinden oluan bir demete selin esini nasl
eklediimize de dikkat edin. Asla unutmamalsnz: Python programlama dilinde sadece ayn
tr verileri birbiriyle birletirebilirsiniz. Mesela yukardaki rnekte selin adl eyi demet adl
demete bir karakter dizisi olarak ekleyemezsiniz:
>>> demet = demet + 'selin'

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "str") to tuple

Bu arada, yukardaki kodu yle yazdnzda da aslnda bir demetle karakter dizisini
birletirmeye alyor olduunuza dikkat edin:
>>> demet = demet + ('selin')

Hatrlarsanz, tek eli bir demet tanmlayabilmek iin parantez iindeki tek enin yanna bir
virgl iareti yerletirmemiz gerekiyordu. Aksi halde demet deil, karakter dizisi tanmlam
oluyorduk. Zaten bir Python programcs olarak, demetler zerinde alrken en sk
yapacanz hata da demet tanmlamaya alrken yanllkla karakter dizisi tanmlamak
olacaktr.
Dediimiz ve yukarda da rneklerle gsterdiimiz gibi, bir demeti yeni batan tanmlayarak
da o demet zerinde deiiklik yapm etkisi elde edebilirsiniz. Ancak elbette bir araya
topladnz veriler zerinde sk sk deiiklikler yapacaksanz demetler yerine listeleri tercih
etmelisiniz.

21.2.5 Demetlerin Kullanm Alan

Demetleri ilk rendiinizde bu veri tipi size son derece gereksizmi gibi gelebilir. Ama
aslnda olduka yaygn kullanlan bir veri tipidir bu. zellikle programlarn ayar (conf )
dosyalarnda bu veri tipi sklkla kullanlr. rnein Python tabanl bir web ats (framework )
olan Djangonun settings.py adl ayar dosyasnda pek ok deer bir demet olarak saklanr.
Mesela bir Django projesinde web sayfalarnn ablonlarn (template ) hangi dizin altnda
saklayacanz belirlediiniz ayar yle grnr:
TEMPLATE_DIRS = ('/home/projects/djprojects/blog/templates',)

Burada, ablon dosyalarnn hangi dizinde yer alacan bir demet iinde gsteriyoruz. Bu
demet iine birden fazla dizin ad yazabilirdik. Ama biz btn ablon dosyalarn tek bir dizin
altnda tutmay tercih ettiimiz iin tek eli bir demet tanmlamz. Bu arada, daha nce
de sylediimiz gibi, demetlerle ilgili en sk yapacanz hata, tek eli demet tanmlamaya

370 Blm 21. Listeler ve Demetler


Python 3 iin Trke Klavuz, Srm 3

alrken aslnda yanllkla bir karakter dizisi tanmlamak olacaktr. rnein yukardaki
TEMPLATE_DIRS deikenini yle yazsaydk:
TEMPLATE_DIRS = ('/home/projects/djprojects/blog/templates')

Aslnda bir demet deil, alelade bir karakter dizisi tanmlam olurduk...

21.2. Demetler 371


BLM 22

Listelerin ve Demetlerin Metotlar

22.1 Listelerin Metotlar

Burada, geen blmde kaldmz yerden devam edeceiz listeleri anlatmaya. Arlkl olarak
bu blmde listelerin metotlarndan sz edeceiz. Metot kavramn karakter dizilerinden
hatrlyorsunuz. Karakter dizilerini anlatrken bol miktarda metot grmtk.
Pythonda btn veri tipleri bize birtakm metotlar sunar. Bu metotlar yardmyla, ilgili veri
tipi zerinde nemli deiiklikler veya sorgulamalar yapabiliyoruz.
Hatrlarsanz bir veri tipinin hangi metotlara sahip olduunu grmek iin dir()
fonksiyonundan yararlanyorduk. Listelerde de durum farkl deil. Dolaysyla u komut bize
listelerin metotlarn sralayacaktr:
>>> dir(list)

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',


'__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__',
'__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',
'__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__',
'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop',
'remove', 'reverse', 'sort']

Grdnz gibi, tpk karakter dizilerinde olduu gibi, listelerin metotlarn grmek iin de
dir() fonksiyonuna parametre olarak veri tipinin teknik adn veriyoruz. Pythonda listelerin
teknik ad list olduu iin bu komutu dir(list) eklinde kullanyoruz. Elbette, eer istersek,
listelerin metotlarn almak iin herhangi bir listeyi de kullanabiliriz. Mesela bo bir liste
kullanalm:
>>> dir([])

Bu komut da dir(list) ile ayn kty verecektir. Bu listede bizi ilgilendiren metotlar ise
unlardr:
>>> [i for i in dir(list) if not "_" in i]

['append', 'clear', 'copy', 'count', 'extend', 'index',


'insert', 'pop', 'remove', 'reverse', 'sort']

Metotlar, bir programcnn hayatn nemli lde kolaylatran aralardr. Bu yzden,


Listeler konusunun ilk blmnde rendiimiz listeye e ekleme, e karma, e

372
Python 3 iin Trke Klavuz, Srm 3

deitirme, e silme gibi ilemleri orada anlattmz yntemlerle deil, biraz sonra
greceimiz metotlar araclyla yapmay tercih edeceiz. Ama tabii ki, metotlar tercih
edecek olmamz, birinci blmde anlattmz yntemleri bir kenara atmanz gerektirmez.
Unutmayn, bir dildeki herhangi bir zellii siz kullanmasanz bile, etrafta bu zellii kullanan
baka programclar var. Dolaysyla en azndan bakalarnn yazd kodlar anlayabilmek iin
dahi olsa, kendinizin kullanmayacanz yntem ve yollar renmeniz gerekir.
append() metoduyla balayalm...

22.1.1 append()

append kelimesi ngilizcede eklemek, ilave etmek, ilitirmek gibi anlamlara gelir. append()
metodunun grevi de kelime anlamyla uyumludur. Bu metodu, bir listeye e eklemek iin
kullanyoruz. Mesela:
>>> liste = ["elma", "armut", "ilek"]
>>> liste.append("erik")

Bu metot, yeni eyi listenin en sonuna ekler. Mesela yukardaki rnekte erik adl karakter
dizisi listede ilek adl karakter dizisinin sana eklendi.
Hatrlarsanz bir nceki blmde listeye e ekleme iini + ileci ile de yapabileceimizi
sylemitik. Dolaysyla, aslnda yukardaki kodu yle de yazabiliriz:
>>> liste = ["elma", "armut", "ilek"]
>>> liste = liste + ["erik"]
>>> print(liste)

['elma', 'armut', 'ilek', 'erik']

Bu iki yntem birbiriyle ayn sonucu verse de hem pratiklik hem de ileyi bakmndan bu iki
yntemin birbirinden farkl olduunu gryoruz.
Pratiklik asndan bakarsak, append() metodununu kullanmann + ilecini kullanmaya
kyasla daha kolay olduunu herhalde kimse reddetmeyecektir. Bu iki yntem ileyi
bakmndan da birbirinden ayrlyor. Zira + ilecini kullandmzda listeye yeni bir e
eklerken aslnda liste adl baka bir liste daha oluturmu oluyoruz. Hatrlarsanz nceki
blmlerde listelerin deitirilebilir (mutable ) veri tipleri olduunu sylemitik. te append()
metodu sayesinde listelerin bu zelliinden sonuna kadar yararlanabiliyoruz. + ilecini
kullandmzda ise, orijinal listeyi deitirmek yerine yeni bir liste oluturduumuz iin, sanki
listelere karakter dizisi muamelesi yapm gibi oluyoruz. Grdnz gibi, listeye append()
metodunu uyguladktan sonra bunu bir deikene atamamza gerek kalmyor. append()
metodu orijinal liste zerinde dorudan deiiklik yapmamza izin verdii iin daha az kod
yazmamz ve programmzn daha performansl almasn salyor.
+ ileci ile append() metodu ilev olarak birbirine benzese de bu iki yntem arasnda nemli
farkllklar da vardr. Mesela u rnee bir gz atalm:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
hepsi = iletim_sistemleri + platformlar
print(hepsi)

['Windows', 'GNU/Linux', 'Mac OS X', 'IPhone', 'Android', 'S60']

22.1. Listelerin Metotlar 373


Python 3 iin Trke Klavuz, Srm 3

Burada iki farkl listeyi, + ileci kullanarak birletirdik. Ayn ii append() metoduyla u ekilde
yapabiliriz:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
for i in platformlar:
iletim_sistemleri.append(i)

print(iletim_sistemleri)

Burada platformlar adl liste zerinde bir for dngs kurmamzn nedeni, append()
metodunun yalnzca tek bir parametre alabilmesidir. Yani bu metodu kullanarak bir listeye
birden fazla e ekleyemezsiniz:
>>> liste = [1, 2, 3]
>>> liste.append(4, 5, 6)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: append() takes exactly one argument (3 given)

Bu sebeple, ekleyeceiniz listenin eleri zerinde bir for dngs kurmanz gerekir:
>>> liste = [1, 2, 3]
>>> for i in [4, 5, 6]:
... liste.append(i)
...
>>> print(liste)

[1, 2, 3, 4, 5, 6]

Bir listeye birden fazla e eklemek iin aklnza yle bir yntem de gelmi olabilir:
>>> liste = [1, 2, 3]
>>> liste.append([4, 5, 6])

Ancak bu komutun kts pek beklediiniz gibi olmayabilir:


>>> print(liste)

[1, 2, 3, [4, 5, 6]]

Grdnz gibi, [4, 5, 6] esi listeye tek para olarak eklendi. Eer istediiniz ey buysa
ne l! Ama deilse, for dngs ya da + ileci ile istediiniz kty elde edebilirsiniz.
yle bir rnek daha dnn: Diyelim ki kullancnn girdii btn saylar birbiriyle arpan
bir uygulama yazmak istiyoruz. Bunun iin yle bir kod yazabiliriz:
sonu = 1

while True:
say = input("say (hesaplamak iin q): ")
if say == "q":
break

sonu *= int(say)

print(sonu)

374 Blm 22. Listelerin ve Demetlerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

Burada kullanc her dngde bir say girecek ve programmz girilen bu sayy sonu
deikeninin o anki deeriyle arparak yine sonu deikenine gnderecek. Bylece kullanc
tarafndan girilen btn saylarn arpmn elde etmi olacaz. Kullancnn q harne
basmasyla birlikte de sonu deikeninin deeri ekranda grnecek. Yalnz burada birka
sorun var. Diyelim ki kullanc hibir say girmeden q harne basarsa, sonu deikeninin
1 olan deeri ekranda grnecek ve bu ekilde kullanc yanl bir sonu elde etmi olacak.
Ayrca arpma ilemi iin en az 2 adet say gerekiyor. Dolaysyla kullanc 2 den az say girerse
de programmz yanl sonu verecektir. Kullancnn yeterli miktarda say girip girmediini
tespit edebilmek iin yine listelerden ve listelerin append() metodundan yararlanabiliriz:
kontrol = []
sonu = 1

while True:
say = input("say (hesaplamak iin q): ")
if say == "q":
break
kontrol.append(say)
sonu *= int(say)

if len(kontrol) < 2:
print("Yeterli say girilmedi!")
else:
print(sonu)

Burada nceki koda ilave olarak, kontrol adl bo bir liste tanmladk. Bu liste kullancnn
girdii saylar depolayacak. Bir nceki rnekte kullancnn girdii saylar hibir yerde
depolamadk. Orada yaptmz ey her dngde kullanc tarafndan girilen sayy sonu
deikeninin deeriyle arpp yine sonu deikenine gndermekti. Dolaysyla kullanc
tarafndan girilen saylar bir yerde tutulmad iin kaybolup gidiyordu. Burada ise kontrol
adl liste, kullanc tarafndan girilen saylar tuttuu iin, bu saylar daha sonra istediimiz
gibi kullanabilme imkanna kavuuyoruz.
Ayrca bu ikinci kodlarda kontrol deikeninin boyutuna bakarak kullancnn 2 den az say
girip girmediini denetliyoruz. Eer kontrol listesinin uzunluu 2 den azsa kullanc arpma
ilemi iin yeterli say girmemi demektir. Byle bir durumda arpma ilemini yapmak yerine,
kullancya Yeterli say girilmedi! eklinde bir uyar mesaj gsteriyoruz.
append() metodu listelerin en nemli metotlarndan biridir. Hem kendi yazdnz, hem
de bakalarnn yazd programlarda append() metodunu ska greceksiniz. Dolaysyla
listelerin hibir metodunu bilmeseniz bile append() metodunu renmelisiniz.

22.1.2 extend()

extend kelimesi ngilizcede geniletmek, yaymak gibi anlamlara gelir. te extend() adl
metot da kelime anlamna uygun olarak listeleri geniletir.
yle bir dndnzde extend() metodunun append() metoduyla ayn ii yaptn
zannedebilirsiniz. Ama aslnda bu iki metot ileyi olarak birbirinden ok farkldr.
append() metodunu kullanarak yazdmz u koda dikkatlice bakn:
li1 = [1, 3, 4]
li2 = [10, 11, 12]
li1. append(li2)

22.1. Listelerin Metotlar 375


Python 3 iin Trke Klavuz, Srm 3

print(li1)

append() metodunu anlatrken sylediimiz gibi, bu metot bir listeye her defasnda sadece
tek bir e eklenmesine izin verir. Yukarda olduu gibi, eer bu metodu kullanarak bir
listeye yine bir liste eklemeye alrsanz, eklediiniz liste tek bir e olarak eklenecektir.
Yani yukardaki kodlar size yle bir kt verecektir:
[1, 3, 4, [10, 11, 12]]

Grdnz gibi, [10, 11, 12] listesi teki listeye tek bir liste halinde eklendi. te extend()
metodu bu tr durumlarda iinize yarayabilir. Mesela yukardaki rnei bir de extend()
metodunu kullanarak yazalm:
li1 = [1, 3, 4]
li2 = [10, 11, 12]
li1. extend(li2)

print(li1)

Bu defa yle bir kt alyoruz:


[1, 3, 4, 10, 11, 12]

Grdnz gibi, extend() metodu tam da kelime anlamna uygun olarak listeyi yeni elerle
geniletti.
Hatrlarsanz append() metodunu anlatrken yle bir rnek vermitik:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
hepsi = iletim_sistemleri + platformlar
print(hepsi)

Burada + ilecini kullanarak iletim_sistemleri ve platformlar adl listeleri birletirerek hepsi


adl tek bir liste elde ettik. Ayn etkiyi append() metodunu kullanarak u ekilde elde
edebileceimizi de sylemitik orada:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
for i in platformlar:
iletim_sistemleri.append(i)

print(iletim_sistemleri)

Esasnda, append() metodunu kullanmaya kyasla, burada + ilecini kullanmak sanki daha
pratikmi gibi grnyor. Bir de una bakn:
iletim_sistemleri = ["Windows", "GNU/Linux", "Mac OS X"]
platformlar = ["IPhone", "Android", "S60"]
iletim_sistemleri.extend(platformlar)
print(iletim_sistemleri)

Grdnz gibi, bu rnekte extend() metodunu kullanmak append() metodunu kullanmaya


gre daha pratik ve makul. nk bir listeye tek tek e eklemek asndan append()
metodu daha uygundur, ama eer yukarda olduu gibi bir listeye baka bir liste ekleyeceksek
extend() metodunu kullanmay tercih edebiliriz.

376 Blm 22. Listelerin ve Demetlerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

22.1.3 insert()

Bildiiniz gibi, + ileci, append() ve extend() metotlar eleri listenin sonuna ekliyor. Peki
biz bir eyi listenin sonuna deil de, liste iinde baka bir konuma eklemek istersek ne
yapacaz? te bunun iin insert() adl baka bir metottan yararlanacaz.
insert kelimesi yerletirmek, sokmak gibi anlamlara gelir. insert() metodu da bu anlama
uygun olarak, eleri listenin istediimiz bir konumuna yerletirir. Dikkatlice inceleyin:
>>> liste = ["elma", "armut", "ilek"]
>>> liste.insert(0, "erik")
>>> print(liste)

['erik', 'elma', 'armut', 'ilek']

Grdnz gibi insert() metodu iki parametre alyor. lk parametre, enin hangi
konuma yerletirileceini, ikinci parametre ise yerletirilecek enin ne olduunu gsteriyor.
Yukardaki rnekte erik esini listenin 0. konumuna, yani listenin en bana yerletiriyoruz.
nsert() metodu zellikle dosya ilemlerinde iinize yarar. Diyelim ki elimizde ierii yle
olan deneme.txt adl bir dosya var:

Ahmet zkoparan
Mehmet Veli
Serdar Gzel
Zeynep Gz

Bizim amacmz, Ahmet zkoparan satrndan sonra Ferhat Yaz diye bir satr daha eklemek.
Yani dosyamz u hale getirmek istiyoruz:

Ahmet zkoparan
Ferhat Yaz
Mehmet Veli
Serdar Gzel
Zeynep Gz

Biz henz Pythonda dosya ilemlerinin nasl yaplacan renmedik. Ama hatrlarsanz
bundan nceki blmlerde birka yerde open() adl bir fonksiyondan bahsetmi ve bu
fonksiyonun dosya ilemlerinde kullanldn sylemitik. Mesela yukarda bahsettiimiz
deneme.txt adl dosyay amak iin open() fonksiyonunu u ekilde kullanabiliriz:
f = open("deneme.txt", "r")

Burada deneme.txt adl dosyay okuma modunda am olduk. imdi dosya ieriini
okuyalm:
ierik = f.readlines()

Bu satr sayesinde dosya ieriini bir liste halinde alabildik. Eer yukardaki kodlara u
eklemeyi yaparsanz, dosya ieriini grebilirsiniz:
print(ierik)

['Ahmet zkoparan\n', 'Mehmet Veli\n', 'Serdar Gzel\n', 'Zeynep Gz\n', '\n']

Grdnz gibi, dosya ierii basit bir listeden ibaret. Dolaysyla listelerle yapabildiimiz
her eyi ierik adl deikenle de yapabiliriz. Yani bu listeye e ekleyebilir, listeden e

22.1. Listelerin Metotlar 377


Python 3 iin Trke Klavuz, Srm 3

karabilir ya da bu listeyi baka bir liste ile birletirebiliriz.


Dosya ieriini bir liste olarak aldmza gre imdi bu listeye Ahmet zkoparan esinden
sonra Ferhat Yaz esini ekleyelim. Dikkatlice bakn:
ierik.insert(1, "Ferhat Yaz\n")

Dediimiz gibi, f.readlines() satr bize dosya ieriini bir liste olarak verdi. Amacmz
Ahmet zkoparan esinden sonra Ferhat Yaz esini eklemek. Bunun iin, liste
metotlarndan biri olan insert() metodunu kullanarak listenin 1. srasna Ferhat Yaz
esini ekledik. Burada Ferhat Yaz esine n adl satr ba karakterini de ilave ettiimize
dikkat edin. Bu eklemeyi neden yaptmz anlamak iin satr ba karakterini karmay
deneyebilirsiniz.
ierik adl deikenin deerini istediimiz biime getirdiimize gre bu listeyi tekrar
deneme.txt adl dosyaya yazabiliriz. Ama bunun iin ncelikle deneme.txt adl dosyay yazma
modunda amamz gerekiyor. Pythonda dosyalar ya okuma ya da yazma modunda alabilir.
Okuma modunda alan bir dosyaya yazlamaz. O yzden dosyamz bir de yazma modunda
amamz gerekiyor:
g = open("deneme.txt", "w")

open() fonksiyonunun ilk parametresi dosya adn gsterirken, ikinci parametresi dosyann
hangi modda alacan gsteriyor. Biz burada deneme.txt adl dosyay yazma modunda
atk. Buradaki w parametresi ngilizcede yazmak anlamna gelen write kelimesinin ilk
hardir. Biraz nce ise deneme.txt dosyasn r, yani okuma (read ) modunda amtk.
Dosyamz artk zerine yazmaya hazr. Dikkatlice bakn:
g.writelines(ierik)

Burada, biraz nce istediimiz biime getirdiimiz ierik adl listeyi doruda dosyaya yazdk.
Bu ilem iin writelines() adl zel bir metottan yararlandk. Bu metotlar birka blm
sonra ayrntl olarak inceleyeceiz. Biz imdilik sadece sonuca odaklanalm.
Yapmamz gereken son ilem, ak dosyalar kapatmak olmal:
f.close()
g.close()

imdi kodlara topluca bir bakalm:


f = open("deneme.txt", "r")
ierik = f.readlines()
ierik.insert(1, "Ferhat Yaz\n")

g = open("deneme.txt", "w")
g.writelines(ierik)

f.close()
g.close()

Grdnz gibi yaptmz ilem u basamaklardan oluuyor:


1. ncelikle dosyamz okuma modunda ayoruz (f = open("deneme.txt", "r"))
2. Ardndan dosya ieriini bir liste olarak alyoruz (ierik = f.readlines())

378 Blm 22. Listelerin ve Demetlerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

3. Aldmz bu listenin 2. srasna Ferhat Yaz esini ekliyoruz (ierik.insert(1,


"Ferhat Yaz\n"))
4. Listeyi istediimiz ekle getirdikten sonra bu defa dosyamz yazma modunda ayoruz
(g = open("deneme.txt", "w"))
5. Biraz nce dzenlediimiz listeyi dosyaya yazyoruz (g.writelines(ierik))
6. Son olarak da, hem yaptmz deiikliklerin etkin hale gelebilmesi hem de iletim
sisteminin programmza tahsis ettii kaynaklarn serbest kalmas iin dosyalarmz
kapatyoruz (f.close() ve g.close())
Burada insert() metodunun bize nasl kolaylk saladna dikkat edin. insert() metodu da
listelerin nemli metotlarndan biridir ve dediimiz gibi, zellikle dosyalar maniple ederken
epey iimize yarar.

22.1.4 remove()

Bu metot listeden e silmemizi salar. rnein:


>>> liste = ["elma", "armut", "ilek"]
>>> liste.remove("elma")
>>> liste

['armut', 'ilek']

22.1.5 reverse()

Daha nce verdiimiz rneklerde, liste elerini ters evirmek iin dilimleme yntemini
kullanabileceimizi renmitik:
>>> meyveler = ["elma", "armut", "ilek", "kiraz"]
>>> meyveler[::-1]

['kiraz', 'ilek', 'armut', 'elma']

Eer istersek, bu i iin, karakter dizilerini incelerken rendiimiz reversed() fonksiyonunu


da kullanabiliriz:
>>> reversed(meyveler)

Bu komut bize u kty verir:


<list_reverseiterator object at 0x00DC9810>

Demek ki reversed() fonksiyonunu bir liste zerine uyguladmzda list_reverseiterator ad


verilen bir nesne elde ediyoruz. Bu nesnenin ieriini grmek iin birka farkl yntemden
yararlanabiliriz. rnein:
>>> print(*reversed(meyveler))

kiraz ilek armut elma

... veya:

22.1. Listelerin Metotlar 379


Python 3 iin Trke Klavuz, Srm 3

>>> print(list(reversed(meyveler)))

['kiraz', 'ilek', 'armut', 'elma']

... ya da:
>>> for i in reversed(meyveler):
... print(i)
...
kiraz
ilek
armut
elma

Grdnz gibi, Pythonda bir listeyi ters evirmenin pek ok yntemi var. Dilerseniz imdi
bu yntemlere bir tane daha ekleyelim.
Pythonda listelerin elerini ters evirmek iin yukardaki yntemlere ek olarak listelerin
reverse() metodunu da kullanabilirsiniz:
>>> liste = ["elma", "armut", "ilek"]
>>> liste.reverse()
>>> liste

['ilek', 'armut', 'elma']

htiyacnz olan ktnn trne ve ekline gre yukardaki yntemlerden herhangi birini tercih
edebilirsiniz.

22.1.6 pop()

Tpk remove() metodu gibi, bu metot da bir listeden e silmemizi salar:


>>> liste = ["elma", "armut", "ilek"]
>>> liste.pop()

Ancak bu metot, remove() metodundan biraz farkl davranr. pop() metodunu kullanarak
bir liste esini sildiimizde, silinen e ekrana baslacaktr. Bu metot parametresiz olarak
kullanldnda listenin son esini listeden atar. Alternatif olarak, bu metodu bir parametre
ile birlikte de kullanabilirsiniz. rnein:
>>> liste.pop(0)

Bu komut listenin 0. esini listeden atar ve atlan eyi ekrana basar.

22.1.7 sort()

Yine listelerin nemli bir metodu ile kar karyayz. sort() adl bu nemli metot bir listenin
elerini belli bir lte gre sraya dizmemizi salar. Basit bir rnek verelim. Diyelim ki
elimizde yle bir liste var:
yeler = ['Ahmet', 'Mehmet', 'Ceylan', 'Seyhan', 'Mahmut', 'Zeynep',
'Abdullah', 'Kadir', 'Kemal', 'Kamil', 'Selin', 'Senem',
'Sinem', 'Tayfun', 'Tuna', 'Tolga']

380 Blm 22. Listelerin ve Demetlerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

Bu listedeki isimleri mesela alfabe srasna dizmek iin sort() metodunu kullanabiliriz:
>>> yeler.sort()
>>> print(yeler)

['Abdullah', 'Ahmet', 'Ceylan', 'Kadir', 'Kamil', 'Kemal', 'Mahmut',


'Mehmet', 'Selin', 'Senem', 'Seyhan', 'Sinem', 'Tayfun', 'Tolga',
'Tuna', 'Zeynep']

Bu metot elbette yalnzca hareri alfabe srasna dizmek iin deil saylar sralamak iin de
kullanlabilir:
>>> saylar = [1, 0, -1, 4, 10, 3, 6]
>>> saylar.sort()
>>> print(saylar)

[-1, 0, 1, 3, 4, 6, 10]

Grdnz gibi, sort() metodu eleri artan sralamaya tabi tutuyor. Yani eler a, b,
c veya 1, 2, 3 eklinde sralanyor. Bunun tersini yapmak da mmkndr. Yani istersek
Pythonn sralama ilemini c, b, a eklinde yapmasn da salayabiliriz. Bunun iin sort()
metodunun reverse parametresini kullanacaz:
>>> yeler = ['Ahmet', 'Mehmet', 'Ceylan', 'Seyhan', 'Mahmut', 'Zeynep',
'Abdullah', 'Kadir', 'Kemal', 'Kamil', 'Selin', 'Senem',
'Sinem', 'Tayfun', 'Tuna', 'Tolga']

>>> yeler.sort(reverse=True)

Grdnz gibi sort() metodunun reverse adl bir parametresine verdiimiz True deeri
sayesinde liste elerini ters sraladk. Bu parametrenin ntanml deeri False tur. Yani
sort() metodu ntanml olarak eleri artra artra sralar. eleri azalta azalta sralamak
iin reverse parametresinin False olan ntanml deerini True yapmamz yeterli olacaktr.
Gelin isterseniz sort() metodunu kullanarak bir rnek daha verelim. Elimizde yle bir liste
olsun:
>>> isimler = ["Ahmet", "Ik", "smail", "idem", "Can", "ule"]

Bu listedeki isimleri alfabe srasna dizelim:


>>> isimler.sort()
>>> isimler

['Ahmet', 'Can', 'Ik', 'idem', 'smail', 'ule']

Grdnz gibi, kt pek beklediimiz gibi deil. Tpk karakter dizilerini anlatrken
rendiimiz sorted() fonksiyonunda olduu gibi, listelerin sort() metodu da Trke
karakterleri dzgn sralayamaz. Eer Trke karakterleri sralamamz gereken bir program
yazyorsak bizim sort() metodunun ileyiine mdahale etmemiz gerekir. Temel olarak,
sorted() fonksiyonunu anlatrken sylediklerimiz burada da geerlidir. Orada bahsettiimiz
locale modl burada da ou durumda iimizi halletmemizi salar. Ama sorted()
fonksiyonunu anlatrken de sylediimiz gibi, locale modl burada da i ve harerini
dzgn sralayamaz. Trke harerin tamamn dzgn sralayabilmek iin yle bir kod
yazabiliriz:

22.1. Listelerin Metotlar 381


Python 3 iin Trke Klavuz, Srm 3

harfler = "abcdefghijklmnoprstuvyz"
evrim = {harf: harfler.index(harf) for harf in harfler}

isimler = ["ahmet", "k", "ismail", "idem", "can", "ule"]

isimler.sort(key=lambda x: evrim.get(x[0]))

print(isimler)

Bu kodlarn bir ksmn anlayabiliyor, bir ksmn ise anlayamyor olabilirsiniz. nk burada
henz ilemediimiz konular var. Zaman geldiinde bu kodlarn tamamn anlayabilecek
duruma geleceksiniz. Siz imdilik sadece bu kodlardan ne karabildiinize bakn yeter.
Zaten bizim buradaki amacmz, sort() metodunun Trke hareri de dzgn bir ekilde
sralayabileceini gstermekten ibarettir.
Bu arada ufak bir uyar yapmadan gemeyelim: Yukardaki kodlar da esasnda Trke
kelimeleri tam anlamyla dzgn bir ekilde sralamak iin yeterli deil. Gml Fonksiyonlar
konusunu incelerken, yeri geldiinde bu konuya tekrar deinip, Trke kelimelerin nasl
doru, tam ve eksiksiz bir biimde sralanacan da tm ayrntlaryla inceleyeceiz.

22.1.8 index()

Karakter dizileri konusunu anlatrken bu veri tipinin index() adl bir metodu olduundan sz
etmitik hatrlarsanz. te liste veri tipinin de index() adnda ve karakter dizilerinin index()
metoduyla ayn ii yapan bir metodu bulunur. Bu metot bir liste esinin liste iindeki
konumunu syler bize:
>>> liste = ["elma", "armut", "ilek"]
>>> liste.index("elma")

Karakter dizilerinin index() metoduyla ilgili sylediimiz her ey listelerin index() metodu
iin de geerlidir.

22.1.9 count()

Karakter dizileri ile listelerin ortak metotlarndan biri de count() metodudur. Tpk karakter
dizilerinde olduu gibi, listelerin count() metodu da bir enin o veri tipi iinde ka kez
getiini syler:
>>> liste = ["elma", "armut", "elma", "ilek"]
>>> liste.count("elma")

Karakter dizilerinin count() metoduyla ilgili sylediimiz her ey listelerin count() metodu
iin de geerlidir.

382 Blm 22. Listelerin ve Demetlerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

22.1.10 copy()

Hatrlarsanz, geen blmde, listeleri, birbirlerini etkilemeyecek ekilde kopyalamak iin u


iki yntemi kullanmtk:
>>> liste1 = ["ahmet", "mehmet", "zlem"]
>>> liste2 = liste1[:]

ve:
>>> liste2 = list(liste1)

te ayn i iin yukardakilere ek olarak copy() adl bir metottan da yararlanabiliriz. Dikkatlice
bakn:
>>> liste2 = liste1.copy()

Hangi yntemi seeceiniz size kalm...

22.1.11 clear()

Listelerle ilgili olarak ele alacamz son metodun ad clear(). Bu metodun grevi bir listenin
ieriini silmektir.
Diyelim ki elimizde yle bir liste var:
>>> liste = [1, 2, 3, 5, 10, 20, 30, 45]

Bu listenin iini boaltmak iin clear() metodunu kullanabiliriz:


>>> liste.clear()
>>> liste

[]

Bu metodun del szcnden farkl olduunu dikkat edin. clear() metodu listenin ieriini
boaltrken, del szc listeyi olduu gibi ortadan kaldrr.

22.2 Demetlerin Metotlar

Listelerin metotlarn incelediimize gre, artk demetlerin metotlarna bakabiliriz.


Geen blmde de sylediimiz gibi, listeler ve demetler birbirine benzer. Aralarndaki en
nemli fark, listelerin deitirilebilir bir veri tipi iken, demetlerin deitirilemez bir veri tipi
olmasdr. Elbette bu fark, iki veri tipinin metotlarnda da kendini gsterir. Demetler zerinde
deiiklik yapamadmz iin, bu veri tipi deiiklik yapmaya yarayan metotlara sahip deildir.
Demetlerin hangi metotlar olduunu u komutla grebilirsiniz:
>>> dir(tuple)

Grdnz gibi, bu veri tipinin bizi ilgilendiren iki metodu var:


1. index()
2. count()

22.2. Demetlerin Metotlar 383


Python 3 iin Trke Klavuz, Srm 3

22.2.1 index()

Listeler ve karakter dizileri konusunu anlatrken bu veri tiplerinin index() adl bir metodu
olduundan sz etmitik hatrlarsanz. te demet veri tipinin de index() adnda ve listelerle
karakter dizilerinin index() metoduyla ayn ii yapan bir metodu bulunur. Bu metot bir
demet esinin demet iindeki konumunu syler bize:
>>> demet = ("elma", "armut", "ilek")
>>> demet.index("elma")

Listelerin ve karakter dizilerinin index() metoduyla ilgili sylediimiz her ey demetlerin


index() metodu iin de geerlidir.

22.2.2 count()

Karakter dizileri, listeler ve demetlerin ortak metotlarndan biri de count() metodudur. Tpk
karakter dizileri ve listelerde olduu gibi, demetlerin count() metodu da bir enin o veri tipi
iinde ka kez getiini syler:
>>> demet = ("elma", "armut", "elma", "ilek")
>>> demet.count("elma")

Karakter dizilerinin ve listelerin count() metoduyla ilgili sylediimiz her eydemetlerin


count() metodu iin de geerlidir.

384 Blm 22. Listelerin ve Demetlerin Metotlar


BLM 23

Sayma Sistemleri

Saylar olmadan bilgisayar ve programlama dnlemez. O yzden, nceki derslerimizde


karakter dizilerini anlatrken yle bir deinip getiimiz saylar konusunu, sayma sistemleri
konusunu da ilave ederek, birer programc aday olan bizleri yakndan ilgilendirdii iin
mmkn olduunca ayrntl bir ekilde ele almaya alacaz.
Saylar ve Sayma Sistemleri konusunu iki farkl blmde inceleyeceiz.
Saylar konusunun temelini oluturduu iin, ncelikle sayma sistemlerinden sz edelim.
ncelikle sayma sistemi kavramn tanmlayarak ie balayalm. Nedir bu sayma sistemi
denen ey?
Sayma ileminin hangi ltlere gre yaplacan belirleyen kurallar btnne sayma sistemi
ad verilir.
Dnyada yaygn olarak kullanlan drt farkl sayma sistemi vardr. Bunlar, onlu, sekizli, on
altl ve ikili sayma sistemleridir. Bu drd arasnda en yaygn kullanlan sayma sistemi ise,
tabii ki, onlu sistemdir. nsanlarn elleri ve ayaklarnda on parmak olduunu dnrsek, bu
sistemin neden daha yaygn kullanldn anlamak aslnda hi de zor deil!
Onlu sistemin yaygnln dnerek, sayma sistemleri konusunu anlatmaya onlu sayma
sisteminden balayalm.

23.1 Onlu Sayma Sistemi

Biz insanlar genellikle hesap ilemleri iin onlu sayma sistemini kullanrz. Hepinizin bildii
gibi bu sistem; 0, 1, 2, 3, 4, 5, 6, 7, 8 ve 9 olmak zere toplam on rakamdan oluur. Yani
saylar gsteren, birbirinden farkl toplam on simge (rakam) vardr bu sistemde. Bu on
simgeyi kullanarak, olas btn saylar gsterebiliriz.
Bu arada terminoloji ile ilgili ufak bir aklama yapalm:
Rakamlar, saylar gstermeye yarayan simgelerdir. Onlu sayma sisteminde toplam on farkl
rakam vardr. Btn rakamlar birer saydr, ama btn saylar birer rakam deildir. rnein
8 hem bir rakam hem de bir saydr. Ancak mesela 32 bir say olup bu say, 3 ve 2 adl iki
farkl rakamn bir araya getirilmesi ile gsterilir. Yani 32 says tek bana bir rakam deildir.
Aklamamz da yaptmza gre yolumuza devam edebiliriz.
nsanlar yukarda bahsettiimiz bu onlu sisteme ve bu sistemi oluturan rakamlara/simgelere
o kadar almtr ki, ou zaman baka bir sistemin varlndan veya var olma olaslndan
haberdar bile deildir.

385
Python 3 iin Trke Klavuz, Srm 3

Ama elbette dnya zerindeki tek sayma sistemi onlu sistem olmad gibi, saylar gstermek
iin kullanlabilecek rakamlar da yukardakilerle snrl deildir.
Nihayetinde rakam dediimiz eyler insan icad birtakm simgelerden ibarettir. Elbette
doada 2 veya 7 diye bir ey bulunmaz. Bizim yaygn olarak yukardaki ekilde gsterdiimiz
rakamlar Arap rakamlardr. Mesela Romallar yukardakiler yerine I, II, III, IV, V, VI, VII, VIII,
IX ve X gibi farkl simgeler kullanyordu... Neticede 2 ve II ayn kavrama iaret ediyor. Sadece
kullanlan simgeler birbirinden farkl, o kadar.
Onlu sayma sisteminde bir sayy oluturan rakamlar 10 un kuvvetleri olarak hesaplanr.
rnein 1980 saysn ele alalm. Bu sayy 10 un kuvvetlerini kullanarak u ekilde
hesaplayabiliriz:
>>> (0 * (10 ** 0)) + (8 * (10 ** 1)) + (9 * (10 ** 2)) + (1 * (10 ** 3))

1980

Grdnz gibi, saynn en sandaki basamak 10 un 0. kuvveti olacak ekilde, sola doru
kuvveti artrarak ilerliyoruz.
Gelelim teki sayma sistemlerine...

23.2 Sekizli Sayma Sistemi

Onlu sayma sisteminin aksine sekizli sayma sisteminde toplam sekiz rakam bulunur. Bu
rakamlar unlardr:
0, 1, 2, 3, 4, 5, 6, 7
Grdnz gibi, onlu sistemde toplam on farkl simge varken, sekizli sistemde toplam sekiz
farkl simge var.
Bu blmn en banda da sylediimiz gibi, insanlar onlu sayma sistemine ve bu sistemi
oluturan simgelere o kadar almtr ki, ou zaman baka bir sistemin varlndan veya
var olma olaslndan haberdar bile deildir. Hatta baka sayma sistemlerinden bir vesileyle
haberdar olup, bu sistemleri renmeye alanlar onlu sayma sistemine olan alkanlklar
nedeniyle yeni sayma sistemlerini anlamakta dahi zorluk ekebilirler. Bunun birincil nedeni,
iyi tandklarn zannettikleri onlu sistemi de aslnda o kadar iyi tanmyor olmalardr.
O halde baka sayma sistemlerini daha iyi anlayabilmek iin ncelikle yaygn olarak
kullandmz sayma sisteminin nasl ilediini anlamaya alalm:
Onlu sistemde toplam on farkl simge bulunur:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9
9 dan byk bir sayy gstermek gerektiinde simge listesinin en bana dnlr ve basamak
says bir artrlarak, semboller birletirilir:
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ..., 99, 100, ..., 999, 1000
te bu kural teki sayma sistemleri iin de geerlidir. Mesela sekizli sayma sistemini ele
alalm.
Dediimiz gibi, sekizli sistemde toplam sekiz farkl simge bulunur:
0, 1, 2, 3, 4, 5, 6, 7

386 Blm 23. Sayma Sistemleri


Python 3 iin Trke Klavuz, Srm 3

Bu sistemde 7 den byk bir sayy gstermek gerektiinde, tpk onlu sistemde olduu
gibi, simge listesinin en bana dnyoruz ve basamak saysn bir artrarak sembolleri
birletiriyoruz:
10, 11, 12, 13, 14, 15, 16, 17, 20, ..., 77, 100
Onlu sayma sistemi ile sekizli sayma sistemi arasndaki fark daha belirgin bir ekilde
grebilmek iin u kodlar yazalm:
say_sistemleri = ["onlu", "sekizli"]

print(("{:^5} "*len(say_sistemleri)).format(*say_sistemleri))

for i in range(17):
print("{0:^5} {0:^5o}".format(i))

Bu kodlarda renmediimiz ve anlayamayacamz hibir ey yok. Bu kodlar oluturan


btn paralar nceki derslerimizde ayrntl olarak incelemitik.
Bu kodlardan yle bir kt alacaz:
onlu sekizli
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 10
9 11
10 12
11 13
12 14
13 15
14 16
15 17
16 20

Grdnz gibi, onlu sistemde elimizde toplam on farkl simge olduu iin, elimizdeki
simgeleri kullanarak 10. sayya kadar ilerleyebiliyoruz. Bu noktadan sonra simge stoumuz
tkendii iin en baa dnp bir basamak artryoruz ve simgeleri birbiriyle birletirerek yeni
saylar elde ediyoruz.
Sekizli sistemde ise elimizde yalnzca sekiz farkl simge olduu iin, elimizdeki simgeleri
kullanarak ancak 8. sayya kadar gelebiliyoruz. teki saylar gsterebilmek iin bu noktadan
sonra baa dnp bir artrmamz ve simgeleri birbiriyle birletirerek yeni saylar elde etmemiz
gerekiyor.
Sekizli sayma sisteminde bir sayy oluturan rakamlar 8 in kuvvetleri olarak hesaplanr.
rnein sekizli sayma sistemindeki 3674 saysn ele alalm. Bu sayy 8 in kuvvetlerini
kullanarak u ekilde hesaplayabiliriz:
>>> (4 * (8 ** 0)) + (7 * (8 ** 1)) + (6 * (8 ** 2)) + (3 * (8 ** 3))

1980

23.2. Sekizli Sayma Sistemi 387


Python 3 iin Trke Klavuz, Srm 3

Bu hesaplama eklini onlu sayma sisteminden hatrlyor olmalsnz. Grdnz gibi, sekizli
sistemdeki bir saynn her bir basaman 8 in kuvvetleri olarak hesapladmzda, bu saynn
onlu sistemdeki karln elde ediyoruz.

23.3 On Altl Sayma Sistemi

u ana kadar onlu ve sekizli sayma sistemlerinden bahsettik. nemli bir baka sayma sistemi
de on altl sayma sistemidir.
Onlu sayma sisteminde on farkl rakam, sekizli sayma sisteminde sekiz farkl rakam olduunu
renmitik. On altl sayma sisteminde ise, tahmin edebileceiniz gibi, on alt farkl rakam
bulunur:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f
imdiye kadar renmi olduumuz sayma sistemleri arasndaki fark daha net grmek iin
biraz nce yazdmz kodlara on altl sayma sistemini de ekleyelim:
say_sistemleri = ["onlu", "sekizli", "on altl"]

print(("{:^8} "*len(say_sistemleri)).format(*say_sistemleri))

for i in range(17):
print("{0:^8} {0:^8o} {0:^8x}".format(i))

Buradan yle bir kt alacaz:


onlu sekizli on altl
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 10 8
9 11 9
10 12 a
11 13 b
12 14 c
13 15 d
14 16 e
15 17 f
16 20 10

Grdnz gibi, onlu sistemde birbirinden farkl toplam 10 adet rakam/simge varken, sekizli
sistemde toplam 8 farkl simge, on altl sistemde ise toplam 16 farkl simge var. Yani onlu
sistemde olas btn saylar eldeki 10 farkl simge ve bunlarn kombinasyonunun kullanlmas
yoluyla; sekizli sistemde 8 farkl simge ve bunlarn kombinasyonunun kullanlmas yoluyla;
on altl sistemde ise 16 farkl simge ve bunlarn kombinasyonunun kullanlmas yoluyla
gsteriliyor. Bu sebeple onlu sistemde 9 saysndan itibaren bir basamak artrlp simge
listesinin bana dnlrken, sekizli sistemde 7 saysndan itibaren; on altl sistemde ise f
saysndan itibaren baa dnlyor.

388 Blm 23. Sayma Sistemleri


Python 3 iin Trke Klavuz, Srm 3

On altl sistemde 9 saysndan sonra gelen hareri yadrgam olabilirsiniz. Bu durumu yle
dnn: Say dediimiz eyler insan icad birtakm simgelerden ibarettir. Daha nce de
sylediimiz gibi, doada 2 veya 7 diye bir ey gremezsiniz...
te on altlk sistemdeki saylar gsterebilmek iin de birtakm simgelere ihtiya var. lk
on simge, onluk sayma sistemindekilerle ayn. Ancak 10 dan sonraki saylar gsterebilmek
iin elimizde baka simge yok. On altlk sistemi tasarlayanlar, bir tercih sonucu olarak, eksik
sembolleri alfabe hareriyle tamamlamay tercih etmiler. Alfabe hareri yerine pekala Roma
rakamlarn da tercih edebilirlerdi. Eer bu sistemi tasarlayanlar byle tercih etmi olsayd
bugn on altlk sistemi yle gsteriyor olabilirdik:
0
1
2
3
4
5
6
7
8
9
I
II
III
IV
V
VI

Bugn bu saylar bu ekilde kullanmyor olmamzn tek sebebi, sistemi tasarlayanlarn bunu
byle tercih etmemi olmasdr...
On altl sayma sisteminde bir sayy oluturan rakamlar 16 nn kuvvetleri olarak hesaplanr.
Peki ama bu sayma sistemindeki a, b, c, d, e ve f hareriyle nasl aritmetik ilem yapacaz?
rnein on altl sayma sistemindeki 7bc saysn ele alalm. Bu saynn onlu sistemdeki
karln 16 nn kuvvetlerini kullanarak hesaplayabiliriz hesaplamasna, ama peki yukarda
bahsettiimiz harer ne olacak? Yani yle bir ilem tabii ki mmkn deil:
>>> ((c * 16 ** 0)) + ((b * 16 ** 1)) + ((7 * 16 ** 2))

Elbette c ve b saylarn herhangi bir aritmetik ilemde kullanamayz. Bunun yerine, bu


harerin onlu sistemdeki karlklarn kullanacaz:
a > 10
b > 11
c > 12
d > 13
e > 14
f > 15
Buna gre:
>>> ((12 * (16 ** 0)) + ((11 * (16 ** 1)) + ((7 * (16 ** 2))

1980

23.3. On Altl Sayma Sistemi 389


Python 3 iin Trke Klavuz, Srm 3

Demek ki on altl sistemdeki 7bc saysnn onlu sistemdeki karl 1980 mi.

23.4 kili Sayma Sistemi

Bildiiniz, veya orada burada duymu olabileceiniz gibi, bilgisayarlarn temelinde iki tane
say vardr: 0 ve 1. Bilgisayarlar btn ilemleri sadece bu iki say ile yerine getirir.
Onlu, sekizli ve on altl say sistemleri dnda, zellikle bilgisayarlarn altyapsnda tercih
edilen bir baka say sistemi daha bulunur. te bu sistemin ad ikili (binary ) say sistemidir.
Nasl onlu sistemde 10, sekizli sistemde 8, on altl sistemde ise saylar gsteren 16 farkl
simge varsa, bu say sisteminde de saylar gsteren toplam iki farkl sembol vardr: 0 ve 1.
kili say sisteminde olas btn saylar ite bu iki simge ile gsterilir.
Gelin isterseniz durumu daha net bir ekilde grebilmek iin yukarda verdiimiz say sistemi
tablosuna ikili saylar da ekleyelim:
say_sistemleri = ["onlu", "sekizli", "on altl", "ikili"]

print(("{:^9} "*len(say_sistemleri)).format(*say_sistemleri))

for i in range(17):
print("{0:^9} {0:^9o} {0:^9x} {0:^9b}".format(i))

Bu kodlar u kty verecektir:


onlu sekizli on altl ikili
0 0 0 0
1 1 1 1
2 2 2 10
3 3 3 11
4 4 4 100
5 5 5 101
6 6 6 110
7 7 7 111
8 10 8 1000
9 11 9 1001
10 12 a 1010
11 13 b 1011
12 14 c 1100
13 15 d 1101
14 16 e 1110
15 17 f 1111
16 20 10 10000

Burada, onlu, sekizli ve on altl say sistemleri iin geerli olan durumun aynen ikili say
sistemi iin de geerli olduunu rahatlkla grebiliyoruz. kili say sistemindeki mevcut saylar
gsterebilmemiz iin toplam iki farkl simge var. Bunlar: 0 ve 1. kili say sisteminde 0
ve 1 diye saymaya balayp nc sayy sylememiz gerektiinde, elimizde 0 ve 1 den
baka simge olmad iin bir basamak artrp simge listesinin bana dnyoruz ve bylece
onluk dzendeki 2 saysn ikili dzende gsterebilmek iin 0 ve 1 den sonra 10 simgesini
kullanyoruz.
Bu sylediklerimizden sonra nternet zerinde ska karlatnz u szn anlamn
herhalde artk daha iyi anlyor olmalsnz:

390 Blm 23. Sayma Sistemleri


Python 3 iin Trke Klavuz, Srm 3

nsanlar 10a ayrlr: kili sistemi bilenler ve bilmeyenler!


Bu arada, elbette ikili dzendeki 10 says on eklinde telaffuz edilmiyor. Bu sayy bir-sfr
diye seslendiriyoruz...
kili sayma sisteminde bir sayy oluturan rakamlar 2 nin kuvvetleri olarak hesaplanr.
rnein ikili sayma sistemindeki 1100 saysn ele alalm. Bu sayy 2 nin kuvvetlerini
kullanarak u ekilde hesaplayabiliriz:
>>> (0 * (2 ** 0)) + (0 * (2 ** 1)) + (1 * (2 ** 2)) + (1 * (2 ** 3))

12

Demek ki 1100 says onlu sistemde 12 saysna karlk geliyormu.

23.5 Sayma Sistemlerini Birbirine Dntrme

Sklkla kullanlan drt farkl sayma sistemini rendik. Peki biz bir sayma sisteminden
brne dntrme ilemi yapmak istersek ne olacak? rnein onlu sistemdeki bir sayy
ikili sisteme nasl evireceiz?
Python programlama dilinde bu tr ilemleri kolaylkla yapmamz salayan birtakm
fonksiyonlar bulunur. Ayrca zel fonksiyonlar kullanmann yansra karakter dizisi
biimlendirme (string formatting ) yntemlerini kullanarak da sayma sistemlerini birbirine
dntrebiliriz. Biz burada her iki yntemi de tek tek inceleyeceiz.
Gelin isterseniz bu dntrme ilemleri iin hangi zel fonksiyonlarn olduuna bakalm
nce.

23.5.1 Fonksiyon Kullanarak

bin()

Bu fonksiyon bir saynn ikili (binary ) say sistemindeki karln verir:


>>> bin(2)

'0b10'

Bu fonksiyonun kt olarak bir karakter dizisi verdiine dikkat edin. Bu karakter dizisinin
ilk iki karakteri (0b ), o saynn ikili sisteme ait bir say olduunu gsteren bir iarettir. Bu
bilgilerden yola karak, yukardaki karakter dizisinin gerek ikili ksmn almak iin u yntemi
kullanabilirsiniz:
>>> bin(2)[2:]

'10'

hex()

Bu fonksiyon, herhangi bir sayy alp, o saynn on altl sistemdeki karln verir:

23.5. Sayma Sistemlerini Birbirine Dntrme 391


Python 3 iin Trke Klavuz, Srm 3

>>> hex(10)

'Oxa'

Tpk bin() fonksiyonunda olduu gibi, hex() fonksiyonunun da kt olarak bir karakter dizisi
verdiine dikkat edin. Hatrlarsanz bin() fonksiyonunun ktsndaki ilk iki karakter (0b ),
o saynn ikili sisteme ait bir say olduunu gsteren bir iaret olarak kullanlyordu. hex()
fonksiyonunun ktsndaki ilk iki karakter de (0x ), o saynn on altl sisteme ait bir say
olduunu gsteriyor.

oct()

Bu fonksiyon, herhangi bir sayy alp, o saynn sekizli sistemdeki karln verir:
>>> oct(10)

'0o12'

Tpk bin() ve hex() fonksiyonlarnda olduu gibi, oct() fonksiyonunun da kt olarak bir
karakter dizisi verdiine dikkat edin. Hatrlarsanz bin() ve hex() fonksiyonlarnn ktsndaki
ilk iki karakter (0b ve 0x ), o saylarn hangi sisteme ait saylar olduunu gsteriyordu. Ayn
ekilde oct() fonksiyonunun ktsndaki ilk iki karakter de (0o ), o saynn sekizli sisteme ait
bir say olduunu gsteriyor.

int()

Aslnda biz bu fonksiyonu yakndan tanyoruz. Bildiiniz gibi bu fonksiyon herhangi bir say
veya say deerli karakter dizisini tam sayya (integer ) dntrmek iin kullanlyor. int()
fonksiyonunun imdiye kadar grdmz ilevi dnda bir ilevi daha bulunur: Biz bu
fonksiyonu kullanarak herhangi bir sayy onlu sistemdeki karlna dntrebiliriz:
>>> int('7bc', 16)

1980

Grdnz gibi, bu fonksiyonu kullanrken dikkat etmemiz gereken baz noktalar var.
lkin, eer int() fonksiyonunu yukardaki gibi bir dntrme ilemi iin kullanacaksak,
bu fonksiyona verdiimiz ilk parametrenin bir karakter dizisi olmas gerekiyor. Dikkat
etmemiz gereken ikinci nokta, int() fonksiyonuna verdiimiz ikinci parametrenin nitelii. Bu
parametre, dntrmek istediimiz saynn hangi tabanda olduunu gsteriyor. Yukardaki
rnee gre biz, on alt tabanndaki 7bc saysn on tabanna dntrmek istiyoruz.
Bir de u rneklere bakalm:
>>> int('1100', 2)

12

>>> int('1100', 16)

4352

lk rnekte, ikili sistemdeki 1100 saysn onlu sisteme eviriyoruz ve 12 saysn elde ediyoruz.
kinci rnekte ise on altl sistemdeki 1100 saysn onlu sisteme eviriyoruz ve 4352 saysn

392 Blm 23. Sayma Sistemleri


Python 3 iin Trke Klavuz, Srm 3

elde ediyoruz.

23.5.2 Biimlendirme Yoluyla

Esasnda biz karakter dizisi biimlendirme yntemlerini kullanarak dntrme ilemlerini


nasl gerekletireceimizi biliyoruz. Biz burada zaten rendiimiz bu bilgileri tekrar ederek
rendiklerimizi pekitirme amac gdeceiz.

Bu karakteri kullanarak bir sayy ikili dzendeki karlna dntrebiliriz:


>>> '{:b}'.format(12)

'1100'

Bu karakter, bin() fonksiyonuyla ayn ii yapar.

Bu karakteri kullanarak bir sayy on altl dzendeki karlna dntrebiliriz:


>>> '{:x}'.format(1980)

'7bc'

Bu karakter, hex() fonksiyonuyla ayn ii yapar.

Bu karakteri kullanarak bir sayy sekizli dzendeki karlna dntrebiliriz:


>>> '{:o}'.format(1980)

'3674'

Bu karakter, oct() fonksiyonuyla ayn ii yapar.


Btn bu anlattklarmzdan sonra (eer o zaman anlamakta zorluk ekmiseniz) aadaki
kodlar daha iyi anlam olmalsnz:
say_sistemleri = ["onlu", "sekizli", "on altl", "ikili"]

print(("{:^9} "*len(say_sistemleri)).format(*say_sistemleri))

for i in range(17):
print("{0:^9} {0:^9o} {0:^9x} {0:^9b}".format(i))

Bu arada, yukarda bir saynn, karakter dizisi biimlendirme yntemleri kullanlarak ikili,
sekizli ve on altl dzene nasl evrileceini grdk. Bir sayy onlu dzene evirmek
iin ise sadece int() fonksiyonunu kullanabiliyoruz. Byle bir evirme ilemini karakter
dizisi biimlendirme yntemlerini kullanarak yapamyoruz. Ama elbette, eer baka bir

23.5. Sayma Sistemlerini Birbirine Dntrme 393


Python 3 iin Trke Klavuz, Srm 3

sayma sisteminden onlu sisteme evirdiiniz bir sayy herhangi bir karakter dizisi iinde
biimlendirmek isterseniz yle bir kod kullanabilirsiniz:
>>> n = '7bc'
>>> "{} saysnn onlu karl {:d} saysdr.".format(n, int(n, 16))

...veya:
>>> n = '7bc'
>>> "{} saysnn onlu karl {} saysdr.".format(n, int(n, 16))

Zira bildiiniz gibi, Pythonda onlu saylar temsil eden harf d hardir. Eer {} yaps
iinde herhangi bir harf kullanmazsanz yukardaki durumda Python {:d} yazmsnz gibi
davranacaktr.

23.6 Sayma Sistemlerinin Birbirlerine Kar Avantajlar

Bylece drt farkl say sisteminin hangi mantk zerine ilediini anlam olduk. Ayrca say
sistemleri arasnda dntrme ilemlerini de rendik.
te bilgisayarlar bu say sistemleri arasnda sadece ikili say sistemini anlayabilir. Aslnda bu
da hi mantksz deil. Bilgisayar dediimiz ey, zerinden elektrik geen devrelerden ibaret
bir makinedir. Eer bir devrede elektrik yoksa o devrenin deeri ~0 volt iken, o devreden
elektrik getiinde devrenin deeri ~5 volttur. Grdnz gibi, ortada iki farkl deer var:
~0 volt ve ~5 volt. Yukarda anlattmz gibi, ikili (binary ) sayma sisteminde de iki deer
bulunur: 0 ve 1. Dolaysyla ikili sayma sistemi bilgisayarn i ileyiine en uygun sistemdir.
ikili sistemde ~0 voltu 0 ile, ~5 voltu ise 1 ile temsil edebiliyoruz. Yani devreden elektrik
getiinde o devrenin deeri 1, elektrik gemediinde ise 0 olmu oluyor. Tabii bilgisayar
asndan bakldnda devrede elektrik vardr veya yoktur. Biz insanlar bu ikili durumu daha
kolay bir ekilde temsil edebilmek iin her bir duruma 0 ve 1 gibi bir ad veriyoruz.
Bilgisayarn ilemcisi sadece bu iki farkl durumu kullanarak her trl hesaplama ilemini
gerekletirebilir. Bu sebeple ikili say sistemi bilgisayarn alma mant iin gayet yeterli
ve uygundur. kili say sistemi yerine mesela onlu say sistemini kullanmak herhalde simge
israfndan baka bir ey olmazd. Neticede, dediimiz gibi, bilgisayarn ileyebilmesi iin iki
farkl simge yeterlidir.
Dediimiz gibi, ikili sayma sistemi bilgisayarn yapsna gayet uygundur. Ama biz insanlar
asndan sadece iki simge yardmyla saymaya almak epey zor olacaktr. Ayrca say
bydke, ikili sistemde saynn kaplad alan hzla ve kolayca artacak, ylan bu saylar
idare etmek hi de kolay olmayacaktr. te bu noktada devreye on altl (hexadecimal ) saylar
girer. Bu sayma sisteminde toplam 16 farkl rakam/simge olduu iin, byk saylar ok daha
az yer kaplayacak ekilde gsterilebilir.
Bildiiniz gibi, ikili sayma sistemindeki herbir basamaa bit ad verilir. kili sayma sistemini
kullanarak, 0 dan 256 ya kadar sayabilmek iin toplam 8 bitlik (yani 8 hanelik) bir yer
kullanmanz gerekir. On altl sistemde ise bu ilemi sadece iki basamakla halledebilirsiniz.
Yani on altl sistemde 00 ile FF arasna toplam 255 tane say sdrlabilir. Dolaysyla on altl
sistemi kullanarak, ok byk saylar ok az yer kullanarak gsterebilirsiniz:
>>> for i in range(256):
... print(i, bin(i)[2:], hex(i)[2:])
...
0 0 0

394 Blm 23. Sayma Sistemleri


Python 3 iin Trke Klavuz, Srm 3

(...)
255 11111111 ff
>>>

Grdnz gibi, onlu sistemde 255 eklinde, ikili sistemde ise 11111111 eklinde gsterilen
say on altl sistemde yalnzca ff eklinde gsterilebiliyor. Dolaysyla, kullanm asndan,
biz insanlar iin on altlk sayma sisteminin ikili sisteme kyasla ok daha pratik bir yntem
olduunu syleyebiliriz.
Ayrca on altl sistem, az alana ok veri sdrabilme zellii nedeniyle HTML renk
kodlarnn gsterilmesinde de tercih edilir. rnein beyaz rengi temsil etmek iin on altl
sistemdeki #FFFFFF ifadesini kullanmak rgb(255,255,255) ifadesini kullanmaya kyasla ok
daha mantkldr. Hatta #FFFFFF ifadesini #FFF eklinde ksaltma imkan dahi vardr.

23.6. Sayma Sistemlerinin Birbirlerine Kar Avantajlar 395


BLM 24

Saylar

Geen blmde sayma sistemlerini ayrntl bir ekilde inceledik. Bu blmde ise yine
bununla balantl bir konu olan saylar konusunu ele alacaz. Esasnda biz saylarn ne
olduuna ve Pythonda bunlarn nasl kullanlacana dair tamamen bilgisiz deiliz. Buraya
gelene kadar, saylar konusunda epey ey syledik aslnda. Mesela biz Pythonda tr say
olduunu biliyoruz:
1. Tam Saylar (integers )
2. Kayan Noktal Saylar (oating point numbers veya ksaca oats )
3. Karmak Saylar (complex numbers )
Eer bir veri type(veri) sorgulamasna int cevab veriyorsa o veri bir tam saydr. Eer bir
veri type(veri) sorgulamasna oat cevab veriyorsa o veri bir kayan noktal saydr. Eer bir
veri type(veri) sorgulamasna complex cevabn veriyorsa o veri bir karmak saydr.
Mesela unlar birer tam saydr:
15, 4, 33
unlar birer kayan noktal saydr:
3.5, 6.6, 2.3
unlarsa birer karmak saydr:
3+3j, 5+2j, 19+10j
Ayrca imdiye kadar rendiklerimiz sayesinde bu saylarn eitli fonksiyonlar yardmyla
birbirlerine dntrlebileceini de biliyoruz:
Fonksiyon Grevi rnek
int() Bir veriyi tam sayya dntrr int(2)
float() Bir veriyi kayan noktal sayya dntrr float(2)
complex() Bir veriyi karmak sayya dntrr complex(2)
Dediimiz gibi, bunlar bizim zaten saylara dair bildiimiz eyler. Elbette bir de henz
renmediklerimiz var.
Gelin imdi bunlarn neler olduunu inceleyelim.

396
Python 3 iin Trke Klavuz, Srm 3

24.1 Saylarn Metotlar

Tpk teki veri tiplerinde olduu gibi, saylarn da baz metotlar bulunur. Bu metotlar
kullanarak saylar zerinde eitli ilemler gerekletirebiliriz.

24.1.1 Tam Saylarn Metotlar

Dediimiz gibi, Pythonda birka farkl say tipi bulunur. Biz ilk olarak tam say (integer ) denen
say tipinin metot ve niteliklerini inceleyeceiz.
ncelikle hangi metotlar ve niteliklerle kar karya olduumuza bakalm:
>>> [i for i in dir(int) if not i.startswith("_")]

['bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator',


'real', 'to_bytes']

Bu listede imdilik bizi ilgilendiren tek bir metot var. Bu metodun ad bit_length().

bit_length()

Bilgisayarlar hakknda bilmemiz gereken en nemli bilgilerden biri udur: Bilgisayarlar ancak
ve ancak saylarla ilem yapabilir. Bilgisayarlarn ilem yapabildii saylar da onlu sistemdeki
saylar deil, ikili sistemdeki saylardr. Yani 0lar ve 1ler.
Bilgisayar terminolojisinde bu 0lar ve 1lerden oluan herbir basamaa bit ad verilir. Yani
ikili sayma sisteminde 0 ve 1 saylarndan herbiri 1 bittir. Mesela onlu sistemde 2 saysnn
ikili sistemdeki karl olan 10 says iki bitlik bir saydr. Onlu sistemdeki 100 saysnn ikili
sistemdeki karl olan 1100100 says ise yedi bitlik bir saydr.
Bu durumu daha net bir ekilde grebilmek iin u kodlar yazalm:
>>> for i in range(11):
... print(i, bin(i)[2:], len(bin(i)[2:]), sep="\t")
...
0 0 1
1 1 1
2 10 2
3 11 2
4 100 3
5 101 3
6 110 3
7 111 3
8 1000 4
9 1001 4
10 1010 4

Burada ikinci stundaki saylar ilk stundaki saylarn ikili sistemdeki karlklardr. nc
stundaki saylar ise her bir saynn ka bit olduunu, yani bir bakma ikili sayma sisteminde
ka basamaa sahip olduunu gsteriyor.
te herhangi bir tam saynn ka bitlik bir yer kapladn renmek iin, tam saylarn
metotlarndan biri olan bit_length() metodundan yararlanacaz:

24.1. Saylarn Metotlar 397


Python 3 iin Trke Klavuz, Srm 3

>>> say = 10
>>> say.bit_length()

Demek ki 10 says bellekte drt bitlik bir yer kaplyormu. Yani bu saynn ikili sistemdeki
karl olan 1010 says drt basamaktan oluuyormu.
Yukardaki rneklerden de rahatlkla karabileceiniz gibi, bit_length() metodu, ikili sayma
sistemindeki bir say zerine len() fonksiyonunun uygulanmas ile edeerdir. Yani:
>>> len(bin(10)[2:]) == (10).bit_length()
True

Bu arada u son rnekte bir ey dikkatinizi ekmi olmal: bit_length() metodunu dorudan
saylar zerine uygulayamyoruz. Yani:
>>> 10.bit_length()
File "<stdin>", line 1
10.bit_length()
^
SyntaxError: invalid syntax

Bu metodu saylarla birlikte kullanabilmek iin iki seeneimiz var: bit_length() metodunu
uygulamak istediimiz sayy nce bir deikene atayabiliriz:
>>> a = 10
>>> a.bit_length()

...veya ilgili sayy parantez iine alabiliriz:


>>> (10).bit_length()

Bu durum, yani sayy parantez iinde gsterme zorunluluu, 10 saysnn sana bir nokta
iareti koyduumuzda, Pythonn bu sayy bir kayan noktal say olarak deerlendirmesinden
kaynaklanyor. Yani biz 10 yazp, bit_length() metodunu bu sayya balama amacyla
saynn sana bir nokta koyduumuz anda, Python bu saynn bir kayan noktal say olduunu
zannediyor. nk Python asndan, 10. says bir kayan noktal saydr. Bunu teyit edelim:
>>> type(10.)

<class 'float'>

Kayan noktal saylarn bit_length() adl bir metodu olmad iin de Pythonn bize bir hata
mesaj gstermekten baka yapabilecei bir ey kalmyor.

24.1.2 Kayan Noktal Saylarn Metotlar

Pythonda tam saylar dnda kayan noktal saylarn da olduunu biliyoruz. Bu say tipinin u
metotlar vardr:

398 Blm 24. Saylar


Python 3 iin Trke Klavuz, Srm 3

>>> [i for i in dir(float) if not i.startswith("_")]

['as_integer_ratio', 'conjugate', 'fromhex', 'hex', 'imag', 'is_integer', 'real']

Biz bu metotlar arasndan, as_integer_ratio() ve is_integer() adl metotlarla ilgileneceiz.

as_integer_ratio()

Bu metot, birbirine blndnde ilgili kayan noktal sayy veren iki adet tam say verir bize.
rnek zerinden aklayalm:
>>> say = 4.5
>>> say.as_integer_ratio()

(9, 2)

9 saysn 2 saysna bldmzde 4.5 saysn elde ederiz. te as_integer_ratio()


metodu, bu 9 ve 2 saylarn bize ayr ayr verir.

is_integer()

Bir kayan noktal saynn ondalk ksmnda 0 harici bir saynn olup olmadn kontrol etmek
iin bu metodu kullanyoruz. rnein:
>>> (12.0).is_integer()

True

>>> (12.5).is_integer()

False

24.1.3 Karmak Saylarn Metotlar

Gelelim karmak saylarn metot ve niteliklerine...


>>> [i for i in dir(complex) if not i.startswith("_")]

['conjugate', 'imag', 'real']

Grdnz gibi, karmak saylarn da birka tane metot ve nitelii var. Biz bunlar arasndan
imag ve real adl nitelikleri inceleyeceiz.

imag

Bir gerek bir de sanal ksmdan oluan saylara karmak saylar (complex ) ad verildiini
biliyorsunuz. rnein u bir karmak saydr:
12+4j
te imag adl nitelik, bize bir karmak saynn sanal ksmn verir:

24.1. Saylarn Metotlar 399


Python 3 iin Trke Klavuz, Srm 3

>>> c = 12+4j
>>> c.imag

4.0

real

real adl nitelik bize bir karmak saynn gerek ksmn verir:
>>> c = 12+4j
>>> c.real

12.0

24.2 Aritmetik Fonksiyonlar

Python programlama dili, bize saylarla rahat alabilmemiz iin baz fonksiyonlar sunar. Bu
fonksiyonlar kullanarak, karmak aritmetik ilemleri kolayca yapabiliriz.
Biz bu blmde Pythonn bize sunduu bu gml fonksiyonlar tek tek inceleyeceiz.
Gml fonksiyonlar, Python programlama dilinde, herhangi bir zel ilem yapmamza gerek
olmadan, kodlarmz iinde dorudan kullanabileceimiz fonksiyonlardr. Biz imdiye kadar
pek ok gml fonksiyonla zaten tanmtk. O yzden gml fonksiyonlar bizim yabancs
olduumuz bir konu deil. Mesela buraya gelene kadar grdmz, len(), range(), type(),
open(), print() ve id() gibi fonksiyonlarn tamam birer gml fonksiyondur. Biz bu
fonksiyonlar ilerleyen derslerde ok daha ayrntl bir ekilde inceleyeceiz. Ama u anda
bile fonksiyonlar konusunda epey bilgiye sahibiz.
imdiye kadar rendiimiz gml fonksiyonlardan u listede yer alanlar, matematik
ilemlerinde kullanlmaya uygun olanlardr:
1. complex()
2. float()
3. int()
4. pow()
5. round()
6. hex()
7. oct()
8. bin()
Biz bu fonksiyonlarn ne ie yaradn nceki derslerimizde zaten ayrntl olarak incelemitik.
O yzden burada bunlardan sz etmeyeceiz. Onun yerine, henz renmediimiz, ama
mutlaka bilmemiz gereken gml fonksiyonlar ele alacaz.
O halde hi vakit kaybetmeden yola koyulalm...

400 Blm 24. Saylar


Python 3 iin Trke Klavuz, Srm 3

24.2.1 abs()

Bu fonksiyon bize bir saynn mutlak deerini verir:


>>> abs(-2)

>>> abs(2)

24.2.2 divmod()

Bu fonksiyon, bir saynn bir sayya blnmesi ileminde blm ve kalan verir:
>>> divmod(10, 2)

(5, 0)

10 says 2 saysna blndnde blm 5, kalan ise 0 dr.


Bir rnek daha verelim:
>>> divmod(14, 3)

(4, 2)

Bu sonutan grdnz gibi, aslnda divmod() fonksiyonu u kodlarla ayn ii yapyor:


>>> 14 // 3, 14 % 3

Bu fonksiyonun gerekletirdii blme ileminin bir taban blme ilemi olduuna zellikle
dikkatinizi ekmek istiyorum.

24.2.3 max()

Size yle bir soru sorduumu dnn: Acaba aadaki listede yer alan saylarn en by
katr?
[882388, 260409, 72923, 692476, 131925, 259114, 47630, 84513, 25413, 614654,
239479, 299159, 175488, 345972, 458112, 791030, 243610, 413702, 565285,
773607, 131583, 979177, 247202, 615485, 647512, 556823, 242460, 852928,
893126, 792435, 273904, 544434, 627222, 601984, 966446, 384143, 308858,
915106, 914423, 826315, 258342, 188056, 934954, 253918, 468223, 262875,
462902, 370061, 336521, 367829, 147846, 838385, 605377, 175140, 957437,
105779, 153499, 435097, 9934, 435761, 989066, 357279, 341319, 420455,
220075, 28839, 910043, 891209, 975758, 140968, 837021, 526798, 235190,
634295, 521918, 400634, 385922, 842289, 106889, 742531, 359913, 842431,
666182, 516933, 22222, 445705, 589281, 709098, 48521, 513501, 277645,
860937, 655966, 923944, 7895, 77482, 929007, 562981, 904166, 619260,
616293, 203512, 67534, 615578, 74381, 484273, 941872, 110617, 53517,
402324, 156156, 839504 , 625325, 694080, 904277, 163914, 756250, 809689,
354050, 523654, 26723, 167882, 103404, 689579, 121439, 158946, 485258,
850804, 650603, 717388, 981770, 573882, 358726, 957285, 418479, 851590,
960182, 11955, 894146, 856069, 369866, 740623, 867622, 616830, 894801,

24.2. Aritmetik Fonksiyonlar 401


Python 3 iin Trke Klavuz, Srm 3

827179, 580024, 987174, 638930, 129200, 214789, 45268, 455924, 655940,


335481, 845907, 942437, 759380, 790660, 432715, 858959, 289617, 757317,
982063, 237940, 141714, 939369, 198282, 975017, 785968, 49954, 854914,
996780, 121633, 436419, 471, 776271, 91626, 209175, 894281, 417963, 624464,
736535, 418888, 506194, 591087, 64075, 50252, 952943, 25878, 217085,
223996, 416042, 484123, 810460, 423284, 956886, 237772, 960241, 601551,
830147, 449088, 364567, 337281, 524358, 980387, 393760, 619710, 100181,
96738, 275199, 553783, 975654, 662536, 979103, 869504, 702350, 174361,
970250, 267625, 661580, 444662, 871532, 881977, 981660, 446047, 508758,
530694, 608789, 339540, 242774, 637473, 874011, 732999, 511638, 744144,
710805, 641326, 88085, 128487, 59732, 739340, 443638, 830333, 832136,
882277, 403538, 441349, 721048, 32859]

te byle bir soruyu zmek iin max() fonksiyonundan yararlanabilirsiniz. Yukardaki listeyi
saylar adl bir deikene atadmz varsayarsak, aadaki kod bize listedeki en byk sayy
verecektir:
>>> max(saylar)

Yukardaki rneklerde max() fonksiyonunu kullanarak bir dizi iindeki en byk sayy bulduk.
Peki bu fonksiyonu kullanarak bir dizi iindeki en uzun karakter dizisini bulabilir miyiz? Evet,
bulabiliriz.
Diyelim ki elimizde yle bir liste var:
isimler = ["ahmet", "mehmet", "necla", "sedat", "abdullah",
"gyaseddin", "sibel", "can", "necmettin", "sava", "zgr"]

Amacmz bu liste iindeki en uzun kelimeyi bulmak. te bunu max() fonksiyonu ile
yapabiliriz. Dikkatlice bakn:
print(max(isimler, key=len))

Bu kodlar altrdmzda, listedeki en uzun isim olan gyaseddini elde edeceiz.


Grdnz gibi, max() fonksiyonu key adl zel bir parametre daha alyor. Bu parametreye
biz len deerini verdik. Bylece max() fonksiyonu liste iindeki eleri uzunluklarna gre
sralayp en uzun eyi bize sundu.
Hatrlarsanz geen blmde yle bir kod yazmtk:
say_sistemleri = ["onlu", "sekizli", "on altl", "ikili"]

print(("{:^9} "*len(say_sistemleri)).format(*say_sistemleri))

for i in range(17):
print("{0:^9} {0:^9o} {0:^9x} {0:^9b}".format(i))

Bu kodlar, farkl sayma sistemleri arasndaki farklar daha net grmemizi salamt. Yalnz
burada dikkat ettiyseniz, say_sistemleri adl listeye her e ekleyiimizde, listedeki en
uzun deeri dikkate alarak karakter dizisi biimlendiricileri iindeki, eler arasnda ne
kadar boluk braklacan belirleyen saylar gncelliyorduk. Mesela yukardaki rnekte,
eler arasnda yeterince boluk brakabilmek iin bu sayy 9 olarak belirlemitik. te
imdi rendiimiz max() fonksiyonunu kullanarak bu saynn otomatik olarak belirlenmesini
salayabiliriz. Dikkatlice inceleyin:

402 Blm 24. Saylar


Python 3 iin Trke Klavuz, Srm 3

say_sistemleri = ["onlu", "sekizli", "on altl", "ikili"]

en_uzun = len(max(say_sistemleri, key=len))

print(("{:^{aralk}} "*len(say_sistemleri)).format(*say_sistemleri, aralk=en_uzun))

for i in range(17):
print("{0:^{1}} {0:^{1}o} {0:^{1}x} {0:^{1}b}".format(i, en_uzun))

Grdnz gibi, max() fonksiyonunu ve bu fonksiyonun key parametresini kullanarak,


oluturduumuz tablodaki elerin arasna uygun boluu otomatik olarak eklemi olduk.
Bunun iin, say_sistemleri adl listedeki en uzun enin uzunluk miktarn temel aldk.

24.2.4 min()

Bu fonksiyon, max() fonksiyonun yapt iin tam tersini yapar. Yani bu fonksiyonu kullanarak
bir dizi iindeki en kk sayy bulabilirsiniz:
>>> min(saylar)

Tpk max() fonksiyonunda olduu gibi, min() fonksiyonunda da key parametresini


kullanabilirsiniz. Mesela max() fonksiyonunu anlatrken verdiimiz isim listesindeki en ksa
ismi bulabilmek iin u kodu yazabilirsiniz:
print(min(isimler, key=len))

24.2.5 sum()

Bu fonksiyon bir dizi iinde yer alan btn saylar birbiriyle toplar. rnein:
>>> a = [10, 20, 43, 45 , 77, 2, 0, 1]
>>> sum(a)

198

Eer bu fonksiyonun, toplama ilemini belli bir saynn zerine gerekletirmesini istiyorsanz
u kodu yazabilirsiniz:
>>> sum(a, 10)

208

sum() fonksiyonuna bu ekilde ikinci bir parametre verdiinizde, bu ikinci parametre toplam
deere eklenecektir.

24.2. Aritmetik Fonksiyonlar 403


BLM 25

Temel Dosya lemleri

Hatrlarsanz print() fonksiyonunu anlatrken, bu fonksiyonun le adl bir parametresi


olduundan sz etmitik. Bu parametre yardmyla print() fonksiyonunun ktlarn
bir dosyaya gnderebiliyorduk. Bylece print() fonksiyonunun bu zellii sayesinde,
Pythondaki Dosya Girdi/kts (File I/O ) konusuyla da ilk kez tanm olmutuk.
Ayrca print() fonksiyonu dnda, open() adl baka bir fonksiyon yardmyla da
dosyalar aabileceimizi ve bu dosyalarn zerinde eitli ilemleri gerekletirebileceimizi
renmitik. Ancak gerek print() fonksiyonunun le parametresi, gerekse open()
fonksiyonuyla imdiye kadar yaptmz rnekler araclyla rendiklerimiz dosyalara ilikin
ok snrl ilemleri yerine getirmemizi salyordu.
te biz bu blmde, dosya girdi/kts konusuna ilikin bildiklerimizi bir adm teye
gtreceiz ve gerek anlamda dosyalar nasl maniple edeceimizi reneceiz.
Programclk maceramz boyunca dosyalarla bol bol muhatap olacaksnz. O yzden bu
konuyu olabildiince ayrntl ve anlalr bir ekilde anlatmaya alacaz.
Dediimiz gibi, biz esasnda bu noktaya gelinceye kadar eitli fonksiyonlar ve bunlarn
birtakm parametreleri araclyla dosya ilemlerinden az da olsa zaten sz etmitik.
Dolaysyla aslnda tamamen yabancs olduunuz bir konuyla kar karya olmanz gibi bir
durum sz konusu deil. Biz bu blmde, zaten aina olduumuz bir konuyu ok daha
derinlemesine ele alacaz.
Python programlama dilinde dosyalarla urarken btn dosya ilemleri iin temel olarak tek
bir fonksiyondan yararlanacaz. Bu fonksiyonu siz zaten tanyorsunuz. Fonksiyonumuzun
ad open().

25.1 Dosya Oluturmak

Dediimiz gibi, Python programlama dilinde dosya ilemleri iin open() adl bir fonksiyondan
yararlanacaz. te dosya oluturmak iin de bu fonksiyonu kullanacaz.
nceki derslerimizde verdiimiz rneklerden de bildiiniz gibi, open() fonksiyonunu temel
olarak yle kullanyoruz:
f = open(dosya_ad, kip)

Not: open() fonksiyonu dosya_ad ve kip dnda baka parametreler de alr. lerleyen
sayfalarda bu parametrelerden de sz edeceiz.

404
Python 3 iin Trke Klavuz, Srm 3

Mesela tahsilat.txt adl bir dosyay yazma kipinde amak iin yle bir komut kullanyoruz:
tahsilat_dosyas = open("tahsilat_dosyas.txt", "w")

Burada tahsilat_dosyas.txt ifadesi dosyamzn adn belirtiyor. w har ise bu dosyann


yazma kipinde aldn sylyor.
Yukardaki komutu altrdnzda, o anda hangi dizin altnda bulunuyorsanz o dizin iinde
tahsilat_dosyas.txt adl bo bir dosyann olutuunu greceksiniz.
Bu arada, dosya adn yazarken, dosya ad ile birlikte o dosyann hangi dizin altnda
oluturulacan da belirleyebilirsiniz. rnein:
dosya = open("/dosyay/oluturmak/istediimiz/dizin/dosya_ad", "w")

Eer dosya adn dizin belirtmeden yazarsanz, oluturduunuz dosya, o anda hangi dizin
altnda bulunuyorsanz orada oluacaktr.
Ayrca dosyay barndran dizin adlarn yazarken, dizinleri ayrmak iin ters taksim (\ ) yerine
dz taksim (/ ) kullanmaya dikkat edin. Aksi halde, dizin ad oluturmaya alrken yanllkla
ka dizileri oluturabilirsiniz. Esasnda siz bu olguya hi yabanc deilsiniz. Zira ka
dizilerini anlatrken yle bir rnek verdiimizi hatrlyor olmalsnz:
print("C:\aylar\nisan\toplam masraf")

te eer bu rnekte olduu gibi ters taksim iaretleri ile oluturulmu dizin adlar
kullanrsanz programnz hata verecektir:
>>> open("C:\aylar\nisan\toplam masraf\masraf.txt", "w")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument: 'C:\x07ylar\nisan\toplam masraf\masraf.txt'

Bunun sebebi, bildiiniz gibi, Pythonn \a, \n ve \t ifadelerini birer ka dizisi olarak
alglamasdr. Bu durumdan kaabilmek iin, dizin adlarn ters taksim iareti ile ayrmann
dnda, r adl ka dizisinden de yararlanabilirsiniz:
>>> open(r"C:\aylar\nisan\toplam masraf\masraf.txt", "w")

...veya ters taksim iaretlerini iftleyebilirsiniz:


>>> open("C:\\aylar\\nisan\\toplam masraf\\masraf.txt", "w")

Bu ekilde, eer bilgisayarnzda C:\aylar\nisan\toplam masraf\ adl bir dizin varsa, o dizin
iinde masraf.txt adl bir dosya oluturulacaktr.
Bylece Python programlama dilinde bo bir dosyann nasl oluturulacan renmi olduk.
O halde gelin isterseniz imdi bu dosyann iini nasl dolduracamz renelim.

25.2 Dosyaya Yazmak

Bir dosyay, yukarda gsterdiimiz ekilde yazma kipinde atmz zaman, Python bizim iin
ii bo bir dosya oluturacaktr. Peki biz bu dosyann iini nasl dolduracaz?

25.2. Dosyaya Yazmak 405


Python 3 iin Trke Klavuz, Srm 3

Python programlama dilinde, open() fonksiyonu ile yazma kipinde atmz bir dosyaya bir
veri yazabilmek iin dosyalarn write() adl metodundan yararlanacaz.
Siz aslnda bu metodun da nasl kullanlacan ok iyi biliyorsunuz:
dosya.write(yazlacak_eyler)

Gelin bu forml somutlatracak bir rnek verelim. Mesela yukarda oluturduumuz


tahsilat dosyasnn iine baz veriler girelim.
nce dosyamz nasl oluturacamz hatrlayalm:
ths = open("tahsilat_dosyas.txt", "w")

imdi de bu dosyaya u bilgileri girelim:


ths.write("Halil Pazarlama: 120.000 TL")

Yani programmz yle grnsn:


ths = open("tahsilat_dosyas.txt", "w")
ths.write("Halil Pazarlama: 120.000 TL")

Bu komutlar verdiinizde, tahsilat_dosyas.txt adl dosyann iine u bilgilerin ilendiini


greceksiniz:
Halil Pazarlama: 120.000 TL

Eer dosyay atnzda bu bilgi yerine hl bo bir dosya gryorsanz, sebebi tamponda
tutulan verilerin henz dosyaya ilenmemi olmasdr.

Not: Bu konuyu print() fonksiyonunun ush adl parametresini incelerken rendiimizi


hatrlyor olmalsnz.

Eer durum byleyse, dosyanz kapatmanz gerekiyor. Bunu close() adl baka bir metotla
yapabildiimizi biliyorsunuz:
ths.close()

Bu arada, bu sylediklerimizden, eer yazdnz bilgiler zaten dosyaya ilenmise dosyay


kapatmanza gerek olmad anlamn karmayn. Herhangi bir ekilde atnz dosyalar
kapatmanz, zellikle dosyann almasyla birlikte kullanlmaya balayan ve arka planda
alan kaynaklarn serbest braklmas asndan byk nem tayor. O yzden atmz
dosyalarn tamamn programn ileyii sona erdiinde kapatmay unutmuyoruz. Yani
yukardaki program tam olarak yle yazyoruz:
ths = open("tahsilat_dosyas.txt", "w")
ths.write("Halil Pazarlama: 120.000 TL"),
ths.close()

Bu kodlarda srasyla u ilemleri gerekletirdik:


1. tahsilat_dosyas adl bir dosyay yazma kipinde aarak, bu adda bir dosya
oluturulmasn saladk,
2. write() metodunu kullanarak bu dosyaya baz bilgiler girdik,

406 Blm 25. Temel Dosya lemleri


Python 3 iin Trke Klavuz, Srm 3

3. Dosyamza yazdmz bilgilerin dosyaya ilendiinden emin olmak ve iletim sisteminin


dosyann almas ve dosyaya veri ilenmesi iin devreye soktuu btn kaynaklar
serbest brakmak iin close() metoduyla programmz kapattk.
Bu arada, bu bal kapatmadan nce nemli bir bilgi daha verelim. Pythonda bir dosyay
w kipinde atmzda, eer o adda bir dosya ilgili dizin iinde zaten varsa, Python bu
dosyay sorgusuz sualsiz silip, yerine ayn adda baka bir bo dosya oluturacaktr. Yani
mesela yukarda tahsilat_dosyas.txt adl dosyay oluturup iine bir eyler yazdktan sonra bu
dosyay yine w kipinde amaya alrsanz, Python bu dosyann btn ieriini silip, yine
tahsilat_dosyas.txt adn tayan baka bir dosya oluturacaktr. O yzden dosya ilemleri
srasnda bu w kipini kullanrken dikkat ediyoruz ve disk zerinde var olan dosyalarmz
yanllkla silmiyoruz.
Bylece bir dosyann nasl oluturulacan, nasl alacan ve iine birtakm bilgilerin nasl
girileceini kabataslak da olsa renmi olduk. imdi de dosyalar nasl okuyacamz
renelim.

25.3 Dosya Okumak

Bir nceki balkta dosyalarn iine bilgi girme ileminin Python programlama dilinde nasl
yapldn inceledik. Elbette bir dosyaya yazabilmenin yansra, bilgisayarnzda halihazrda
var olan bir dosyay okumak da isteyeceksiniz. Peki bunu nasl yapacaksnz?
Pythonda bir dosyay okumak iin yukarda anlattmz yazma yntemine benzer bir yntem
kullanacaz. Bildiiniz gibi, bir dosyay yazma kipinde amak iin w harni kullanyoruz.
Bir dosyay okuma kipinde amak iin ise r harni kullanacaz.
Mesela, bilgisayarmzda var olan hrist.txt adl dosyay okumak zere aalm:
fihrist = open("fihrist.txt", "r")

Bir dosyay open() fonksiyonu yardmyla aarken kip parametresi iin r harni kullanrsak,
Python o dosyay okuma yetkisiyle aacaktr. Yalnz burada yle bir zellik var: Eer bir
dosyay okuma kipinde aacaksanz, bu r harni hi belirtmeseniz de olur. Yani u komut
bilgisayarmzdaki hrist.txt adl dosyay okuma kipinde aacaktr:
fihrist = open("fihrist.txt")

Dolaysyla bir dosyay aarken kip belirtmediimizde Python bizim o dosyay okuma kipinde
amak istediimizi varsayacaktr.
Hatrlarsanz, w kipiyle atmz bir dosyaya yazmak iin write() adl bir metottan
yararlanyorduk. r kipiyle atmz bir dosyay okumak iin ise read(), readline() ve
readlines() adl farkl metottan yararlanacaz.
Yukardaki metot da Pythonda dosya okuma ilemlerini gerekletirmemizi salar. Peki bu
metotlarn de ayn ii yapyorsa neden tek bir metot deil de farkl metot var?
Bu metotlarn de dosya okumaya yarasa da, verdikleri ktlar birbirinden farkldr. O
yzden farkl amalar iin farkl metodu kullanmanz gereken durumlarla karlaabilirsiniz.
Bu metotlar arasndaki fark anlamann en kolay yolu bu metodu srayla kullanp, ktlar
incelemektir.
ncelikle ierii u olan, hrist.txt adl bir dosyamzn olduunu varsayalm:

25.3. Dosya Okumak 407


Python 3 iin Trke Klavuz, Srm 3

Ahmet zbudak : 0533 123 23 34


Mehmet Sln : 0532 212 22 22
Sami Sam : 0542 333 34 34

imdi bir dosya ap u kodlar yazalm:


fihrist = open("fihrist.txt")
print(fihrist.read())

Bu kodlar altrdmzda, eer kullandnz iletim sistemi GNU/Linux ise muhtemelen u


kty elde edeceksiniz:

Ahmet zbudak : 0533 123 23 34


Mehmet Sln : 0532 212 22 22
Sami Sam : 0542 333 34 34

Ama eer bu kodlar Windowsta altrdysanz Trke karakterler bozuk km olabilir. Bu


durumu imdilik grmezden gelin. Birazdan bu durumun nedenini aklayacaz.
Yukarda elde ettiimiz ey bir karakter dizisidir bunu u ekilde teyit edebileceinizi
biliyorsunuz:
fihrist = open("fihrist.txt")
print(type(fihrist.read()))

Grdnz gibi, read() metodu bize, dosyann btn ieriini bir karakter dizisi olarak
veriyor. Bir de una bakalm:
fihrist = open("fihrist.txt")
print(fihrist.readline())

Burada da readline() metodunu kullandk. Bu kodlar bize yle bir kt veriyor:

Ahmet zbudak : 0533 123 23 34

read() metodu bize dosya ieriinin tamamn veriyordu. Grdnz gibi readline()
metodu tek bir satr veriyor. Yani bu metot yardmyla dosyalar satr satr okuyabiliyoruz.
Bu metodun ileyi tarzn daha iyi grebilmek iin bu kodlar dosyaya yazp altrmak yerine
etkileimli kabuk zerinden de altrabilirsiniz:
>>> fihrist = open("fihrist.txt", "r")
>>> print(fihrist.readline())

Ahmet zbudak : 0533 123 23 34

>>> print(fihrist.readline())

Mehmet Sln : 0532 212 22 22

>>> print(fihrist.readline())

Sami Sam : 0542 333 34 34

Grdnz gibi, readline() metodu gerekten de dosyay satr satr okuyor.


Son satr da okuduktan sonra, readline() metodunu tekrar altrrsak ne olur peki?
Bakalm:

408 Blm 25. Temel Dosya lemleri


Python 3 iin Trke Klavuz, Srm 3

>>> print(fihrist.readline())

Grdnz gibi, bu defa hibir kt almadk. nk dosyada okunacak satr kalmad. Bu


yzden de Python bize bo bir kt verdi. Bu durumu daha net grmek iin kodu etkileimli
kabukta print() olmadan yazabilirsiniz:
>>> fihrist.readline()

''

Gerekten de elimizdeki ey bo bir karakter dizisi... Demek ki bir dosya tamamen


okunduktan sonra, Python otomatik olarak tekrar dosyann bana dnmyor. Byle bir
durumda dosyann bana nasl geri dneceimizi inceleyeceiz, ama isterseniz biz baka bir
konuyla devam edelim.

Not: Bir dosyann tamam okunduktan sonra otomatik olarak baa sarlmamas zellii
sadece readline() metodu iin deil, teki btn dosya okuma metotlar iin de geerlidir.
Yani bir dosyay read(), readline() veya readlines() metotlarndan herhangi biri ile
okuduunuzda imle baa dnmez.

Dediimiz ve gsterdiimiz gibi, read() ve readline() metotlar bize bir karakter dizisi
dndryor. Bu iki metot arasndaki fark ise, read() metodunun dosyann tamamn
nmze sererken, readline() metodunun dosyay satr satr okuyup, her defasnda tek bir
satr nmze srmesidir. Bir de readlines() metodunun ne yaptna bakalm...
u kodlar yazalm:
fihrist = open("fihrist.txt")
print(fihrist.readlines())

Bu kodlar yazdmzda una benzer bir kt alacaz:

['Ahmet zbudak : 0533 123 23 34\n', 'Mehmet Sln : 0532 212 22 22\n',
'Sami Sam : 0542 333 34 34']

Grdnz gibi, bu defa karakter dizisi yerine bir liste ile karlayoruz. Demek ki read() ve
readline() metotlar kt olarak bize bir karakter dizisi verirken, readlines() metodu liste
veriyormu. Bunun neden nemli bir bilgi olduunu artk gayet iyi biliyor olmanz lazm. Zira
bir verinin tipi, o veriyle neler yapp neler yapamayacamz dorudan etkiler...

25.4 Dosyalar Otomatik Kapatma

Daha nce de sylediimiz gibi, bir dosyay ap bu dosya zerinde gerekli ilemleri yaptktan
sonra bu dosyay ak brakmamak byk nem tar. Dolaysyla zerinde ilem yaptmz
btn dosyalar, iimiz bittikten sonra, mutlaka kapatmalyz. nk bir dosya aldnda
iletim sistemi, sistem kaynaklarnn bir ksmn bu dosyaya ayrr. Eer dosyay ak
brakrsak, sistem kaynaklarn gereksiz yere megul etmi oluruz. Ancak farkl sebeplerden,
dosyalar aldktan sonra kapanmayabilir. rnein atnz dosyay kapatmay unutmu
olabilirsiniz. Yani programnzn hibir yerinde close() metodunu kullanmamsnzdr.
Bunun dnda, programnzdaki bir hata da dosyalarn kapanmasn engelleyebilir. rnein
bir dosya aldktan sonra programda beklenmeyen bir hata gerekleirse, programnz asla
close() satrna ulaamayabilir. Bu durumda da alan dosya kapanmadan ylece bekler.

25.4. Dosyalar Otomatik Kapatma 409


Python 3 iin Trke Klavuz, Srm 3

Bu tr durumlara kar iki seeneiniz var:


1. try... except... finally... bloklarndan yararlanmak
2. with adl bir deyimi kullanmak
Birinci yntemden daha nce de bahsettiimizi hatrlyorsunuz. Hata yakalama blmn
anlatrken bununla ilgili yle bir rnek vermitik:
try:
dosya = open("dosyaad", "r")
...burada dosyayla baz ilemler yapyoruz...
...ve anszn bir hata oluuyor...
except IOError:
print("bir hata olutu!")
finally:
dosya.close()

Bu yntem gayet uygun ve iyi bir yntemdir. Ancak Python bize bu tr durumlar iin ok daha
pratik bir yntem sunar. Dikkatlice bakn:
with open("dosyaad", "r") as dosya:
print(dosya.read())

Dosyalarmz bu ekilde ap zerlerinde ilemlerimizi yaptmzda Python dosyay bizim iin


kendisi kapatacaktr. Bu ekilde bizim ayrca bir close() satr yazmamza gerek yok. with
deyimini kullanmamz sayesinde, dosya aldktan sonra arada bir hata olusa bile Python
dosyay sasalim kapatp sistem kaynaklarnn israf edilmesini nleyecektir.

25.5 Dosyay leri-Geri Sarmak

Dosya okumak iin kullanlan metotlar anlatrken, dosya bir kez okunduktan sonra imlecin
otomatik olarak dosyann bana dnmediini grmtk. Yani mesela read() metoduyla
dosyay bir kez okuduktan sonra, dosyay tekrar okumak istersek elde edeceimiz ey bo bir
karakter dizisi olacaktr. nk dosya okunduktan sonra okunacak baka bir satr kalmam,
imle dosya sonuna ulam ve otomatik olarak da baa dnmemitir. Bu olguyu etkileimli
kabuk zerinde daha net bir ekilde grebileceinizi biliyorsunuz.
Peki dosyay tamamen okuduktan sonra tekrar baa dnmek istersek ne yapacaz? Bir dosya
tamamen okunduktan sonra tekrar baa dnmek iin dosyalarn seek() adl bir metodundan
yararlanacaz.
Mesela u rneklere bakalm. Bu rnekleri daha iyi anlamak iin bunlar Pythonn etkileimli
kabuunda altrmanz tavsiye ederim:
>>> f = open("python.txt")
>>> f.read()

'Bu programlama dili Guido Van Rossum adl Hollandal bir


programc\ntarafndan 90l yllarn banda gelitirilmeye balanmtr.
ou insan,\nisminin Python olmasna aldanarak, bu programlama dilinin,
adn piton\nylanndan aldn dnr. Ancak zannedildiinin aksine bu
programlama dilinin\nad piton ylanndan gelmez. Guido Van Rossum bu
programlama dilini, The Monty\nPython adl bir ngiliz komedi grubunun,
Monty Pythons Flying Circus adl\ngsterisinden esinlenerek adlandrmtr.
Ancak her ne kadar gerek byle olsa\nda, Python programlama dilinin pek ok

410 Blm 25. Temel Dosya lemleri


Python 3 iin Trke Klavuz, Srm 3

yerde bir ylan figr ile temsil\nedilmesi neredeyse bir gelenek halini
almtr.\n'

Burada open() fonksiyonunu kullanarak python.txt adl bir dosyay ap, read() metodu
yardmyla da bu dosyann ieriini okuduk. Bu noktada dosyay tekrar okumaya alrsak
elde edeceimiz ey bo bir karakter dizisi olacaktr:
>>> f.read()

''

nk dosya bir kez tamamen okunduktan sonra imle otomatik olarak baa dnmyor.
Dosyay tekrar okumak istiyorsak, bunu baa bizim sarmamz lazm. te bunun iin seek()
metodunu kullanacaz:
>>> f.seek(0)

Grdnz gibi seek() metodunu bir parametre ile birlikte kullandk. Bu metoda verdiimiz
parametre, dosya iinde kanc bayt konumuna gideceimizi gsteriyor. Biz burada 0
saysn kullanarak dosyann ilk baytna, yani en bana dnm olduk. Artk dosyay tekrar
okuyabiliriz:
>>> f.read()

'Bu programlama dili Guido Van Rossum adl Hollandal bir


programc\ntarafndan 90l yllarn banda gelitirilmeye balanmtr.
ou insan,\nisminin Python olmasna aldanarak, bu programlama dilinin,
adn piton\nylanndan aldn dnr. Ancak zannedildiinin aksine bu
programlama dilinin\nad piton ylanndan gelmez. Guido Van Rossum bu
programlama dilini, The Monty\nPython adl bir ngiliz komedi grubunun,
Monty Pythons Flying Circus adl\ngsterisinden esinlenerek adlandrmtr.
Ancak her ne kadar gerek byle olsa\nda, Python programlama dilinin pek ok
yerde bir ylan figr ile temsil\nedilmesi neredeyse bir gelenek halini
almtr.\n'

Elbette seek() metodunu kullanarak istediiniz bayt konumuna dnebilirsiniz. Mesela


eer dosyann 10. baytnn bulunduu konuma dnmek isterseniz bu metodu yle
kullanabilirsiniz:
>>> f.seek(10)

Eer o anda dosyann hangi bayt konumunda bulunduunuzu renmek isterseniz de tell()
adl baka bir metottan yararlanabilirsiniz. Bu metodu parametresiz olarak kullanyoruz:
>>> f.tell()

20

Bu ktya gre o anda dosyann 20. baytnn zerindeyiz...


Bu arada, dosya iinde bulunduumuz konumu baytlar zerinden tarif etmemizi biraz
yadrgam olabilirsiniz. Acaba neden karakter deil de bayt? Biraz sonra bu konuya geleceiz.
Biz imdilik nemli baka bir konuya deinelim.

25.5. Dosyay leri-Geri Sarmak 411


Python 3 iin Trke Klavuz, Srm 3

25.6 Dosyalarda Deiiklik Yapmak

Buraya kadar, Pythonda bir dosyann nasl oluturulacan, bo bir dosyaya nasl veri
girileceini ve varolan bir dosyadan nasl veri okunacan rendik. Ama varolan ve ii
halihazrda dolu bir dosyaya nasl veri ekleneceini bilmiyoruz. te imdi bu ilemin nasl
yaplacan tartacaz.
Ancak burada nemli bir ayrntya dikkatinizi ekmek istiyorum. Dosyalarn neresinde
deiiklik yapmak istediiniz byk nem tar. Unutmayn, dosyalarn banda, ortasnda ve
sonunda deiiklik yapmak birbirlerinden farkl kavramlar olup, birbirinden farkl ilemlerin
uygulanmasn gerektirir.
Biz bu blmde dosyalarn ba tarafna, ortasna ve sonuna nasl veri eklenip karlacan
ayr ayr tartacaz.

25.6.1 Dosyalarn Sonunda Deiiklik Yapmak

Daha nce de sylediimiz gibi, Pythonda bir dosyay aarken, o dosyay hangi kipte
aacamz belirtmemiz gerekiyor. Yani eer bir dosyay okumak istiyorsak dosyay r
kipinde, yazmak istiyorsak da w kipinde amamz gerekiyor. Bildiiniz gibi w kipi dosya
ieriini tamamen siliyor.
Eer bir dosyay tamamen silmeden, o dosyaya ekleme yapmak veya o dosyada herhangi
bir deiiklik yapmak istiyorsak, dosyamz buraya kadar rendiimiz iki kipten daha farkl
bir kiple amamz gerekiyor. imdi reneceimiz bu yeni kipin ad a. Yani Pythonda ii bo
olmayan bir dosyada deiiklik yapabilmek iin a adl bir kipten yararlanacaz:
f = open(dosya_ad, "a")

rnein yukarda verdiimiz hrist.txt adl dosyay bu kipte aalm ve dosyaya yeni bir girdi
ekleyelim:
with open("fihrist.txt", "a") as f:
f.write("Selin zden\t: 0212 222 22 22")

Grdnz gibi, dosyaya yeni eklediimiz girdiler otomatik olarak dosyann sonuna ilave
ediliyor. Burada u noktaya dikkat etmeniz lazm. Dosyann sonunda bir satr ba
karakterinin (\n ) bulunup bulunmamasna bal olarak, dosyaya eklediiniz yeni satrlar
dzgn bir ekilde bir alt satra geebilecei gibi, dosyann son satrnn yanna da eklenebilir.
Dolaysyla duruma gre yukardaki satr u ekilde yazmanz gerekebilir:
with open("fihrist.txt", "a") as f:
f.write("\nSelin zden\t: 0212 222 22 22")

Burada bir alt satra geebilmek iin Selin ifadesinden nce bir satr ba karakteri
eklediimize dikkat edin. Ayrca eer bu satrdan sonra bir baka satr daha ekleyecekseniz,
ilgili satrn sonuna da bir satr ba karakteri koymanz gerekebilir:
with open("fihrist.txt", "a") as f:
f.write("Selin zden\t: 0212 222 22 22\n")

Kar karya olduunuz duruma gre, satr ba karakterlerine ihtiyacnz olup olmadn ve
ihtiyacnz varsa bunlar nereye yerletireceinizi kendiniz deerlendirmelisiniz.

412 Blm 25. Temel Dosya lemleri


Python 3 iin Trke Klavuz, Srm 3

25.6.2 Dosyalarn Banda Deiiklik Yapmak

Bir nceki blmde dosya sonuna nasl yeni satr ekleyeceimizi rendik. Ama siz
programclk maceranz srasnda muhtemelen dosyalarn sonuna deil de, en bana ekleme
yapmanz gereken durumlarla da karlaacaksnz. Pythonda bu ii yapmak da ok kolaydr.
rnek olmas asndan, hrist.txt adl dosyann ieriini ele alalm:

Ahmet zbudak : 0533 123 23 34


Mehmet Sln : 0532 212 22 22
Sami Sam : 0542 333 34 34
Selin zden : 0212 222 22 22

Dosya ierii bu. Eer bu dosyay a kipi ile atktan sonra dorudan write() metodunu
kullanarak bir ekleme yaparsak, yeni deer dosyann sonuna eklenecektir. Ama biz mesela u
veriyi:
Sedat Kz : 0322 234 45 45

Ahmet zbudak : 0533 123 23 34 girdisinin hemen stne, yani dosyann sonuna deil de
en bana eklemek istersek ne yapacaz?
ncelikle u kodlar deneyelim:
with open("fihrist.txt", "r") as f:
veri = f.read()
f.seek(0) #Dosyay baa saryoruz
f.write("Sedat Kz\t: 0322 234 45 45\n"+veri)

Bu kodlar bir dosyaya kaydedip altrdmzda Python bize u hatay verecektir:


istihza@netbook:~/Desktop$ python3 deneme.py
Traceback (most recent call last):
File "deneme.py", line 4, in <module>
f.write("Sedat Kz\t: 0322 234 45 45\n"+veri)
io.UnsupportedOperation: not writable

Bu hatay almamzn sebebi dosyay okuma kipinde am olmamz. nk bir dosyay


okuma kipinde atmzda o dosya zerinde yalnzca okuma ilemleri yapabiliriz. Dosyaya
yeni veri ekleme ksmna gelindiinde, dosya yalnzca okuma yetkisine sahip olduu iin,
Python bize yukardaki hata mesajn verecek, dosyann yazlamaz olduundan ikayet
edecektir.
Peki dosyay w karakteri yardmyla yazma kipinde aarsak ne olur? O zaman da u meum
hatay alrz:
istihza@netbook:~/Desktop$ python3 deneme.py
Traceback (most recent call last):
File "deneme.py", line 2, in <module>
veri = f.read()
io.UnsupportedOperation: not readable

Grdnz gibi, bu kez de dosyann okunamadna ilikin bir hata alyoruz. nk biz bu
kez de dosyay yazma kipinde atk. Ancak burada yle bir durum var. Bildiiniz gibi, bir
dosyay w kipi ile atmzda, Python bize hibir ey sormadan varolan ierii silecektir.
Burada da yukarda yazdmz kodlar yznden dosya ieriini kaybettik. Unutmayn, dosya
okuma-yazma ilemleri belli bir takm riskleri iinde barndrr. O yzden bu tr ilemleri
yaparken fazladan dikkat gstermeliyiz.

25.6. Dosyalarda Deiiklik Yapmak 413


Python 3 iin Trke Klavuz, Srm 3

Yukarda da grdmz gibi, dosyamz r veya w kiplerinde amak ie yaramad. Peki ne


yapacaz? Bunun cevab ok basit: Dosyamz hem okuma hem de yazma kipinde aacaz.
Bunun iin de farkl bir kip kullanacaz. Dikkatlice bakn:
with open("fihrist.txt", "r+") as f:
veri = f.read()
f.seek(0) #Dosyay baa saryoruz
f.write("Sedat Kz\t: 0322 234 45 45\n"+veri)

Burada r+ adl yeni bir kip kullandmza dikkat edin. + iareti bir dosyay hem okuma
hem de yazma kipinde amamza yardmc olur. te bu iareti r kipiyle birlikte r+ eklinde
kullanarak dosyamz hem okuma hem de yazma kipinde amay baardk. Artk ilgili dosya
zerinde hem okuma hem de yazma ilemlerini ayn anda gerekletirebiliriz.
Yukardaki kodlarda ilk satrn ardndan yle bir kod yazdk:
veri = f.read()

Bylece dosyann btn ieriini veri adl bir deikene atam olduk. Peki bu ilemi
yapmazsak ne olur? Yani mesela yle bir kod yazarsak:
with open("fihrist.txt", "r+") as f:
f.seek(0)
f.write("Sedat Kz\t: 0322 234 45 45\n")

Bu ekilde Sedat Kz\t: 0322 234 45 45\n satr, dosyadaki ilk satr silip onun yerine
geecektir. nk f.seek(0) ile dosyann bana dnp o noktaya, yani dosyann ilk satrna
bir veri ekledikten sonra Python br satrlar otomatik olarak bir alt satra kaydrmaz. Bunun
yerine ilk satrdaki verileri silip onun yerine, yeni eklenen satr getirir. Eer yapmak istediiniz
ey buysa ne l. Bu kodlar kullanabilirsiniz. Ama bizim istediimiz ey bu deil. O yzden
veri = f.read() satrn kullanarak dosya ieriini bir deiken iinde depoluyoruz ve bylece
bu verileri kaybetmemi oluyoruz.
Bu satrn ardndan gelen f.seek(0) satrnn ne ie yaradn biliyorsunuz. Biz yeni veriyi
dosyann en bana eklemek istediimiz iin, doal olarak bu kod yardmyla dosyann en
bana saryoruz. Bylece u kod:
f.write("Sedat Kz\t: 0322 234 45 45\n"+veri)

Sedat Kz\t: 0322 234 45 45\n satrn dosyann en bana ekliyor. Ayrca burada, biraz nce
veri deikenine atadmz dosya ieriini de yeni eklediimiz satrn hemen arkasna ilave
ettiimize dikkat edin. Eer bunu yapmazsanz, elinizde sadece Sedat Kzn iletiim bilgilerini
barndran bir dosya olacaktr...

25.6.3 Dosyalarn Ortasnda Deiiklik Yapmak

Grdnz gibi, Pythonda bir dosyann en sonuna ve en bana veri eklemek ok zor deil.
Birka satr yardmyla bu ilemleri rahatlkla yapabiliyoruz. Peki ya bir dosyann en bana
veya en sonuna deil de rastgele bir yerine ekleme yapmak istersek ne olacak?
Hatrlarsanz, Pythonda her veri tipinin farkl zellikleri olduundan, her veri tipinin farkl
alardan birbirlerine kar stnlkleri ya da zayklar olduundan sz etmitik. Dediimiz
gibi, Pythonda baz iler iin baz veri tiplerini kullanmak daha pratik ve avantajl olabilir.
rnein karakter dizileri deitirilemeyen veri tipleri olduu iin, mesela bir metinde
deiiklik yapmamz gereken durumlarda, eer mmknse listeleri kullanmak daha mantkl
olabilir. Zira bildiiniz gibi, karakter dizilerinin aksine listeler deitirilebilir veri tipleridir.

414 Blm 25. Temel Dosya lemleri


Python 3 iin Trke Klavuz, Srm 3

nceki sayfalarda bir dosyay okurken farkl metottan yararlanabileceimizi renmitik.


Bu metotlarn read(), readline() ve readlines() adl metotlar olduunu biliyorsunuz. Bu
metottan read() adl olan bize kt olarak bir karakter dizisi veriyor. readline() metodu
ise dosyalar satr satr okuyor ve bize yine bir karakter dizisi veriyor. Sonuncu metot olan
readlines() ise bize bir liste veriyor. readline() metodundan farkl olarak readlines()
metodu dosyann tamamn bir rpda okuyor.
Bu metot arasndan, ad readlines() olannn, dosyalarn herhangi bir yerinde deiiklik
yapmak konusunda bize yardmc olabileceini tahmin etmi olabilirsiniz. nk dediimiz
gibi readlines() metodu bize bir dosyann ieriini liste halinde veriyor. Bildiiniz gibi
listeler, zerinde deiiklik yaplabilen veri tipleridir. Listelerin bu zelliinden yararlanarak,
dosyalarn herhangi bir yerinde yapmak istediimiz deiiklikleri rahatlkla yapabiliriz. imdi
dikkatlice bakn u kodlara:
with open("fihrist.txt", "r+") as f:
veri = f.readlines()
veri.insert(2, "Sedat Kz\t: 0322 234 45 45\n")
f.seek(0)
f.writelines(veri)

Bu kodlar bir dosyaya kaydedip altrdysanz, istediimiz ilemi baaryla yerine getirdiini
grmsnzdr. Peki ama bu kodlar nasl alyor?
Yukardaki kodlarda dikkatimizi eken pek ok zellik var. lk olarak gzmze arpan
ey, dosyay r+ kipinde am olmamz. Bu ekilde dosyay hem okuma hem de yazma
kipinde am oluyoruz. nk dosyada ayn anda hem okuma hem de yazma ilemleri
gerekletireceiz.
Daha sonra yle bir satr yazdk:
veri = f.readlines()

Bu sayede dosyadaki btn verileri bir liste olarak alm olduk. Liste adl veri tipi ile ne
yapabiliyorsak, bu ekilde aldmz dosya ierii zerinde de ayn eyleri yapabiliriz. Bizim
amacmz bu listenin 2. srasna yeni bir satr eklemek. Bu ilemi listelerin insert() adl
metodu yardmyla rahatlkla yapabiliriz:
veri.insert(2, "Sedat Kz\t: 0322 234 45 45\n")

Bu ekilde liste zerinde istediimiz deiiklikleri yaptktan sonra tekrar dosyann bana
dnmemiz lazm. nk readlines() metoduyla dosyay bir kez tam olarak okuduktan sonra
imle o anda dosyann en sonunda bulunuyor. Eer dosyann en bana dnmeden herhangi
bir yazma ilemi gerekletirirsek, yazlan veriler dosyann sonuna eklenecektir. Bizim
yapmamz gereken ey dosyann en bana sarp, deitirilmi verilerin dosyaya yazlmasn
salamak olmal. Bunu da u satr yardmyla yapyoruz:
f.seek(0)

Son olarak da btn veirleri dosyaya yazyoruz:


f.writelines(veri)

imdiye kadar dosyaya yazma ilemleri iin write() adl bir metottan yararlanmtk. Burada
ise writelines() adl baka bir metot gryoruz. Peki bu iki metot arasndaki fark nedir?
write() metodu bir dosyaya yalnzca karakter dizilerini yazabilir. Bu metot yardmyla
dosyaya liste tipinde herhangi bir veri yazamazsnz. Eer mutlaka write() metodunu

25.6. Dosyalarda Deiiklik Yapmak 415


Python 3 iin Trke Klavuz, Srm 3

kullanmak isterseniz, liste zerinde bir for dngs kurmanz gerekir. O zaman yukardaki
kodlar yle yazmanz gerekir:
with open("fihrist.txt", "r+") as f:
veri = f.readlines()
veri.insert(2, "Sedat Kz\t: 0322 234 45 45\n")
f.seek(0)
for e in veri:
f.write(e)

writelines() adl metot ise bize dosyaya liste tipinde verileri yazma imkan verir. Dolaysyla
herhangi bir dng kurmak zorunda kalmadan listeleri dosyalarmza yazabiliriz.
Bylece Pythonda dosyalarn herhangi bir yerine nasl yazabileceimizi renmi olduk. Bu
arada eer isteseydik yukardaki kodlar yle de yazabilirdik:
with open("fihrist.txt", "r") as f:
veri = f.readlines()

with open("fihrist.txt", "w") as f:


veri.insert(2, "Sedat Kz\t: 0322 234 45 45\n")
f.writelines(veri)

Bir nceki kodlardan farkl olarak bu kodlarda dosyamz nce okuma kipinde ap verileri
veri adl bir deiken iinde sakladk. Ardndan ayn dosyay bir kez de yazma kipinde aarak,
gerekli deiiklikleri liste zerinde gerekletirdikten sonra btn verileri dosyaya yazdk.
Unutmayn, Pythonda herhangi bir ilemi pek ok farkl ekilde gerekletirebilirsiniz. Biz
yukarda olas yntemlerden bazlarn ele aldk. Zaten btn yntemleri tek tek gstermemiz
pek mmkn olmazd. Siz dosyalara ilikin bilgilerinizi ve farkl aralar kullanarak ayn
ilemleri ok daha farkl ekillerde de yapabilirsiniz. Yani kar karya olduunuz duruma
deerlendirip, yukardaki kodlardan uygun olann veya kendi bulduunuz bambaka bir
yntemi kullanabilirsiniz.
Bu arada, aslnda yukardaki kodlarda uyguladmz yntem biraz gvensiz. nk ayn
dosyay hem okuyup hem de bu dosyaya yeni veri ekliyoruz. Eer bu ilemlerin herhangi
bir aamasnda bir hata oluursa, btn deiiklikleri dosyaya ileyemeden dosya ieriini
tmden kaybedebiliriz. Bu tr risklere kar en uygun zm, okuma ve yazma ilemlerini ayr
dosyalar zerinde gerekletirmektir. Bunun nasl yaplacandan biraz sonra sz edeceiz.
Biz imdi baka bir konuya deinelim.

25.7 Dosyaya Erime Kipleri

Dosyalar konusunu anlatrken yukarda verdiimiz rneklerden de grdnz gibi,


Pythonda dosyalara eriimin trn ve niteliini belirleyen baz kipler var. Bu kipler
dosyalarn alrken hangi yetkilere sahip olacan veya olmayacan belirliyor. Gelin
isterseniz bu kipleri tek tek ele alalm.

416 Blm 25. Temel Dosya lemleri


Python 3 iin Trke Klavuz, Srm 3

Kip Aklamas
"r" Bu ntanml kiptir. Bu kip dosyay okuma yetkisiyle aar. Ancak bu kipi
kullanabilmemiz iin, ilgili dosyann disk zerinde halihazrda var olmas gerekir.
Eer bu kipte almak istenen dosya mevcut deilse Python bize bir hata mesaj
gsterecektir. Dediimiz gibi, bu ntanml kiptir. Dolaysyla dosyay aarken
herhangi bir kip belirtmezsek Python dosyay bu kipte amak istediimizi
varsayacaktr.
"w" Bu kip dosyay yazma yetkisiyle aar. Eer belirttiiniz adda bir dosya zaten disk
zerinde varsa, Python hibir ey sormadan dosya ieriini silecektir. Eer
belirttiiniz adda bir dosya diskte yoksa, Python o adda bir dosyay otomatik olarak
oluturur.
"a" Bu kip dosyay yazma yetkisiyle aar. Eer dosya zaten disk zerinde mevcutsa
ieriinde herhangi bir deiiklik yaplmaz. Bu kipte atnz bir dosyaya eklediiniz
veriler varolan verilere ilave edilir. Eer belirttiiniz adda bir dosya yoksa Python
otomatik olarak o adda bir dosyay sizin iin oluturacaktr.
"x" Bu kip dosyay yazma yetkisiyle aar. Eer belirttiiniz adda bir dosya zaten disk
zerinde varsa, Python varolan dosyay silmek yerine size bir hata mesaj gsterir.
Zaten bu kipin w kipinden fark, varolan dosyalar silmemesidir. Eer belirttiiniz
adda bir dosya diskte yoksa, bu kip yardmyla o ada sahip bir dosya
oluturabilirsiniz.
"r+" Bu kip, bir dosyay hem yazma hem de okuma yetkisiyle aar. Bu kipi
kullanabilmeniz iin, belirttiiniz dosyann disk zerinde mevcut olmas gerekir.
"w+" Bu kip bir dosyay hem yazma hem de okuma yetkisiyle aar. Eer dosya mevcutsa
ierik silinir, eer dosya mevcut deilse oluturulur.
"a+" Bu kip bir dosyay hem yazma hem de okuma yetkisiyle aar. Eer dosya zaten disk
zerinde mevcutsa ieriinde herhangi bir deiiklik yaplmaz. Bu kipte atnz bir
dosyaya eklediiniz veriler varolan verilere ilave edilir. Eer belirttiiniz adda bir
dosya yoksa Python otomatik olarak o adda bir dosyay sizin iin oluturacaktr.
"x+" Bu kip dosyay hem okuma hem de yazma yetkisiyle aar. Eer belirttiiniz adda bir
dosya zaten disk zerinde varsa, Python varolan dosyay silmek yerine size bir hata
mesaj gsterir. Zaten bu kipin w+ kipinden fark, varolan dosyalar silmemesidir.
Eer belirttiiniz adda bir dosya diskte yoksa, bu kip yardmyla o ada sahip bir
dosya oluturup bu dosyay hem okuma hem de yazma yetkisiyle aabilirsiniz.
"rb" Bu kip, metin dosyalar ile ikili (binary ) dosyalar ayrt eden sistemlerde ikili
dosyalar okuma yetkisiyle amak iin kullanlr. r kipi iin sylenenler bu kip iin
de geerlidir.
"wb" Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar yazma
yetkisiyle amak iin kullanlr. w kipi iin sylenenler bu kip iin de geerlidir.
"ab" Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar yazma
yetkisiyle amak iin kullanlr. a kipi iin sylenenler bu kip iin de geerlidir.
"xb" Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar yazma
yetkisiyle amak iin kullanlr. x kipi iin sylenenler bu kip iin de geerlidir.
"rb+"Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar hem
okuma hem de yazma yetkisiyle amak iin kullanlr. r+ kipi iin sylenenler bu
kip iin de geerlidir.
"wb+"Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar hem
okuma hem de yazma yetkisiyle amak iin kullanlr. w+ kipi iin sylenenler bu
kip iin de geerlidir.
"ab+"Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar hem
okuma hem de yazma yetkisiyle amak iin kullanlr. a+ kipi iin sylenenler bu
kip iin de geerlidir.
"xb+"Bu kip, metin dosyalar ile ikili dosyalar ayrt eden sistemlerde ikili dosyalar hem
okuma hem de yazma yetkisiyle amak iin kullanlr. x+ kipi iin sylenenler bu
25.7. Dosyaya Erime Kipleri 417
kip iin de geerlidir.
Python 3 iin Trke Klavuz, Srm 3

Btn bu tabloya baktnzda ilk bakta sanki bir sr farkl eriim kipi olduunu dnm
olabilirsiniz. Ama aslnda tabloyu biraz daha incelerseniz, temel olarak r, w, a, x ve
b kiplerinin olduunu, geri kalan kiplerin ise bunlarn kombinasyonlarndan olutuunu
greceksiniz.
Daha nce de sylediimiz gibi, dosya ilemlerini pek ok farkl yntemle
gerekletirebilirsiniz. Yukardaki tabloyu dikkatlice inceleyerek, yapmak istediiniz ileme
uygun kipi rahatlkla seebilirsiniz.
Bu arada, yukardaki tabloda deindiimiz ikili (binary ) dosyalardan henz sz etmedik. Bir
sonraki blmde bu dosya trn de ele alacaz.

418 Blm 25. Temel Dosya lemleri


BLM 26

Dosyalarn Metot ve Nitelikleri

Dosyalara ilikin olarak bir nceki blmde anlattmz eylerin kafanza yatmas asndan
size u bilgiyi de verelim: Dosyalar da, tpk karakter dizileri ve listeler gibi, Python
programlama dilindeki veri tiplerinden biridir. Dolaysyla tpk karakter dizileri ve listeler
gibi, dosya (le ) adl bu veri tipinin de baz metotlar ve nitelikleri vardr. Gelin isterseniz bu
metot ve niteliklerin neler olduunu yle bir listeleyelim:
dosya = open("falanca_dosya.txt", "w")
print(*[metot for metot in dir(dosya) if not metot.startswith("_")], sep="\n")

Bu kodlar, dosya adl veri tipinin bizi ilgilendiren btn metotlarn alt alta ekrana basacaktr.
Eer yukardaki kodlar anlamakta zorluk ektiyseniz, bunlar yle de yazabilirsiniz:
dosya = open("falanca_dosya.txt", "w")

for metot in dir(dosya):


if not metot.startswith("_"):
print(metot, sep="\n")

Bildiiniz gibi bu kodlar bir ncekiyle tamamen ayn anlama geliyor.


Bu kodlar altrdnzda karnza pek ok metot kacak. Biz buraya gelene kadar bu
metotlarn en nemlilerini zaten inceledik. ncelemediimiz yalnzca birka nemli metot (ve
nitelik) kald. Gelin isterseniz henz incelemediimiz bu nemli metot ve nitelikleri gzden
geirelim.

26.1 closed Nitelii

Bu nitelik, bir dosyann kapal olup olmadn sorgulamamz salar. Dosya adnn f olduunu
varsayarsak, bu nitelii yle kullanyoruz:
f.closed

Eer f adl bu dosya kapalysa True kts, aksa False kts verilecektir.

26.2 readable() Metodu

Bu metot bir dosyann okuma yetkisine sahip olup olmadn sorgulamamz salar. Eer bir
dosya r gibi bir kiple almsa, yani o dosya okunabilir zellikle ise bu metot bize True

419
Python 3 iin Trke Klavuz, Srm 3

kts verir. Ama eer dosya yazma kipinde almsa bu metot bize False kts verecektir.

26.3 writable() Metodu

Bu metot bir dosyann yazma yetkisine sahip olup olmadn sorgulamamz salar. Eer bir
dosya w gibi bir kiple almsa, yani o dosya yazlabilir zellikle ise bu metot bize True
kts verir. Ama eer dosya okuma kipinde almsa bu metot bize False kts verecektir.

26.4 truncate() Metodu

Bu metot, henz ilemediimiz metotlar arasnda en nemlilerinden biridir. Bu metot


yardmyla dosyalarmz istediimiz boyuta getirebiliyoruz.
ngilizcede truncate kelimesi budamak, krpmak gibi anlamlara gelir. Bu metodun yapt i
de bu anlamyla uyumludur. Bu metodu temel olarak yle kullanyoruz:
>>> with open("falanca.txt", "r+") as f:
... f.truncate()

Bu komutu bu ekilde kullandmzda dosyann btn ierii silinecektir. Yani bu kodlar,


sanki dosyay w kipiyle amsnz gibi bir etki ortaya karacaktr.
truncate() metodu yukarda grdnz ekilde parametresiz olarak kullanlabilecei gibi,
parametreli olarak da kullanlabilir. Bu metodun parantezleri arasna, dosyann ka baytlk
bir boyuta sahip olmasn istediinizi yazabilirsiniz. rnein:
>>> with open("falanca.txt", "r+") as f:
... f.truncate(10)

Bu kodlar, falanca.txt adl dosyann ilk 10 bayt dndaki btn verileri siler. Yani dosyay
yalnzca 10 baytlk bir boyuta sahip olacak ekilde krpar.
Gelin isterseniz bu metotla ilgili bir rnek verelim. Elimizdeki dosyann u ierie sahip
olduunu varsayalm:

Ahmet zbudak : 0533 123 23 34


Mehmet Sln : 0532 212 22 22
Sami Sam : 0542 333 34 34

Amacmz dosyadaki u iki satr tamamen silmek:


Mehmet Sln : 0532 212 22 22
Sami Sam : 0542 333 34 34

Yani dosyann yeni ieriinin tam olarak yle olmasn istiyoruz:

Ahmet zbudak : 0533 123 23 34

Bunun iin truncate() metodundan yararlanarak u kodlar yazabiliriz:


with open("fihrist.txt", "r+") as f:
f.readline()
f.seek(f.tell())
f.truncate()

420 Blm 26. Dosyalarn Metot ve Nitelikleri


Python 3 iin Trke Klavuz, Srm 3

Bu kodlar bir dosyaya kaydedip altrdnzda, istediiniz sonucu elde ettiinizi


greceksiniz.
Burada srasyla u ilemleri gerekletirdik:
1. nce dosyamz hem okuma hem de yazma kipinde atk. nk ayn dosya zerinde
hem okuma hem de yazma ilemleri gerekletireceiz:
with open("fihrist.txt", "r+") as f:

2. Ardndan dosyadan tek bir satr okuduk:


f.readline()

3. Daha sonra, truncate() metodunun imle konumundan itibaren krpma ilemi


gerekletirebilmesi iin imleci dosya iinde o anda bulunduumuz konuma, yani ikinci
satrn bana getirdik. Bildiiniz gibi dosyalarn tell() metodu, o anda dosya iinde
hangi konumda bulunduumuzu bildiriyor. Biz biraz nce yazdmz readline()
komutu yardmyla dosyadan bir satr okuduumuz iin, o anda ikinci satrn banda
bulunuyoruz. te seek() metodunu ve tell() metodundan elde ettiimiz bu konum
bilgisini kullanarak imleci istediimiz konuma getirdik:
f.seek(f.tell())

4. mleci istediimiz konuma getirdiimize gre artk krpma ilemini gerekletirebiliriz:


f.truncate()

Artk elimizde tek satrlk bir dosya var...


truncate() metodunun, yukarda anlattmzdan farkl bir zellii daha var. Her ne kadar
truncate kelimesi krpmak anlamna gelse ve bu metotla dosya boyutlarn kltebilsek bile,
bu metodu kullanarak ayn zamanda dosya boyutlarn artrabiliriz de. rnein boyutu 1
kilobayt olan bir dosyay 3 kilobayta karmak iin bu metodu yle kullanabiliriz:
>>> f = open("fihrist.txt", "r+")
>>> f.truncate(1024*3)
>>> f.close()

Dosyann boyutunu kontrol edecek olursanz, dosyann gerekten de 3 kilobayta ktn


greceksiniz. Peki bu metot bu ii nasl yapyor? Aslnda bunun cevab ok basit: Dosyann
sonuna gereken miktarda 0 ekleyerek... Zaten eer hrist.txt adl bu dosyay tekrar ap
okursanz bu durumu kendiniz de grebilirsiniz:
>>> f = open("fihrist.txt")
>>> f.read()

Grdnz gibi, dosya sfrlarla dolu.

26.5 mode Nitelii

Bu nitelik, bize bir dosyann hangi kipte aldna dair bilgi verir:
>>> f = open("falanca.txt")
>>> f.mode

26.5. mode Nitelii 421


Python 3 iin Trke Klavuz, Srm 3

'r'

Demek ki bu dosya r kipinde alm...

26.6 name Nitelii

Bu nitelik, bize bir dosyann adn verir:


>>> f.name

'falanca.txt'

26.7 encoding Nitelii

Bu nitelik, bize bir dosyann hangi dil kodlamas ile kodlandn syler:
>>> f.encoding

'utf-8'

veya:
>>> f.encoding

'cp1254' #Windows

Not: Bu dil kodlamas konusunu ilerleyen sayfalarda ayrntl olarak inceleyeceiz.

Bylece dosyalarn en nemli metot ve niteliklerini incelemi olduk. Bu arada, gerek


bu derste, gerekse nceki derslerde verdiimiz rneklerden, metot ile nitelik kavramlar
arasndaki fark anladnz zannediyorum. Metotlar bir i yaparken, nitelikler bir deer
gsterir. Nitelikler basit birer deikenden ibarettir. Metotlar ise bir iin nasl yaplaca
ile ilgili sreci tanmlar. Esasnda bu ikisi arasndaki farklar ok fazla kafaya takmanza gerek
yok. Zamanla (zellikle de baka programlarn kaynak kodlarn incelemeye baladnzda) bu
ikisi arasndaki fark bariz bir biimde greceksiniz. O noktaya geldiinizde, zaten kavramlar
arasndaki farklar grmeniz konusunda biz de size yardmc olmaya alacaz.

422 Blm 26. Dosyalarn Metot ve Nitelikleri


BLM 27

kili (Binary ) Dosyalar

Dosyalar ounlukla iki farkl snfa ayrlr: Metin dosyalar ve ikili dosyalar. Metin dosyalar
derken neyi kastettiimiz az ok anlalyor. Eer bir dosyay bir metin dzenleyici ile
atnzda herhangi bir dilde yazlm okunabilir bir metin gryorsanz, o dosya bir metin
dosyasdr. Mesela Notepad, Gedit, Kwrite veya benzeri metin dzenleyicileri kullanarak
oluturduunuz dosyalar birer metin dosyasdr. imdiye kadar verdiimiz btn rnekler
metin dosyalarn ieriyordu. Peki ikili (binary ) dosya ne demek?
kili dosyalar ise, metin dosyalarnn aksine, metin dzenleyicilerle alamayan, almaya
alldnda ise ounlukla anlamsz karakterler ieren bir dosya trdr. Resim dosyalar,
mzik dosyalar, video dosyalar, MS Oce dosyalar, LibreOce dosyalar, OpenOce
dosyalar, vb. ikili dosyalara rnektir.
nceki blmlerde de ifade ettiimiz gibi, bilgisayarlar yalnzca saylarla ilem yapabilir.
Bilgisayarlarn zerinde ilem yapabildii bu saylarn 0 ve 1 adl iki say olduunu biliyoruz.
Peki bu iki farkl sayy kullanarak neler yapabiliriz? Aslnda, bu iki farkl sayy kullanarak her
trl ilemi yapabiliriz: Basit veya karmak aritmetik hesaplamalar, metin dzenleme, resim
veya video dzenleme, web siteleri hazrlama, uzaya mekik gnderme... Btn bu ilemleri
sadece iki farkl say kullanarak yapabiliriz. Daha dorusu bilgisayarlar yapabilir.
Durum byle olmasna ramen, ilk bilgisayarlar yalnzca hesaplama ilemleri iin
kullanlyordu. Yani metin ieren ilemleri yapmak bilgisayarlarn deil, mesela daktilolarn
grevi olarak grlyordu. Bu durumu telefon teknolojisi ile kyaslayabilirsiniz. Bildiiniz gibi,
ilk telefonlar yalnzca iki kii arasndaki sesli iletiimi salamak iin kullanlyordu. Ama yeni
nesil telefonlar artk ikiden fazla kii arasndaki sesli ve grntl iletiimi salayabilmenin
yansra, nceleri birbirinden farkl cihazlarla gerekletirilen ilemleri artk tek bana yerine
getirebiliyor.
lk bilgisayarlarda ise metinlerin, daha dorusu karakterlerin grevi bir hayli snrlyd.
Bata da sylediimiz gibi, ounlukla dosyalar iki farkl snfa ayrlr: Metin dosyalar ve
ikili dosyalar. Ama iin asl sadece tek bir dosya tr vardr: kili dosyalar (binary les ).
Yani bilgisayarlar asndan btn dosyalar, ilerinde ne olursa olsun, birer ikili dosyadr ve
ilerinde sadece 0lar ve 1leri barndrr. te bu 0 ve 1lerin ne anlama geleceini, iletim
sistemleri ve bu sistemler zerine kurulu yazlmlar belirler. Eer bir dosya metin dosyasysa
bu dosyadaki 0 ve 1ler birer karakter/harf olarak yorumlanr. Ama eer dosya bir ikili
dosyaysa dosya iindeki 0 ve 1ler zel birtakm veriler olarak ele alnr ve bu verileri okuyan
yazlma gre deer kazanr. rnein eer ilgili dosya bir resim dosyasyla, bu dosya herhangi
bir resim grntleyici yazlm ile aldnda karmza bir resim kar. Eer ilgili dosya bir
video dosyasyla, bu dosya bir video grntleyici yazlm ile aldnda karmza bir video
kar. Bu olgudan bir sonraki blmde daha ayrntl olarak sz edeceiz. Biz imdilik iin

423
Python 3 iin Trke Klavuz, Srm 3

sadece pratiine younlaalm ve temel olarak iki farkl dosya eidi olduunu varsayalm:
Metin dosyalar ve ikili dosyalar.
Buraya gelene kadar hep metin dosyalarndan sz etmitik. imdi ise ikili dosyalardan sz
edeceiz.
Hatrlarsanz metin dosyalarn amak iin temel olarak yle bir komut kullanyorduk:
f = open(dosya_ad, 'r')

Bu ekilde bir metin dosyasn okuma kipinde am oluyoruz. Bir metin dosyasn deil de,
ikili bir dosyay amak iin ise u komutu kullanacaz:
f = open(dosya_ad, 'rb')

Dosyaya erime kiplerini gsterdiimiz tabloda ikili eriim trlerini de verdiimizi


hatrlyorsunuz.
Peki neden metin dosyalar ve ikili dosyalar iin farkl eriim kipleri kullanyoruz?
letim sistemleri satr sonlar iin birbirinden farkl karakterler kullanrlar. rnein
GNU/Linux datmlarnda satr sonlar \n karakteri ile gsterilir. Windows iletim sistemi
ise satr sonlarn \r\n karakterleriyle gsterir. te Python herhangi bir dosyay aarken,
eer o dosya bir metin dosyas ise, satr sonlarn gsteren karakterleri, dosyann ald
iletim sistemine gre ayarlar. Yani satr sonlarn standart bir hale getirerek \n karakterine
dntrr.
Metin dosyalar ile ikili dosyalar arasnda nemli bir fark bulunur: Bir metin dosyasndaki
ufak deiiklikler dosyann okunamaz hale gelmesine yol amaz. Olabilecek en kt ey,
deitirilen karakterin okunamaz hale gelmesidir. Ancak ikili dosyalarda ufak deiiklikler
dosyann tmden bozulmasna yol aabilir. Dolaysyla Pythonn yukarda bahsedilen satr
sonu deiiklikleri ikili dosyalarn bozulmasna yol aabilir. Yani eer siz ikili bir dosyay
rb yerine sadece r gibi bir kiple aarsanz dosyann bozulmasna yol aabilirsiniz. kili bir
dosyay rb (veya wb, ab, xb, vb.) gibi bir kipte atnzda Python satr sonlarna herhangi
bir deitirme-dntrme ilemi uygulamaz. Bylece dosya bozulma riskiyle kar karya
kalmaz. O yzden, metin dosyalarn ve ikili dosyalar aarken farkl kipler kullanmamz
gerektiine dikkat ediyoruz.

27.1 kili Dosyalarla rnekler

Gelin isterseniz bu noktada birka rnek verelim.

27.1.1 PDF Dosyalarndan Bilgi Alma

Tpk resim, mzik ve video dosyalar gibi, PDF dosyalar da birer ikili dosyadr. O halde
hemen nmze bir PDF dosyas alalm ve bu dosyay okuma kipinde aalm:
>>> f = open("falanca.pdf", "rb")

imdi de bu dosyadan 10 baytlk bir veri okuyalm:


>>> f.read(10)

b'%PDF-1.3\n4'

424 Blm 27. kili (Binary ) Dosyalar


Python 3 iin Trke Klavuz, Srm 3

Bu ktda grdnz b iaretine imdilik taklmayn. Birazdan bunun ne olduunu btn


ayrntlaryla anlatacaz. Biz bu harn, elimizdeki verinin bayt trnde bir veri olduunu
gsteren bir iaret olduunu bilelim yeter.
Grdnz gibi, bir PDF dosyasnn ilk birka baytn okuyarak hem dosyann bir PDF
belgesi olduunu teyit edebiliyoruz, hem de bu PDF belgesinin, hangi PDF srm ile
oluturulduunu anlayabiliyoruz. Buna gre bu belge PDF talimatnamesinin 1.3 numaral
srm ile oluturulmu.
Eer biz bu belgeyi bir ikili dosya olarak deil de bir metin dosyas olarak amaya alsaydk
yle bir hata alacaktk:
>>> f = open("falanca.pdf")
>>> okunan = f.read()

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
File "C:\Python33\lib\encodings\cp1254.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 527: char
acter maps to <undefined>

Pythonn bu dosyann bir ikili dosya olduu konusunda bilgilendirerek, dosyann dzgn bir
ekilde alp okunabilmesini salyoruz.
Gelin bu PDF belgesi zerinde biraz daha alalm.
PDF belgelerinde, o belge hakknda baz nemli bilgiler veren birtakm zel etiketler bulunur.
Bu etiketler unlardr:
Etiket Anlam
/Creator Belgeyi oluturan yazlm
/Producer Belgeyi PDFe eviren yazlm
/Title Belgenin bal
/Author Belgenin yazar
/Subject Belgenin konusu
/Keywords Belgenin anahtar kelimeleri
/CreationDate Belgenin oluturulma zaman
/ModDate Belgenin deitirilme zaman
Bu etiketlerin tamam btn PDF dosyalarnda tanml deildir. Ama zellikle /Producer
etiketi her PDF dosyasnda bulunur.
imdi rnek olmas bakmndan elimize bir PDF dosyas alalm ve bunu gzelce okuyalm:
>>> f = open("falanca.pdf", "rb")
>>> okunan = f.read()

imdi de /Producer ifadesinin dosya iinde getii noktann sra numarasn bulalm.
Bildiiniz gibi, dosyalarn read() metodu bize bir karakter dizisi verir. Yine bildiiniz gibi,
karakter dizilerinin index() metodu yardmyla bir enin karakter dizisi iinde getii noktay
bulabiliyoruz. Yani:
>>> producer_index = okunan.index(b"/Producer")

Burada /Producer ifadesinin bana b harni yerletirmeyi unutmuyoruz. nk u anda


yaptmz ilem ikili bir dosya iinde geen birtakm baytlar arama ilemidir.

27.1. kili Dosyalarla rnekler 425


Python 3 iin Trke Klavuz, Srm 3

producer_index deikeni, /Producer ifadesinin ilk baytnn dosya iindeki konumunu


tutuyor. Kontrol edelim:
>>> producer_index

4077883

Bu deerin gerekten de /Producer ifadesinin ilk baytn depoladn teyit edelim:


>>> okunan[producer_index]

47

Daha nce de dediimiz gibi, bilgisayarlar yalnzca saylar grr. Bu saynn hangi karaktere
karlk geldiini bulmak iin chr() fonksiyonundan yararlanabilirsiniz:
>>> chr(okunan[producer_index])

'/'

Grdnz gibi, gerekten de producer_index deikeni /Producer ifadesinin ilk baytnn


dosya iindeki konumunu gsteriyor. Biz bu konumu ve bu konumun 50-60 bayt tesini
sorgularsak, PDF belgesini reten yazlmn adna ulaabiliriz. Dikkatlice bakn:
>>> okunan[producer_index:producer_index+50]

b'/Producer (Acrobat Distiller 2.0 for Macintosh)\r/T'

Hatta eer bu kt zerine split() metodunu uygularsak, kty daha kullanl bir hale
getirebiliriz:
>>> producer = okunan[producer_index:producer_index+50].split()
>>> producer

[b'/Producer', b'(Acrobat', b'Distiller', b'2.0', b'for', b'Macintosh)', b'/T']

Bu ekilde, ihtiyacmz olan bilginin istediimiz parasna kolayca ulaabiliriz:


>>> producer[0]

b'/Producer'

>>> producer[1]

b'(Acrobat'

>>> producer[1:3]

[b'(Acrobat', b'Distiller']

Elbette bu yntem, bir PDF dosyasndan gerekli etiketleri almann en iyi yntemi deildir.
Ama henz Python bilgimiz bu kadarn yapmamza msaade ediyor. Ancak yine de, yukarda
rnek, bir ikili dosyadan nasl veri alnaca konusunda size iyi bir kir verecektir.

426 Blm 27. kili (Binary ) Dosyalar


Python 3 iin Trke Klavuz, Srm 3

27.1.2 Resim Dosyalarnn Trn Tespit Etme

Dediimiz gibi, resim dosyalar, mzik dosyalar, video dosyalar ve benzeri dosyalar birer
ikili dosyadr. Mesela resim dosyalarn ele alalm. Diyelim ki, resimlerin hangi trde
olduunu tespit eden bir program yazmak istiyorsunuz. Yani yazdnz bu programla bir
resim dosyasnn PNG mi, JPEG mi, TIFF mi, yoksa BMP mi olduunu anlamak istiyorsunuz.
Peki bir resim dosyasnn hangi trde olduunu bulmak iin uzantsna baksanz olmaz m?
Asla unutmayn dosya uzantlar ile dosya biimleri arasnda dorudan bir balant yoktur.
O yzden dosya uzantlar, dosya biimini anlamak asndan gvenilir bir yntem deildir.
Bir resim dosyasnn sonuna hangi uzanty getirirseniz getirin, o dosya bir resim dosyasdr.
Yani mesela bir resim dosyasnn uzants yanllkla veya bilerek .doc olarak deitirilmise,
o dosya bir WORD dosyas haline gelmez. te yazacanz program, bir resim dosyasnn
uzants ne olursa olsun, hatta dosyann bir uzants olmasa bile, o dosyann hangi trde
olduunu syleyebilecek.
Bir resim dosyasnn hangi trde olduunu anlayabilmek iin ilgili dosyann ilk birka
baytn okumanz yeterlidir. Bu birka bayt iinde o resim dosyasnn trne dair bilgileri
bulabilirsiniz.
Resim dosyalarnn trlerini birbirinden ayrt etmenizi salayacak verilerin ne olduunu,
ilgili resim trnn teknik artnamesine bakarak renebilirsiniz. Ancak teknik artnameler
genellikle okumas zor metinlerdir. Bu yzden, dorudan artnameyi okumak yerine, Internet
zerinde ksa bir aratrma yaparak konuyu daha kolay anlamanz salayacak yardmc
belgelerden de yardm alabilirsiniz.

JPEG

JPEG biimi ile ilgili bilgileri http://www.jpeg.org adresinde bulabilirsiniz. JPEG dosya biimini
daha iyi anlamanz salayacak yardmc kaynak ise udur:
1. http://www.faqs.org/faqs/jpeg-faq/part1/section-15.html
Yukarda verdiimiz adreslerdeki bilgilere gre bir JPEG dosyasnn en banda u veriler
bulunur:
FF D8 FF E0 ? ? 4A 46 49 46 00

Ancak eer ilgili JPEG dosyas bir CANON fotograf makinesi ile oluturulmusa bu veri dizisi
yle de olabilir:
FF D8 FF E0 ? ? 45 78 69 66 00

Burada soru iareti ile gsterdiimiz ksm, yani dosyann 5. ve 6. baytlar farkl
JPEG dosyalarnda birbirinden farkl olabilir. Dolaysyla bir JPEG dosyasn baka resim
dosyalarndan ayrabilmek iin dosyann ilk drt baytna bakmamz, sonraki iki bayt
atlamamz ve bunlardan sonra gelen be bayt kontrol etmemiz yeterli olacaktr.
Yukarda grdkleriniz birer on altl (hex ) saydr. Bunlar onlu dzende srasyla u saylara
karlk gelir:
255 216 255 224 ? ? 74 70 73 70 0
255 216 255 224 ? ? 45 78 69 66 0 #canon

Bu diziler iinde zellikle u drt say bizi yakndan ilgilendiriyor:

27.1. kili Dosyalarla rnekler 427


Python 3 iin Trke Klavuz, Srm 3

74 70 73 70
45 78 69 66 #canon

Bu saylar srasyla J, F, I, F ve E, x, i, f harerine karlk gelir. Yani bir JPEG dosyasn


ayrt edebilmek iin ilgili dosyann 7-10 aras baytlarnn ne olduuna bakmamz yeterli
olacaktr. Eer bu aralkta JFIF veya Exif ifadeleri varsa, o dosya bir JPEG dosyasdr. Buna
gre yle bir kod yazabiliriz:
f = open(dosya_ad, 'rb')
data = f.read(10)
if data[6:11] in [b"JFIF", b"Exif"]:
print("Bu dosya JPEG!")
else:
print("Bu dosya JPEG deil!")

Burada herhangi bir resim dosyasnn ilk on baytn okuduk ncelikle:


data = f.read(10)

nk aradmz bilgiler ilk on bayt iinde yer alyor.


Daha sonra okuduumuz ksmn 7 ila 10. baytlar arasnda kalan verinin ne olduuna
bakyoruz:
if data[6:11] in [b"JFIF", b"Exif"]:
...

Eer ilgili aralkta JFIF veya Exif baytlar yer alyorsa bu dosyann bir JPEG dosyas olduuna
karar veriyoruz.
Yukardaki kodlar elinizdeki bir JPEG dosyasna uygulayarak kendi kendinize pratik
yapabilirsiniz.
Mesela benim elimde d1.jpg, d2.jpg ve d3.jpeg adl farkl JPEG dosyas var:
dosyalar = ["d1.jpg", "d2.jpg", "d3.jpeg"]

Bu dosyalarn ilk onar baytn okuyorum:


for f in dosyalar:
okunan = open(f, 'rb').read(10)
print(okunan)

Buradan u kty alyorum:


d1.jpg b'\xff\xd8\xff\xe0\x00\x10JFIF'
d2.jpg b'\xff\xd8\xff\xe1T\xaaExif'
d3.jpeg b'\xff\xd8\xff\xe0\x00\x10JFIF'

Grdnz gibi bu ktlar yukarda JPEG dosyalarna ilikin olarak verdiimiz bayt dizilimi
ile uyuuyor. Mesela ilk dosyay ele alalm:
d1.jpg b'\xff\xd8\xff\xe0\x00\x10JFIF'

Burada u baytlar var:


\xff \xd8 \xff \xe0 \x00 \x10 J F I F

428 Blm 27. kili (Binary ) Dosyalar


Python 3 iin Trke Klavuz, Srm 3

Saylarn bandaki \x iaretleri bunlarn birer on altl say olduunu gsteren bir iarettir.
Dolaysyla yukardakileri daha net inceleyebilmek iin yle de yazabiliriz:
ff d8 ff e0 00 10 J F I F

imdi de ikinci dosyann ktsn ele alalm:


d2.jpg b'\xff\xd8\xff\xe1T\xaaExif'

Burada da u baytlar var:


ff d8 ff e1T aa E x i f

te dosyalarn trn ayrt etmek iin bu ktlardaki son drt bayt kontrol etmemiz yeterli
olacaktr:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("Evet {} adl dosya bir JPEG!".format(f))
else:
print("{} JPEG deil!".format(f))

Bu kodlar elinizde bulunan farkl trdeki dosyalara uygulayarak, aldnz ktlar


inceleyebilirsiniz.

PNG

PNG dosya biiminin teknik artnamesine http://www.libpng.org/pub/png/spec/ adresinden


ulaabilirsiniz.
Ayrca yardmc kaynak olarak da http://www.leformat.info/format/png/egff.htm
adresindeki belgeyi kullanabilirsiniz.
artnamade, http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-le-signature
sayfasndaki bilgiye gre bir PNG dosyasnn ilk 8 bayt mutlaka aadaki deerleri ieriyor:
onlu deer 137 80 78 71 13 10 26 10
on altl deer 89 50 4e 47 0d 0a 1a 0a
karakter deeri \211 P N G \r \n \032 \n
imdi elimize herhangi bir PNG dosyas alarak bu durumu teyit edelim:
>>> f = open("falanca.png", "rb")

>>> okunan = f.read(8)

artnamede de sylendii gibi, bir PNG dosyasn teki trlerden ayrt edebilmek iin
dosyann ilk 8 baytna bakmamz yeterli olacaktr. O yzden biz de yukardaki kodlarda
sadece ilk 8 bayt okumakla yetindik.
Bakalm ilk 8 baytta neler varm:
>>> okunan

b'\x89PNG\r\n\x1a\n'

27.1. kili Dosyalarla rnekler 429


Python 3 iin Trke Klavuz, Srm 3

Bu deerin, artnamedeki karakter deeri ile ayn olup olmadn sorgulayarak herhangi bir
dosyann PNG olup olmadna karar verebilirsiniz:
>>> okunan == b"\211PNG\r\n\032\n"

True

Dolaysyla una benzer bir kod yazarak, farkl resim dosyalarnn trn tespit edebilirsiniz:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("{} adl dosya bir JPEG!".format(f))
elif okunan[:8] == b"\211PNG\r\n\032\n":
print("{} adl dosya bir PNG!".format(f))
else:
print("Tr bilinmeyen dosya: {}".format(f))

Bu kodlarda bir resim dosyasnn ilk 10 baytn okuduk. 7-11 aras baytlarn iinde JFIF veya
Exif baytlar varsa o dosyann bir JPEG olduuna; ilk 8 bayt b211PNGrn032n adl bayt
dizisine eitse de o dosyann bir PNG olduuna karar veriyoruz.

GIF

GIF artnamesine http://www.w3.org/Graphics/GIF/spec-gif89a.txt adresinden


ulaabilirsiniz.
Bir dosyann GIF olup olmadna karar verebilmek iin ilk 3 baytn okumanz yeterli
olacaktr. Standart bir GIF dosyasnn ilk bayt G, I ve F karakterlerinden oluur.
Dosyann sonraki 3 bayt ise GIF in srm numarasn verir. 20.04.2016 itibariyle GIF
standardnn u srmleri bulunmaktadr:
1. 87a - Mays 1987
2. 89a - Temmuz 1989
Dolaysyla standart bir GIF dosyasnn ilk 6 bayt yledir:
GIF87a veya GIF89a
Eer bir dosyann GIF olup olmadn anlamak isterseniz dosyann ilk 3 veya 6 baytn
denetlemeniz yeterli olacaktr:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("{} adl dosya bir JPEG!".format(f))
elif okunan[:8] == b"\211PNG\r\n\032\n":
print("{} adl dosya bir PNG!".format(f))
elif okunan[:3] == b'GIF':
print("{} adl dosya bir GIF!".format(f))
else:
print("Tr bilinmeyen dosya: {}".format(f))

430 Blm 27. kili (Binary ) Dosyalar


Python 3 iin Trke Klavuz, Srm 3

TIFF

TIFF artnamesine http://partners.adobe.com/public/developer/en/tiff/TIFF6.pdf adresinden


ulaabilirsiniz. Bu artnameye gre bir TIFF dosyas unlardan herhangi biri ile balar:
1. II
2. MM
Dolaysyla, bir TIFF dosyasn tespit edebilmek iin dosyann ilk 2 baytna bakmanz yeterli
olacaktr:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("{} adl dosya bir JPEG!".format(f))
elif okunan[:8] == b"\211PNG\r\n\032\n":
print("{} adl dosya bir PNG!".format(f))
elif okunan[:3] == b'GIF':
print("{} adl dosya bir GIF!".format(f))
elif okunan[:2] in [b'II', b'MM']:
print("{} adl dosya bir TIFF!".format(f))
else:
print("Tr bilinmeyen dosya: {}".format(f))

BMP

BMP trndeki resim dosyalarna ilikin bilgi iin http://www.digitalpreservation.gov/formats/fdd/fdd000189


adresine bavurabilirsiniz.
Buna gre, BMP dosyalar BM ile balar. Yani:
for f in dosyalar:
okunan = open(f, 'rb').read(10)
if okunan[6:11] in [b'JFIF', b'Exif']:
print("{} adl dosya bir JPEG!".format(f))
elif okunan[:8] == b"\211PNG\r\n\032\n":
print("{} adl dosya bir PNG!".format(f))
elif okunan[:3] == b'GIF':
print("{} adl dosya bir GIF!".format(f))
elif okunan[:2] in [b'II', b'MM']:
print("{} adl dosya bir TIFF!".format(f))
elif okunan[:2] in [b'BM']:
print("{} adl dosya bir BMP!".format(f))
else:
print("Tr bilinmeyen dosya: {}".format(f))

Grdnz gibi ikili dosyalar, baytlarn zel bir ekilde dizildii ve zel bir ekilde
yorumland bir dosya trdr. Dolaysyla ikili dosyalarla alabilmek iin, ikili dosyann
bayt dizilimini yakndan tanmak gerekiyor.

27.1. kili Dosyalarla rnekler 431


BLM 28

Basit bir letiim Modeli

Bu blmde, bilgisayarlarn alma mantn, verileri nasl ilediini, saylarla karakter


dizilerini nasl temsil ettiini daha iyi ve daha net bir ekilde anlayabilmek iin basit bir iletiim
modeli kuracaz.
imdi yle bir durum hayal edin: Diyelim ki, hatlar zerinden iletilen elektrik akm yoluyla
bir arkadanzla haberlemenizi salayacak bir sistem tasarlyorsunuz. Bu sistem, verici
tarafnda elektrik akmnn gnderilmesini salayan bir anahtardan, alc tarafnda ise, gelen
akmn iddetine gre lo veya parlak k veren bir ampulden oluuyor. Eer vericiden
gnderilen elektrik akm dkse alc lo bir k, eer gelen akm yksekse alc parlak bir
k grecek. Elbette eer isterseniz dk akm-yksek akm kartl yerine akm varl-akm
yokluu kartln da kullanabilirsiniz. Bylece vericiden akm gnderildiinde ampul yanar,
gnderilmediinde ise sner. Bana dk akm-yksek akm kartl daha kullanl geldii
iin byle tercih ettim. Siz tabii ki br trlsn de tercih edebilirsiniz.
Yukarda bahsedildii gibi sistemimizi kurduk diyelim. Peki ama bu sistem verici ile alc
arasnda basit de olsa bir iletiim kurmamz nasl olacak da salayacak?
Aslnda bunun cevab ve mant ok basit. Grdnz gibi, bu sistemde iki farkl durum sz
konusu: Lo k ve parlak k (veya yanan ampul ve snm ampul).
Bu ikili yapy, tahmin edebileceiniz gibi, ikili (binary ) sayma sistemi araclyla rahatlkla
temsil edebiliriz. Mesela lo k durumuna 0, parlak k durumuna ise 1 diyebiliriz.
Dolaysyla verici, ampuln lo k vermesini salayacak dk bir akm gnderdiinde bunun
deerini 0, ampuln yksek k vermesini salayacak yksek bir akm gnderdiinde ise
bunun deerini 1 olarak deerlendirebiliriz.
Burada yaptmz dntrme ilemine teknik olarak kodlama (encoding ) ad verilir. Bu
kodlama sistemine gre biz, iki farkl elektrik akm deerini, yani lo k ve parlak k
deerlerini srasyla ikili sistemdeki 0 ve 1 saylar ile eletirip, lo a 0, parlak a ise
1 dedik.
Hemen anlayacanz gibi, bahsettiimiz bu hayali sistem, telgraf iletiimine ok benziyor.
te gerekte de kullanlan telgraf sistemine ok benzeyen bu basitletirilmi model bizim
bilgisayarlarn alma mantn da daha net bir ekilde anlamamz salayacak.

28.1 8 Bitlik bir Sistem

Hatrlarsanz ikili sayma sisteminde 0 lar ve 1 lerin oluturduu her bir basamaa bit adn
veriyorduk.

432
Python 3 iin Trke Klavuz, Srm 3

Not: Bit kelimesi ngilizcede binary (ikili) ve digit (rakam) kelimelerinin birletirilmesi ile
retilmitir.

Bu bilgiye gre mesela 0 says bir bitlik bir say iken, 1001 says drt bitlik bir saydr.
letiimimizi eksiksiz bir biimde salayabilmemiz, yani gereken btn karakterleri temsil
edebilmemiz iin, sistemimizin 8 hanelik bir say kapasitesine sahip olmas, yani teknik bir
dille ifade etmek gerekirse sistemimizin 8 bitlik olmas herhalde yeterli olacaktr.
8 bitlik bir iletiim sisteminde 10 a kadar u ekilde sayabiliriz:
>>> for i in range(10):
... print(bin(i)[2:].zfill(8))
...
00000000
00000001
00000010
00000011
00000100
00000101
00000110
00000111
00001000
00001001

Verici tarafndaki kii elindeki anahtar yardmyla farkl kuvvetlere sahip sinyalleri art arda
gndererek yukarda gsterildii gibi on farkl sayy alcya iletebilir. Sistemimizin 8 bitlik
olduunu dnrsek kar tarafa 0 says ile birlikte toplam 2 ** 8 = 256 farkl sinyal
gnderebiliriz:
>>> for i in range(256):
... print(bin(i)[2:].zfill(8))

00000000
00000001
00000010
00000011
00000100
...
...
...
11111001
11111010
11111011
11111100
11111101
11111110
11111111

Grdnz gibi, bizim 8 bitlik bu sistemle gnderebileceimiz son sinyal, yani say 255 tir.
Bu sistemle bundan byk bir sayy gnderemeyiz. Bu durumu kendi gzlerinizle grmek
iin u kodlar altrn:
>>> for i in range(256):
... print(bin(i)[2:], i.bit_length(), sep="\t")

Burada ilk stun 256 ya kadar olan saylarn ikili sistemdeki karlklarn, ikinci stun ise
bu saylarn bit uzunluunu gsteriyor. Bu kty incelediinizde de greceiniz gibi, 8 bit

28.1. 8 Bitlik bir Sistem 433


Python 3 iin Trke Klavuz, Srm 3

uzunlua sahip son say 255 tir. 256 says ise 9 bit uzunlua sahiptir. Yani 256 says
mecburen bizim sistemimizin dndadr:
>>> bin(255)[2:]

'11111111'

>>> (255).bit_length()

>>> bin(256)[2:]

'100000000'

>>> (256).bit_length()

Dediimiz gibi, bu sistemde elimizde toplam 8 bit var. Yani bu sistemi kullanarak 0 dan 256 ya
kadar sayp, bu saylar alcya iletebiliriz.
Peki verici ile alc arasnda birtakm saylar gnderip alabilmek ne iimize yarar? Yani bu i
neden bu kadar nemli?
Bu sorularn cevabn birazdan vereceiz, ama ondan nce daha nemli bir konuya deinelim.

28.2 Hata Kontrol

Buraya kadar her ey yolunda. Alc ve verici arasndaki iletiimi elektrik akm vastasyla,
8 bitlik bir sistem zerinden salayabiliyoruz. Ancak sistemimizin ok nemli bir eksii var.
Biz bu sistemde hibir hata kontrol yapmyoruz. Yani vericiden gelen mesajn doruluunu
test eden hibir ltmz yok. Zira alc ile verici arasnda gidip gelen veriler pek ok
farkl ekilde ve sebeple bozulmaya urayabilir. rnein, gnderilen veri alc tarafndan
doru anlalamayabilir veya elektrik sinyallerini ileten kablolardaki arzalar sinyallerin doru
iletilmesini engelleyebilir.
te btn bunlar hesaba katarak, iletiimin doru bir ekilde gerekleebilmesini salamak
amacyla sistemimiz iin basit bir hata kontrol sreci tasarlayalm.
Dediimiz gibi, elimizdeki sistem toplam 256 ya kadar saymamza olanak tanyor. nk
bizim sistemimiz 8 bitlik bir sistem. Bu sisteme bir hata kontrol mekanizmas ekleyebilmek
iin veri iletimini 8 bitten 7 bite ekeceiz. Yani iletiimimizi toplam 2 ** 7 = 127 say ile
snrlayacaz. Bota kalan 8. biti ise bahsettiimiz bu hata kontrol mekanizmasna ayracaz.
Peki hata kontrol mekanizmamz nasl ileyecek?
ok basit: Vericiden alcya ulaan verilerin tek mi yoksa ift mi olduuna bakacaz.
Buna gre sistemimiz yle alacak:
Diyelim ki verici alcya sinyaller araclyla u sayy gndermek istiyor:
0110111

434 Blm 28. Basit bir letiim Modeli


Python 3 iin Trke Klavuz, Srm 3

Bu arada, bunun 7 bitlik bir say olduuna dikkat edin. Dediimiz gibi, biz kontrol
mekanizmamz kurabilmek iin elimizdeki 8 bitlik kapasitenin 7 bitini kullanacaz. Bota
kalan 8. biti ise kontrol mekanizmasna tahsis edeceiz.
Ne diyorduk? Evet, biz kar tarafa 7 bitlik bir say olan 0110111 saysn gndermek istiyoruz.
Bu sayy gndermeden nce, iindeki 1 lerin miktarna bakarak bu saynn tek mi yoksa ift mi
olduuna karar verelim. Burada toplam be adet 1 says var. Yani bu say bir tek saydr. Eer
gndermek istediimiz say bir tek say ise, kar tarafa ulatnda da bir tek say olmaldr.
Biz bu sistem iin yle bir protokol tasarlayabiliriz:
Bu sistemde btn saylar kar tarafa bir tek say olarak iletilmelidir. Eer iletilen
saylar arasnda bir ift say varsa, o say hatal iletilmi veya iletim esnasnda
bozulmu demektir.
Peki biz iletilen btn saylarn bir tek say olmasn nasl salayacaz? te bu ilemi, boa
ayrdmz o 8. bit ile gerekletireceiz:
Eer kar tarafa iletilen bir say zaten tekse, o saynn bana 0 ekleyeceiz.
Bylece saynn teklik-iftlik durumu deimemi olacak. Ama eer iletilecek say
iftse, o saynn bana 1 ekleyeceiz. Bylece ift sayy, sistemimizin gerektirdii
ekilde, tek sayya evirmi olacaz.
rnek olarak 0110111 saysn verelim. Bu sayda toplam be adet 1 var. Yani bu say bir tek
say. Dolaysyla bu saynn bana bir adet 0 ekliyoruz:
0 0110111

Bylece saymzn teklik-iftlik durumu deimemi oluyor. Kar taraf bu sayy aldnda
1 lerin miktarna bakarak bu verinin doru iletildiinden emin oluyor.
Bir de u sayya bakalm:
1111011

Bu sayda toplam alt adet 1 says var. Yani bu say bir ift say. Bir saynn sistemimiz
tarafndan hatasz olarak kabul edilebilmesi iin bu saynn bir tek say olmas gerekiyor. Bu
yzden biz bu sayy tek sayya evirmek iin bana bir adet 1 say ekliyoruz:
1 1111011

Bylece saymzn iinde toplam yedi adet 1 says olmu ve bylece saymz tek sayya
dnm oluyor.
Teknik olarak ifade etmemiz gerekirse, yukarda yaptmz kontrol trne elik denetimi
(parity check ) ad verilir. Bu ilemi yapmamz salayan bite ise elik biti (parity bit ) denir.
ki tr elik denetimi bulunur:
1. Tek elik denetimi (odd parity check )
2. ift elik denetimi (even parity check )
Biz kendi sistemimizde hata kontrol mekanizmasn btn verilerin bir tek say olmas
gereklilii zerine kurduk. Yani burada bir tek elik denetimi gerekletirmi olduk. Elbette
btn verilerin bir ift say olmas gereklilii zerine de kurabilirdik bu sistemi. Yani isteseydik
ift elik denetimi de yapabilirdik. Bu tamamen bir tercih meselesidir. Bu tr sistemlerde
yaygn olarak tek elik denetimi kullanld iin biz de bunu tercih ettik.
Bu rneklerden de grdnz gibi, toplam 8 bitlik kapasitemizin 7 bitini veri aktarm iin,
kalan 1 bitini ise alnp verilen bu verilerin doruluunu denetlemek iin kullanyoruz. Elbette

28.2. Hata Kontrol 435


Python 3 iin Trke Klavuz, Srm 3

kullandmz hata kontrol mekanizmas epey zayf bir sistemdir. Ama, iletiim sistemleri
arasnda verilerin hatasz bir ekilde aktarlp aktarlamadn kontrol etmeye yarayan bir
sistem olan elik denetiminin, bugn bilgisayarn belleklerinde (RAM) dahi kullanlmaya
devam ettiini sylemeden gemeyelim...

28.3 Karakterlerin Temsili

Yukarda anlattklarmzdan da grdnz gibi, sistemimizi kullanarak 7 bit zerinden


toplam 127 say gnderebiliyoruz. Tabii ki sistemimiz 8 bit olduu iin 1 bit de bota kalyor.
te bota duran bu 1 biti ise elik denetimi iin kullanyoruz. Ama elbette alc ile verici
arasnda say alverii yapmak pek de heyecan uyandrc bir faaliyet deil. Kar tarafa saysal
mesajlar yerine birtakm szel mesajlar iletebilsek herhalde ok daha keyii olurdu...
unu asla unutmayn. Eer bir noktadan baka bir noktaya en az iki farkl sinyal yolu
ile birtakm saysal verileri gnderebiliyorsanz ayn ekilde szel verileri de rahatlkla
gnderebilirsiniz. Tpk dk voltaj ve yksek voltaj deerlerini srasyla 0 ve 1 saylar ile
temsil ettiiniz gibi, karakterleri de bu iki say ile temsil edebilirsiniz. Yapmanz gereken
tek ey hangi saylarn hangi karakterlere karlk geleceini belirlemekten ibarettir. Mesela
elimizde saylarla karakterleri eletiren yle bir tablo olduunu varsayalm:
say karakter say karakter say karakter say karakter
0 a 1 b 10 c 11 d
100 e 101 f 110 g 111 h
1000 i 1001 j 1010 k 1011 l
1100 m 1101 n 1110 o 1111 p
10000 q 10001 r 10010 s 10011 t
10100 u 10101 v 10110 w 10111 x
11000 y 11001 z 11010 A 11011 B
11100 C 11101 D 11110 E 11111 F
100000 G 100001 H 100010 I 100011 J
100100 K 100101 L 100110 M 100111 N
101000 O 101001 P 101010 Q 101011 R
101100 S 101101 T 101110 U 101111 V
110000 W 110001 X 110010 Y 110011 Z
Bu tabloda toplam 52 karakter ile 52 say birbiriyle eletirilmi durumda. Mesela vericiden
0 sinyali geldiinde bu tabloya gre biz bunu a har olarak yorumlayacaz. rnein kar
tarafa python mesajn iletmek iin srasyla u sinyalleri gndereceiz:
1111, 11000, 10011, 111, 1110, 1101

Grdnz gibi, elimizdeki 127 saynn 52sini harere ayrdk ve elimizde 75 tane daha say
kald. Eer isterseniz geri kalan bu saylar da birtakm baka karakterlere veya iaretlere
ayrarak, alc ve verici arasndaki btn iletiimin eksiksiz bir ekilde gereklemesini
salayabilirsiniz. rnein yle bir tablo oluturabilirsiniz:

436 Blm 28. Basit bir letiim Modeli


Python 3 iin Trke Klavuz, Srm 3

say karakter say karakter say karakter say karakter


0 0 1 1 10 2 11 3
100 4 101 5 110 6 111 7
1000 8 1001 9 1010 a 1011 b
1100 c 1101 d 1110 e 1111 f
10000 g 10001 h 10010 i 10011 j
10100 k 10101 l 10110 m 10111 n
11000 o 11001 p 11010 q 11011 r
11100 s 11101 t 11110 u 11111 v
100000 w 100001 x 100010 y 100011 z
100100 A 100101 B 100110 C 100111 D
101000 E 101001 F 101010 G 101011 H
101100 I 101101 J 101110 K 101111 L
110000 M 110001 N 110010 O 110011 P
110100 Q 110101 R 110110 S 110111 T
111000 U 111001 V 111010 W 111011 X
111100 Y 111101 Z 111110 ! 111111
1000000 # 1000001 $ 1000010 % 1000011 &
1000100 1000101 ( 1000110 ) 1000111 *
1001000 + 1001001 , 1001010 - 1001011 .
1001100 / 1001101 : 1001110 ; 1001111 <
1010000 = 1010001 > 1010010 ? 1010011 @
1010100 [ 1010101 \ 1010110 ] 1010111 ^
1011000 _ 1011001 1011010 { 1011011
1011100 } 1011101 ~ 1011110 1011111 t
1100000 n 1100001 r 1100010 x0b 1100011 x0c
Aslnda yukarda anlattmz say-karakter eletirme ileminin, ta en bata yaptmz
sinyal-say eletirme ilemiyle mantk olarak ayn olduuna dikkatinizi ekmek isterim.
Sistemimizi tasarlarken, iletilen iki farkl sinyali 0 ve 1 saylar ile temsil etmitik. Yani bu
sinyalleri 0 ve 1 ler halinde kodlamtk. imdi ise bu saylar karakterlere dntryoruz.
Yani yine bir kodlama (encoding ) ilemi gerekletiriyoruz.
Batan beri anlattmz bu kk iletiim modeli, saylarn ve karakterlerin nasl temsil
edilebilecei konusunda bize epey bilgi verdi. Bu arada, yukarda anlattmz sistem
her ne kadar hayali de olsa, bu sisteme benzeyen sistemlerin tarih boyunca kullanldn
ve hatta bugn kullandmz btn iletiim sistemlerinin de yukarda anlattmz temel
zerinde ekillendiini belirtmeden gemeyelim. rnein telgraf iletiiminde kullanlan Mors
alfabesi yukarda tarif ettiimiz sisteme ok benzer. Mors alfabesi, ksa ve uzun sinyallerle
karakterlerin eletirilmesi yoluyla oluturulmutur. Mors sisteminde farkl sinyaller (tpk
bizim sistemimizde olduu gibi) farkl harere karlk gelir:

28.3. Karakterlerin Temsili 437


Python 3 iin Trke Klavuz, Srm 3

Mors alfabesinin bizim oluturduumuz sisteme mantk olarak ne kadar benzediine dikkat
edin. Bu sistemin benzeri biraz sonra gstereceimiz gibi, modern bilgisayarlarda da
kullanlmaktadr.

438 Blm 28. Basit bir letiim Modeli


BLM 29

Karakter Kodlama (Character Encoding )

Bu blme gelinceye kadar Python programlama dilindeki karakter dizisi, liste ve dosya adl
veri tiplerine ilikin epey sz syledik. Artk bu veri tiplerine dair hemen hemen btn
ayrntlar biliyoruz. Ancak henz renmediimiz, ama programclk maceramz asndan
mutlaka renmemiz gereken ok nemli bir konu daha var. Bu nemli konunun ad, karakter
kodlama.
Bu blmde karakter kodlama adl hayati konuyu ilemenin yansra, son birka blmde
stnkr bir ekilde zerinden getiimiz, ama derinlemesine incelemeye pek frsat
bulamadmz btn konular da ele almaya alacaz. Bu konuyu bitirdikten sonra,
nceki konular alrken zihninizde olumu olabilecek boluklarn pek ounun dolduunu
farkedeceksiniz. Szn z, bu blmde hem yeni eyler syleyeceiz, hem de halihazrda
rendiimiz eylerin bir kez daha zerinden geerek bunlarn zihnimizde iyiden iyine
pekimesini salayacaz.
Hatrlarsanz nceki derslerimizde karakter dizilerinin encode() adl bir metodu olduundan
sz etmitik. Ayn ekilde, dosyalarn da encoding adl bir parametresi olduunu sylemitik.
Ayrca bu encoding konusu, ilk derslerimizde metin dzenleyici ayarlarn anlatrken de
karmza kmt. Orada, yazdmz programlarda zellikle Trke karakterlerin dzgn
grnebilmesi iin, kullandmz metin dzenleyicinin dil kodlamas (encoding ) ayarlarn
dzgn yapmamz gerektiini stne basa basa sylemitik. Biz u ana kadar bu konuyu
ayrntl olarak ele almam da olsak, siz imdiye kadar yazdnz programlarda Trke
karakterleri kullanrken halihazrda pek ok problemle karlam ve bu sorunlarn neden
kaynaklandn anlamakta zorlanm olabilirsiniz.
te bu blmde, o zaman henz bilgimiz yetersiz olduu iin ertelediimiz bu encoding
konusunu btn ayrntlaryla ele alacaz ve yazdmz programlarda Trke karakterleri
kullanrken neden sorunlarla karlatmz, bu sorunun temelinde neyin yattn anlamaya
alacaz.
O halde hi vakit kaybetmeden bu nemli konuyu incelemeye balayalm.

29.1 Giri

nceki blmlerde sk sk tekrar ettiimiz gibi, bilgisayar dediimiz ey, zerinden elektrik
geen devrelerden olumu bir sistemdir. Eer bir devrede elektrik yoksa o devrenin deeri
0 volt iken, o devreden elektrik getiinde devrenin deeri yaklak +5 volttur.
Grdnz gibi, ortada iki farkl deer var: 0 volt ve +5 volt. kili (binary ) sayma sisteminde
de iki deer bulunur: 0 ve 1. te biz bu 0 voltu ikili sistemde 0 ile, +5 voltu ise 1 ile temsil

439
Python 3 iin Trke Klavuz, Srm 3

ediyoruz. Yani devreden elektrik getiinde o devrenin deeri 1, elektrik gemediinde ise
0 olmu oluyor. Tabii bilgisayar asndan bakldnda devrede elektrik vardr veya yoktur.
Biz insanlar bu ikili durumu daha kolay bir ekilde maniple edebilmek iin farkl voltaj
durumlarndan her birine srasyla 0 ve 1 gibi bir ad veriyoruz. Yani iki farkl voltaj deerini
iki farkl say halinde kodlam oluyoruz...
Hatrlarsanz bir nceki blmde tasarladmz basit iletiim modelinde de ampuln lo k
vermesini salayan dk elektrik sinyallerini 0 ile, parlak k vermesini salayan yksek
elektrik sinyallerini ise 1 ile temsil etmitik. Bu temsil iine de teknik olarak kodlama
(encoding ) ad verildiini sylemitik. te bilgisayarlar asndan da benzer bir durum sz
konusudur. Bilgisayarlarda da 0 volt ve +5 volt deerleri srasyla ikili sayma sistemindeki 0
ve 1 saylar halinde kodlanabilir.
Szn z ilk bata yalnzca iki farkl elektrik sinyali vardr. Elbette bu elektrik sinyalleri
ile dorudan herhangi bir ilem yapamayz. Mesela elektrik sinyallerini birbiriyle toplayp,
birbirinden karamayz. Ama bu sinyalleri bir sayma sistemi ile temsil edersek (yani bu
sinyalleri o sayma sisteminde kodlarsak), bunlar kullanarak, rnein, aritmetik ilemleri
rahatlkla gerekletirebiliriz. Mesela 0 volt ile +5 voltu birbiriyle toplayamayz, ama 0 voltu
ikili sistemdeki 0 saysyla, +5 voltu ise ikili sistemdeki 1 saysyla kodladktan sonra bu ikili
saylar arasnda her trl aritmetik ilemi gerekletirebiliriz.
Bilgisayarlar yalnzca iki farkl voltaj durumundan anlad ve bu iki farkl voltaj durumu da ikili
sayma sistemindeki iki farkl say ile kolayca temsil edilebildii iin, ilk bilgisayarlar ounlukla
sadece hesap ilemlerinde kullanlyordu. Karakterlerin/harerin bilgisayar dnyasndaki
ilevi bir hayli kstlyd. Metin oluturma ii o zamanlarda daktilo ve benzeri aralarn grevi
olarak grlyordu. Bu durumu, telefon teknolojisi ile kyaslayabilirsiniz. lk telefonlar da
yalnzca iki kii arasndaki sesli iletiimi salamak gibi kstl bir amaca hizmet ediyordu. Bugn
ise, gemite pek ok farkl cihaza paylatrlm grevleri akll telefonlar araclyla tek elden
halledebiliyoruz.
Peki bir bilgisayar yalnzca elektrik sinyallerinden anlyorsa, biz mesela bilgisayarlar nasl
oluyor da metin girii iin kullanabiliyoruz?
Bu sorunun cevab aslnda ok ak: Birtakm elektrik sinyallerini, birtakm aritmetik ilemleri
gerekletirebilmek amacyla nasl birtakm saylar halinde kodlayabiliyorsak; birtakm saylar
da, birtakm metin ilemlerini gerekletirebilmek amacyla birtakm karakterler halinde
kodlayabiliriz.
Peki ama nasl?
Bir nceki blmde bahsettiimiz basit iletiim modeli araclyla bunun nasl yaplacan
anlatmtk. Tpk bizim basit iletiim sistemimizde olduu gibi, bilgisayarlar da yalnzca
elektrik sinyallerini grr. Tpk orada yaptmz gibi, bilgisayarlarda da hangi elektrik
sinyalinin hangi sayya; hangi saynn da hangi karaktere karlk geleceini belirleyebiliriz.
Daha dorusu, bilgisayarlarn grd bu elektrik sinyallerini saylara ve karakterlere
dntrebiliriz. Dardan girilen karakterleri de, bilgisayarlarn anlayabilmesi iin tam aksi
istikamette sayya, oradan da elektrik sinyallerine evirebiliriz. te bu dntrme ilemine
karakter kodlama (character encoding ) ad verilir.
Bu noktada yle bir soru akla geliyor: Tamam, saylar karakterlere, karakterleri de saylara
dntreceiz. Ama peki hangi saylar hangi karakterlere, hangi karakterleri de hangi
saylara dntreceiz? Yani mesela ikili sistemdeki 0 says hangi karaktere, 1 says hangi
karaktere, 10 says hangi karaktere karlk gelecek?
Siz aslnda bu sorunun cevabn da biliyorsunuz. Yine bir nceki blmde anlattmz
gibi, hangi saylarn hangi karakterlere karlk geleceini, saylarla karakterlerin eletirildii

440 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

birtakm tablolalar yardmyla rahatlkla belirleyebiliriz.


Bu i ilk bata kulaa ok kolaym gibi geliyor. Esasnda i kolaydr, ama yle bir
problem var: Herkes ayn saylar ayn karakterlerle eletirmiyor olabilir. Mesela durumu
bir nceki blmde tasarladmz basit iletiim modeli zerinden dnelim. Diyelim ki,
bata yalnzca bir arkadanzla ikinizin arasndaki iletiimi salamak iin tasarladnz bu
sistem bakalarnn da dikkatini ekmi olsun... Tpk sizin gibi, bakalar da lo k-parlak
k kartl zerinden birbiriyle iletiim kurmaya karar vermi olsun. Ancak sistemin temeli
herkese ayn ekilde kullanlyor olsa da, karakter eletirme tablolarn herkes ayn ekilde
kullanmyor olabilir. rnein bakalar, kendi ihtiyalar erevesinde, farkl saylarn farkl
karakterlerle eletirildii farkl tablolar tasarlam olabilir. Bu durumun dezavantaj, farkl
sistemlerle retilen mesajlarn, baka sistemlerde asl gibi grntlenemeyecek olmasdr.
rnein a harnin 1010 gibi bir sayyla temsil edildii sistemle retilen bir mesaj, ayn harn
mesela 1101 gibi bir sayyla temsil edildii sistemde dzgn grntlenemeyecektir. te ayn
ey bilgisayarlar iin de geerlidir.
1960l yllarn ilk yarsna kadar her bilgisayar reticisi, saylarla karakterlerin eletirildii,
birbirinden ok farkl tablolar kullanyordu. Yani her bilgisayar reticisi farkl karakterleri farkl
saylarla eletiriyordu. rnein bir bilgisayarda 10 says a harne karlk geliyorsa, baka
bir bilgisayarda 10 says b harne karlk gelebiliyordu. Bu durumun doal sonucu olarak,
iki bilgisayar arasnda gvenilir bir veri aktarm gerekletirmek mmkn olmuyordu. Hatta
daha da vahimi, ayn rma iinde bile birden fazla karakter eletirme tablosunun kullanld
olabiliyordu...
Peki bu sorunun zm ne olabilir?
Cevap elbette standartlama.
Standartlama ilerleme ve uygarlk asndan ok nemli bir kavramdr. Standartlama
olmadan ilerleme ve uygarlk dnlemez. Eer standartlama diye bir ey olmasayd,
mesela A4 piller boy ve en olarak standart bir lye sahip olmasayd, evde kullandnz
kk aletlerin pili bittiinde uygun pili satn almakta byk zorluk ekerdiniz. Banyo-mutfak
musluklarndaki plastik contann belli bir standard olmasayd, conta eskidiinde yenisini
alabilmek iin eskisinin llerini inceden inceye hesaplayp bu llere gre yeni bir conta
arayna kmanz gerekirdi. Herhangi bir yerden bulduunuz contay herhangi bir muslukta
kullanamazdnz. te bu durumun ayns bilgisayarlar iin de geerlidir. Eer bugn
karakterlerle saylar eletirme ilemi belli bir standart zerinden yrtlyor olmasayd,
kendi bilgisayarnzda oluturduunuz bir metni baka bir bilgisayarda atnzda ayn metni
gremezdiniz. te 1960l yllara kadar bilgisayar dnyasnda da aynen buna benzer bir sorun
vard. Yani o dnemde, hangi saylarn hangi karakterlerle eleecei konusunda uzlama
olmad iin, farkl bilgisayarlar arasnda metin dei tokuu pek mmkn deildi.
1960l yllarn banda IBM irketinde alan Bob Bemer adl bir bilim adam bu kargaann
sona ermesi gerektiine karar verip, herkes tarafndan benimsenecek ortak bir karakter
kodlama sistemi zerinde ilk almalar balatt. te ASCII (aski okunur) bylece hayatmza
girmi oldu.
Peki bu ASCII denen ey tam olarak ne anlama geliyor? Gelin bu sorunun cevabn, en batan
balayarak ve olabildiince ayrntl bir ekilde vermeye alalm.

29.1. Giri 441


Python 3 iin Trke Klavuz, Srm 3

29.2 ASCII

Bilgisayarlarn iki farkl elektrik sinyali ile altn, bu iki farkl sinyalin de 0 ve 1 saylar ile
temsil edildiini, bilgisayarla metin ilemleri yapabilmek iin ise bu saylarn belli karakterlerle
eletirilmesi gerektiini sylemitik.
Yukarda da bahsettiimiz gibi, uygarlk ve ilerleme asndan standartlama nemli bir
basamaktr. yle dnn: Biz bilgisayarlarn alma prensibinde iki farkl elektrik sinyali
olduunu biliyoruz. Biz insanlar olarak, ilerimizi daha kolay yapabilmek iin, bu sinyalleri
daha somut birer ara olan 0 ve 1 saylarna atamz. Eer devrede elektrik yoksa bu
durumu 0 ile, eer devrede elektrik varsa bu durumu 1 ile temsil ediyoruz. Esasnda bu
da bir uzlama gerektirir. Devrede elektrik yoksa bu durumu pekala 0 yerine 1 ile de temsil
edebilirdik... Eer elektrik sinyallerinin temsili zerinde byle bir uzlamazlk olsayd, her
eyden nce hangi sinyalin hangi sayya karlk gelecei konusunda da ortak bir karara
varmamz gerekirdi.
Elektriin var olmad durumu 0 yerine 1 ile temsil etmek akla pek yatkn olmad iin
uzlamada bir problem kmyor. Ama karakterler byle deildir. Onlarca (hatta yzlerce ve
binlerce) karakterin saylarla eletirilmesi gereken bir durumda, ortak bir eletirme dzeni
zerinde uzlama salamak hi de kolay bir i deildir. Zaten 1960l yllarn bana kadar da
byle bir uzlama salanabilmi deildi. Dediimiz gibi, her bilgisayar reticisi saylar farkl
karakterlerle eletiriyor, yani birbirlerinden tamamen farkl karakter kodlama sistemleri
kullanyordu.
te bu kargaay ortadan kaldrmak gayesiyle, Bob Bemer ve ekibi hangi saylarn hangi
karakterlere karlk geleceini belli bir standarda balayan bir tablo oluturdu. Bu standarda
ise American Standard Code for Information Interchange, yani Bilgi Alverii iin Standart
Amerikan Kodu veya ksaca ASCII ad verildi.

29.2.1 7 Bitlik bir Sistem

ASCII ad verilen sistem, birtakm saylarn birtakm karakterlerle eletirildii basit


bir tablodan ibarettir. Bu tabloyu http://www.asciitable.com/ adresinde grebilirsiniz:

442 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

sterseniz bu tabloyu Python yardmyla kendiniz de oluturabilirsiniz:


for i in range(128):
if i % 4 == 0:
print("\n")

print("{:<3}{:>8}\t".format(i, repr(chr(i))), sep="", end="")

Not: Bu kodlarda repr() fonksiyonu dnda bilmediiniz ve anlayamayacanz hibir ey


yok. Biraz sonra repr() fonksiyonundan da bahsedeceiz. Ama dilerseniz, bu fonksiyonun ne
ie yarad konusunda en azndan bir kir sahibi olmak iin, yukardaki kodlar bir de repr()
olmadan yazmay ve aldnz kty incelemeyi deneyebilirsiniz.

ASCII tablosunda toplam 128 karakterin saylarla eletirilmi durumda olduunu


gryorsunuz. Bir nceki blmde bahsettiimiz basit iletiim modelinde anlattklarmzdan
da aina olduunuz gibi, 128 adet say 7 bite karlk gelir (2**7=128). Yani 7 bit ile
gsterilebilecek son say 127 dir. Dolaysyla ASCII 7 bitlik bir sistemdir.
ASCII tablosunu yle bir incelediimizde ilk 32 enin gze ilk bata anlamsz grnen
birtakm karakterlerden olutuunu gryoruz:
say karakter say karakter say karakter say karakter
0 \x00 1 \x01 2 \x02 3 \x03
4 \x04 5 \x05 6 \x06 7 \x07
8 \x08 9 \t 10 \n 11 \x0b
12 \x0c 13 \r 14 \x0e 15 \x0f
16 \x10 17 \x11 18 \x12 19 \x13
20 \x14 21 \x15 22 \x16 23 \x17
24 \x18 25 \x19 26 \x1a 27 \x1b
28 \x1c 29 \x1d 30 \x1e 31 \x1f

29.2. ASCII 443


Python 3 iin Trke Klavuz, Srm 3

Not: Bu arada, asciitable.com adresinden baktnz tablo ile yukardaki tablonun birbirinden
farkl olduunu zannedebilirsiniz ilk bakta. Ama aslnda arada herhangi bir fark yok. Yalnzca
iki tablonun karakterleri gsterim ekli birbirinden farkl. rnein asciitable.comdaki tabloda
9 saysnn TAB (horizontal tab) adl bir karaktere atandn gryoruz. Yukardaki tabloda
ise 9 saysnn yannda \t adl ka dizisi var. Grdnz gibi, TAB (horizontal tab) ifadesi
ile \t ifadesi ayn karaktere atfta bulunuyor. Yalnzca bunlarn gsterimleri birbirinden farkl,
o kadar.

Aslnda bu karakter salatas arasnda bizim tandmz birka karakter de yok deil. Mesela 9.
sradaki \t esinin sekme oluturan ka dizisi olduunu syledik. Ayn ekilde, 10. sradaki
\n esinin satr bana geiren ka dizisi olduunu, 13. sradaki \r esinin ise satr
baa alan ka dizisi olduunu da biliyoruz. Bu tr karakterler baslamayan (non-printing )
karakterlerdir. Yani mesela ekranda grntlenebilen a, b, c, !, ?, = gibi karakterlerden
farkl olarak bu ilk 32 karakter ekranda grnmez. Bunlara ayn zamanda kontrol karakterleri
(control characters ) ad da verilir. nk bu karakterler ekranda grntlenmek yerine,
metnin akn kontrol eder. Bu karakterlerin ne ie yaradn u tabloyla tek tek gsterebiliriz
(tablo http://tr.wikipedia.org/wiki/ASCII adresinden alntdr):
Say Karakter Say Karakter
0 bo 16 veri balantsndan k
1 balk balangc 17 aygt denetimi 1
2 metin balangc 18 aygt denetimi 2
3 metin sonu 19 aygt denetimi 3
4 aktarm sonu 20 aygt denetimi 4
5 sorgu 21 olumsuz bildirim
6 bildirim 22 zaman uyumlu bota kalma
7 zil 23 aktarm blou sonu
8 geri al 24 iptal
9 yatay sekme 25 ortam sonu
10 satr besleme/yeni satr 26 deitir
11 dikey sekme 27 k
12 form besleme/yeni sayfa 28 dosya ayrcs
13 satr ba 29 grup ayrcs
14 dar kaydr 30 kayt ayrcs
15 ieri kaydr 31 birim ayrcs
Grdnz gibi, bunlar birer harf, say veya noktalama iareti deil. O yzden bu karakterler
ekranda grnmez. Ama bir metindeki veri, satr ve paragraf dzeninin nasl olacan, metnin
nerede balayp nerede biteceini ve nasl grneceini kontrol ettikleri iin nemlidirler.
Geri kalan saylar ise dorudan karakterlere, saylara ve noktalama iaretlerine tahsis
edilmitir:

444 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

say karakter say karakter say karakter say karakter


32 33 ! 34 35 #
36 $ 37 % 38 & 39
40 ( 41 ) 42 * 43 +
44 , 45 - 46 . 47 /
48 0 49 1 50 2 51 3
52 4 53 5 54 6 55 7
56 8 57 9 58 : 59 ;
60 < 61 = 62 > 63 ?
64 @ 65 A 66 B 67 C
68 D 69 E 70 F 71 G
72 H 73 I 74 J 75 K
76 L 77 M 78 N 79 O
80 P 81 Q 82 R 83 S
84 T 85 U 86 V 87 W
88 X 89 Y 90 Z 91 [
92 \ 93 ] 94 ^ 95 _
96 97 a 98 b 99 c
100 d 101 e 102 f 103 g
104 h 105 i 106 j 107 k
108 l 109 m 110 n 111 o
112 p 113 q 114 r 115 s
116 t 117 u 118 v 119 w
120 x 121 y 122 z 123 {
124 | 125 } 126 ~ 127 x7f

te 32 ile 127 aras saylarla eletirilen yukardaki karakterler yardmyla metin


ihtiyalarmzn byk blmn karlayabiliriz. Yani ASCII ad verilen bu eletirme tablosu
sayesinde bilgisayarlarn saylarla birlikte karakterleri de ileyebilmesini salayabiliriz.
1960l yllara gelindiinde, bilgisayarlar 8 bit uzunluundaki verileri ileyebiliyordu. Yani,
ASCII sisteminin gereklendii (yani hayata geirildii) bilgisayarlar 8 bitlik bir kapasiteye
sahipti. Bu 8 bitin 7 biti karakterle ayrlmt. Dolaysyla mevcut btn karakterler 7
bitlik bir alana sdrlmt. Bota kalan 8. bit ise, veri aktarmnn dzgn gerekletirilip
gerekletirilmediini denetlemek amacyla doruluk kontrol iin kullanlyordu. Bu
kontrole teknik olarak elik denetimi (parity check ), bu elik denetimini yapmamz salayan
bite ise elik biti (parity bit ) ad verildiini biliyorsunuz. Geen blmde bu teknik terimlerin
ne anlama geldiini aklam, hatta bunlarla ilgili basit bir rnek de vermitik.
Adndan da anlalaca gibi, ASCII bir Amerikan standarddr. Dolaysyla hazrlannda
ngilizce temel alnmtr. Zaten ASCII tablosunu incelediinizde, bu tabloda Trkeye zg
harerin bulunmadn greceksiniz. Bu sebepten, bu standart ile mesela Trkeye zg
karakterleri gsteremeyiz. nk ASCII standardnda , , gibi harer kodlanmamtr.
zellikle Pythonn 2.x serisini kullanm olanlar, ASCIInin bu yetersizliinin nelere sebep
olduunu gayet iyi bilir. Pythonn 2.x serisinde mesela dorudan yle bir kod yazamayz:
print("Merhaba irin Baba!")

Merhaba irin Baba! adl karakter dizisinde geen har ASCII d bir karakterdir. Yani bu
harf ASCII ile temsil edilemez. O yzden byle bir kod yazp bu kodu altrdmzda Python
bize yle bir hata mesaj gsterecektir:

29.2. ASCII 445


Python 3 iin Trke Klavuz, Srm 3

File "deneme.py", line 1


SyntaxError: Non-ASCII character '\xde' in file deneme.py on line 1, but no
encoding declared; see http://www.python.org/peps/pep-0263.html for details

Aynen anlattmz gibi, yukardaki hata mesaj da kodlar arasnda ASCII olmayan bir karakter
yer aldndan yaknyor...
ASCIInin her ne kadar yukarda bahsettiimiz eksiklikleri olsa da bu standart son derece
yaygndr ve piyasada bulunan pek ok sistemde kullanlmaya devam etmektedir. rnein
size kullanc ad ve parola soran hemen hemen btn sistemler bu ASCII tablosunu temel alr
veya bu tablodan etkilenmitir. O yzden ou yerde kullanc ad ve/veya parola belirlerken
Trke karakterleri kullanamazsnz. Hatta pek ok yaz tipinde yalnzca ASCII tablosunda yer
alan karakterlerin karl bulunur. Bu yzden, mesela blogunuzda kullanmak zere seip
beendiiniz ou yaz tipi , , , gibi hareri gstermeyebilir. Yukarda Merhaba
irin Baba! rneinde de gsterdiimiz gibi, Pythonn 2.x serisinde de ntanml olarak
ASCII kodlama biimi kullanlyordu. O yzden Pythonn 2.x srmlerinde Trke karakterleri
gsterebilmek iin daha fazla ilave ilem yapmak zorunda kalyorduk.
Szn z, eer yazdnz veya kendiniz yazmam da olsanz herhangi bir sebeple
kullanmakta olduunuz bir programda Trke karakterlere ilikin bir hata alyorsanz, bu
durumun en muhtemel sebebi, kullandnz programn veya sistemin, dorudan ASCIIyi
veya ASCIIye benzer baka bir sistemi temel alarak alyor olmasdr. ASCII tablosunda
grnen 128 karakter dnda kalan hibir karakter ASCII ile kodlanamayaca iin, zellikle
farkl dillerin kullanld bilgisayarlarda alan programlar kanlmaz olarak karakterlere
ilikin pek ok hata verecektir. rnein, karakter kodlamalarna ilikin olarak yukarda
bahsettiimiz ayrntlardan habersiz bir Amerikal programcnn yazd bir programa Trke
veri girdiinizde bu program bir anda tuhaf grnen hatalar verip kecektir...

29.2.2 Geniletilmi ASCII

Dediimiz gibi, ASCII 7 bitlik bir karakter kmesidir. Bu standardn ilk kt dnemde 8.
bitin hata kontrol iin kullanldn sylemitik. Sonraki yllarda 8. bitin hata kontrol iin
kullanlmasndan vazgeildi. Bylece 8. bit yine boa dm oldu. Bu bitin boa dmesi ile
elimizde yine toplam 128 karakterlik bir boluk olmu oldu. Dediimiz gibi 7 bit ile toplam
128 say-karakter eletirilebilirken, 8 bit ile toplam 256 say-karakter eletirilebilir. Ne de
olsa:
>>> 2**7

128

>>> 2**8

256

te bu fazla bit, farkl kii, kurum ve organizasyonlar tarafndan, ngilizcede bulunmayan


ama baka dillerde bulunan karakterleri temsil etmek iin kullanld. Ancak elbette bu
fazladan bitin salad 128 karakter de dnyadaki btn karakterlerin temsil edilmesine
yetmez. Bu yzden 8. bitin sunduu boluk, birbirinden farkl karakterleri gsteren eitli
tablolarn ortaya kmasna sebep oldu. Bu birbirinden farkl tablolara genel olarak kod
sayfas ad verilir. rnein Microsoft irketinin Trkiyeye gnderdii bilgisayarlarda tanml
cp857 adl kod sayfasnda 128 ile 256 aralnda Trke karakterlere de yer verilmiti (bkz.
http://msdn.microsoft.com/en-us/library/cc195068.aspx)

446 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

Bu tabloya baktnzda batan 128e kadar olan karakterlerin standart ASCII tablosu ile ayn
olduunu greceksiniz. 128. karakterden itibaren ise Trkeye zg harer tanmlanr.
Mesela bu tabloda 128. karakter Trkedeki byk har iken, 159. karakter kk
hardir. Bu durumu u Python kodlar ile de teyit edebilirsiniz:
>>> "".encode("cp857")

b'\x80'

>>> "".encode("cp857")

b'\x9f'

Bu arada bu saylarn onaltl sayma dzenine gre olduunu biliyorsunuz. Onlu dzende
bunlarn karl srasyla udur:
>>> int("80", 16)

128

>>> int("9f", 16)

159

Burada karakter dizilerinin encode() adl metodunu kullandmza dikkat edin. Bu metot
yardmyla herhangi bir karakteri herhangi bir karakter kodlama sistemine gre kodlayabiliriz.
Mesela yukardaki iki rnekte ve harerini cp857 adl kod sayfasna gre kodladk ve
bunlarn bu kod sayfasnda hangi saylara karlk geldiini bulduk.
cp857 numaral kod sayfasnda ve hareri yer ald iin, biz bu hareri o kod sayfasna
gre kodlayabiliyoruz. Ama mesela ASCII kodlama sisteminde bu harer bulunmaz. O yzden
bu hareri ASCII sistemine gre kodlayamayz:
>>> "".encode("ascii")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xc7' in position
0: ordinal not in range(128)

Tpk hata mesajnda da sylendii gibi:


Unicode Kodlama Hatas: 'ascii' kod zcs, 0 konumundaki '\xc7' adl
karakteri kodlayamyor. Say 0-128 aralnda deil.

Gerekten de onlu sistemde 199 saysna karlk gelen bu onaltl \xc7 says ASCIInin
kapsad say aralnn dnda kalmakta, bu yzden de ASCII kod zcs ile
kodlanamamaktadr.
Dediimiz gibi, Microsoft Trkiyeye gnderdii bilgisayarlarda 857 numaral kod sayfasn
tanmlyordu. Ama mesela Arapa konuulan lkelere gnderdii bilgisayarlarda
ise, http://msdn.microsoft.com/en-us/library/cc195061.aspx adresinden grebileceiniz 708
numaral kod sayfasn tanmlyordu. Bu kod sayfasn incelediinizde, 128 alt karakterlerin
standart ASCII ile ayn olduunu ancak 128 st karakterlerin Trke kod sayfasndaki
karakterlerden farkl olduunu greceksiniz. te 128 st karakterler btn dillerde
birbirinden farkldr. Bu farklln ne sonu dourabileceini tahmin edebildiinizi
zannediyorum. Elbette, mesela kendi bilgisayarnzda yazdnz bir metni Arapa konuulan

29.2. ASCII 447


Python 3 iin Trke Klavuz, Srm 3

bir lkedeki bilgisayara gnderdiinizde, doal olarak metin iindeki Trkeye zg


karakterlerin yerinde baka karakterler belirecektir.
Bu blmn banda da sylediimiz gibi, Geniletilmi ASCII sisteminde 128 ile 256 aral
iin pek ok farkl karakter eletirme tablolar kullanlyordu. Mesela Microsoft irketi bu
aralk iin kendine zg birtakm kod sayfalar tasarlamt. Bu kod sayfalarna rnek olarak
yukarda cp857 ve cp708 numaral kod sayfalarn rnek vermitik.
Elbette 128 ile 256 araln dolduran, yalnzca Microsofta ait kod sayfalar yoktu piyasada.
Ayn aral farkl karakterlerle dolduran pek ok baka eletirme tablosu da dolayordu
etrafta. rnein zellikle Bat Avrupa dillerindeki karakterleri temsil edebilmek iin
oluturulmu latin1 (br adyla ISO-8859-1) adl karakter kmesi bugn de yaygn olarak
kullanlan sistemlerinden biridir. Almancada olup da ASCII sistemi ile temsil edilemeyen ,
, gibi harer ve Franszcada olup da yine ASCII sistemi ile temsil edilemeyen ve gibi
harer bu karakter kmesinde temsil edilebiliyordu. Eer dilerseniz bu karakter kmesini de
http://www.leformat.info/info/charset/ISO-8859-1/list.htm adresinden inceleyebilirsiniz.
Yalnz burada nemli bir ayrnty not delim. Geniletilmi ASCII, standart ASCII gibi genel
kabul grm tek bir sistem deildir.Geniletilmi ASCII dediimizde zaten tek bir karakter
kmesi akla gelmiyor. Dolaysyla ASCII dendiinde anlamamz gereken ey 128 karakterlik
bir say-karakter eletirme tablosudur. ASCII hibir zaman bu 128 karakterin tesine geip de
256 karakterlik bir aral temsil etmi deildir. Dolaysyla 127. saynn tesindeki karakterleri
kapsayan sistem ASCII deildir. Geniletilmi ASCII kavram, temel ASCII sisteminde temsil
edilen say-karakter iftlerinin pek ok farkl kurum ve kurulu tarafndan birbirinden farkl
biimlerde geniletilmesiyle oluturulmu, ancak ASCIInin kendisi kadar standartlaamam
bir sistemler btndr. Bu sistem iinde pek ok farkl kod sayfas (veya karakter kmesi)
yer alr. Tek bana Geniletilmi ASCII ifadesi aklayc olmayp; ASCIInin hangi karakter
kmesine gre geniletildiinin de belirtilmesi gerekir.
Btn bu anlattklarmzdan u sonucu karyoruz: ASCII bilgisayarlar arasnda gvenli bir
ekilde veri aktarmn salamak iin atlm en nemli ve en baarl admlardan bir tanesidir.
Bu gl standart sayesinde uzun yllar bilgisayarlar aras temel iletiim baaryla saland.
Ancak bu standardn zayf kald nokta 7 bitlik olmas ve bota kalan 8. bitin tek bana
dnyadaki btn dilleri temsil etmeye yeterli olmamasdr.

29.2.3 1 Karakter == 1 Bayt

ASCII standard, her karakterin 1 bayt ile temsil edilebilecei varsaym zerine kurulmutur.
Bildiiniz gibi, 1 bayt (geleneksel olarak) 8 bite karlk gelir. Peki 1 baytn 8 bite karlk
gelmesinin nedeni nedir? Aslnda bunun zel bir nedeni yok. 1 destede neden 10 e, 1
dzinede de 12 e varsa, 1 baytta da 8 bit vardr... Yani biz insanlar yle olmasna karar
verdiimiz iin 1 destede 10 e, 1 dzinede 12 e, 1 baytta ise 8 bit vardr.
Dediimiz gibi ASCII standard 7 bitlik bir sistemdir. Yani bu standartta en byk say olan
127 yalnzca 7 bit ile gsterilebilir:
>>> bin(127)[2:]

'1111111'

127 says 7 bit ile gsterilebilecek son saydr:


>>> (127).bit_length()

448 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

>>> (128).bit_length()

8 bitlik bir sistem olan Geniletilmi ASCII ise 0 ile 255 aras saylar temsil edebilir:
>>> bin(255)[2:]

'11111111'

255 says 8 bit ile gsterilebilecek son saydr:


>>> (255).bit_length()

>>> (256).bit_length()

Dolaysyla ASCIIde ve Geniletilmi ASCIIde 1 baytlk alana toplam 256 karakter sdrlabilir.
Eer daha fazla karakteri temsil etmek isterseniz 1 bayttan fazla bir alana ihtiya duyarsnz.
Bu arada, olas bir yanl anlamay nleyelim:
1 bayt olma durumu mesela dorudan a harnin kendisi ile ilgili bir ey deildir. Yani a
har 1 bayt ile gsterilebiliyorken, mesela har 1 bayt ile gsterilemiyorsa, bunun nedeni
harninin tuhaf bir harf olmas deildir! Eer ASCII gibi bir sistem Trkiyede tasarlanm
olsayd, herhalde har ilk 128 say arasnda kendine bir yer bulurdu. Mesela byle bir
sistemde muhtemelen x, w ve q hareri, Trk alfabesinde yer almadklar iin, darda
kalrd. O zaman da , , gibi harerin 1 bayt olduunu, x, w ve q gibi harerin ise 1
bayt olmadn sylerdik.

29.3 UNICODE

lk bilgisayarlarn ABD kl olmas nedeniyle, bilgisayarlar ounlukla ABDde retilip ABD


pazarna satlyordu. Bu nedenle ngilizce alfabeyi temel alan ASCII gibi bir sistem bu pazarn
karakter temsil ihtiyalarn %99 orannda karlyordu. Ancak bilgisayarlarn ABD dna
kmas ve ABD dnda da da yaylmaya balamasnn ardndan, ASCIInin yetersizlikleri de
iyice grnr olmaya balad. nk ASCII tablosunda, ngilizce dndaki dillerde bulunan
aksanl ve noktal harerin (, , , gibi) hibiri bulunmuyordu.
lk zamanlarda insanlar aksanl ve noktal hareri ASCII tablosundaki benzerleriyle
deitirerek kullanmaya raz olmulard ( yerine e; yerine a; yerine o; yerine c
gibi). Ancak bu zm Avrupa dillerini kullananlarn sorununu ksmen zyor da olsa,
Asya dillerindeki problemi zemez. nk ASCII tablosunu kullanarak ince ve Japonca gibi
dillerdeki karakterleri herhangi bir ekilde temsil etmeniz mmkn deildir.
Bu sknty ksmen de olsa giderebilmek iin, yukarda da bahsetmi olduumuz, 128-256
arasndaki boluktan yararlanlmaya baland. Dediimiz gibi, ASCII 7 bitlik bir sistem
olduu iin, 8 bitlik bilgisayarlarda fazladan 1 bitin bota kalmasna izin verir. te bu
1 bitlik boluk dnyann eitli lkeleri tarafndan kendi karakter ihtiyalarn karlamak

29.3. UNICODE 449


Python 3 iin Trke Klavuz, Srm 3

iin kullanld. Dolaysyla Almanlar 128-256 arasn farkl karakterlerle, Franszlar baka
karakterlerle, Yunanlar ise bambaka karakterlerle doldurdular.
Hatrlarsanz ASCIInin ortaya k sebebi bilgisayarlar arasnda veri alveriini
mmkn klmakt. ASCII Amerikadaki bilgisayarlar arasnda salkl bir veri alverii
gerekletirilmesini rahatlkla mmkn klyordu. Ama bilgisayarlarn dnyaya yaylmas
ile birlikte ilk bataki veri aktarm problemi tekrar ortaya kt. Bu defa da, mesela
Trkiyeden gnderilen bir metin (rnein bir e.posta) Almanyadaki bilgisayarlarda dzgn
grntlenemeyebiliyordu. rnein Windows-1254 (cp1254) numaral kod sayfas ile
kodlanm Trke bir metin, Almanyada Windows-1250 numaral kod sayfasnn tanml
olduu bir bilgisayarda, ayn saylarn her iki kod sayfasnda farkl karakterlere karlk
gelmesi nedeniyle dzgn grntlenemez.

Not: Windows-1254 adl kod sayfas iin http://en.wikipedia.org/wiki/Windows-1254


adresine; Windows-1250 adl kod sayfas iin ise http://en.wikipedia.org/wiki/Windows-1250
adresine bakabilirsiniz.

te nasl 1960l yllarn banda Bob Bemer ve arkadalar bilgisayarlar arasnda salkl
bir veri iletiimi salamak iin kollar svayp ASCII gibi bir zm rettiyse, ASCII ve
Geniletilmi ASCII ile kodlanamayan karakterleri de kodlayp, uluslar arasnda ok geni apl
veri alveriine izin verebilmek amacyla Xerox irketinden Joe Becker, Apple irketinden ise
Lee Collins ve Mark Davis UNICODE adl bir zm zerinde ilk almalar balatt.
Peki tam olarak nedir bu UNICODE denen ey?
Aslnda Unicode da tpk ASCII gibi bir standarttr. Unicodeun bir proje olarak ortaya k
1987 ylna dayanr. Projenin amac, dnyadaki btn dillerde yer alan karakterlerin tek,
benzersiz ve doru bir biimde temsil edilebilmesidir. Yani bu projenin ortaya k gayesi,
ASCIInin yetersiz kald noktalar tela etmektir.

29.3.1 Snrsz Bitlik bir Sistem

Unicode standard ile ilgili olarak bilmemiz gereken ilk ey bu standardn ASCIIyi tamamen
grmezden gelmiyor olmasdr. Daha nce de sylediimiz gibi, ASCII son derece yaygn ve
gl bir standarttr. stelik ASCII standard yaygn olarak kullanlmaya da devam etmektedir.
Bu sebeple ASCII ile halihazrda kodlanm karakterler UNICODE standardnda da ayn ekilde
kodlanmtr. Dolaysyla ASCII UNICODE sisteminin bir alt kmesi olduu iin, ASCII ile
uyumlu olan btn sistemler otomatik olarak UNICODE ile de uyumludur. Ancak tabii bunun
tersi geerli deildir.
UNICODEun ASCIIden en nemli fark, UNICODEun ASCIIye kyasla ok daha byk
miktarda karakterin kodlanmasna izin vermesidir. ASCII yalnzca 128 karakterin
kodlanmasna izin verirken UNICODE 1.000.000dan fazla karakterin kodlanmasna izin verir.
UNICODE sistemini devasa bir karakter tablosu olarak hayal edebilirsiniz. Bildiiniz gibi ASCII
7 bitlik bir sistemdir. Bu sebeple de sadece 128 karakteri kodlayabilir. UNICODE ilk ortaya
ktnda 16 bitlik bir sistem olarak tasarlanmt. Dolaysyla UNICODE daha ilk knda
2**16=65536 karakterin kodlanmasna izin veriyordu. Bugn ise UNICODE sisteminin byle
kesin bir snr yoktur. nk bilmem ka bitlik bir sistem kavram UNICODE iin geerli
deildir. Dediimiz gibi, UNICODEu, ucu buca olmayan dev bir karakter tablosu olarak
dnebilirsiniz. Bu tabloya istediimiz kadar karakteri ekleyebiliriz. Bizi engelleyen snrl
bir bit kavram mevcut deildir. nk UNICODE sisteminin kendisi, ASCII sisteminin

450 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

aksine, dorudan doruya karakterleri kodlamaz. UNICODEun yapt ey karakterleri


tanmlamaktan ibarettir.
Unicode sisteminde her karakter tek ve benzersiz bir kod konumuna (code point ) karlk
gelir. Kod konumlar u formle gre gsterilir:
U+saynn_onaltl_deeri

rnein a harnin kod konumu udur:


u+0061

Buradaki 0061 says onaltl bir saydr. Bunu onlu say sistemine evirebilirsiniz:
>>> int("61", 16)

97

Hatrlarsanz a harnin ASCII tablosundaki karl da 97 idi.


Esasnda ASCII ile UNICODE birbirleri ile karlatrlamayacak iki farkl kavramdr. Neticede
ASCII bir kodlama biimidir. UNICODE ise pek ok farkl kodlama biimini iinde barndran
devasa bir sistemdir.

Not: Unicode standardna http://www.unicode.org/versions/Unicode6.2.0/UnicodeStandard-6.2.pdf


adresinden ulaabilirsiniz.

29.3.2 UTF-8 Kod zcs

Dediimiz gibi UNICODE devasa bir tablodan ibarettir. Bu tabloda karakterlere ilikin birtakm
bilgiler bulunur ve bu sistemde her karakter, kod konumlar ile ifade edilir. UNICODE
kendi bana karakterleri kodlamaz. Bu sistemde tanmlanan karakterleri kodlama ii kod
zclerin grevidir.
UNICODE sistemi iinde UTF-1, UTF-7, UTF-8, UTF-16 ve UTF-32 adl kod zcler bulunur.
UTF-8, UNICODE sistemi iindeki en yaygn, en bilinen ve en kullanl kod zcdr.
UTF-8 adl kod zcnn kodlayabildii karakterlerin listesine
http://www.leformat.info/info/charset/UTF-8/list.htm adresinden ulaabilirsiniz. Bu
listenin sayfalar dolusu olduuna ve her sayfaya, sayfann en altndaki More... balants ile
ulaabileceinize dikkat edin.

29.3.3 1 Karakter != 1 Bayt

ASCII sisteminde her karakterin 1 bayta karlk geldiini sylemitik. Ancak 1 bayt dnyadaki
btn karakterleri kodlamaya yetmez. Geri kalan karakterleri de kodlayabilmek iin 1 bayttan
fazlasna ihtiyacmz var. Mesela karakter kodlama iin:
1 bayt kullanrsak toplam 2**8 = 256
2 bayt kullanrsak toplam 2**16 = 65,536
3 bayt kullanrsak toplam 2**24 = 16,777,216
4 bayt kullanrsak toplam 2**32 = 4,294,967,296

karakter kodlayabiliriz. Bu durumu u Python kodlar ile de gsterebiliriz:

29.3. UNICODE 451


Python 3 iin Trke Klavuz, Srm 3

>>> for i in range(1, 5):


... print("{} bayt kullanrsak toplam 2**{:<2} = {:,}".format(i, i*8, (2**(i*8))))

Grne gre biz 4 baytlk bir sistem kullanrsak gelmi gemi btn karakterleri rahatlkla
temsil etmeye yetecek kadar alana sahip oluyoruz. Ancak burada yle bir durum var.
Bildiiniz gibi, 0 ile 256 aralndaki karakterler yalnzca 1 bayt ile temsil edilebiliyor. 256
ile 65,536 arasndaki karakterler iin ise 2 bayt yeter. Ayn ekilde 65,536 ile 16,777,216
aralndaki saylar iin de 3 bayt yeterli. Bu durumda eer biz btn karakterleri 4 bayt
ile temsil edecek olursak, korkun derece bir israfa dm oluruz. nk ASCII gibi bir
kodlama sisteminde yalnzca 1 bayt ile temsil edilebilecek bir karakterin kaplad alan bu
sistemle bou bouna 4 kat artm olacaktr.
Bu sorunun zm elbette sabit boyutlu karakter kodlama biimleri yerine deiken boyutlu
karakter kodlama biimleri kullanmaktr. te UNICODE sistemi iindeki UTF-8 adl kod
zc, karakterleri deiken sayda baytlar halinde kodlayabilir. UTF-8, UNICODE sistemi
iinde tanmlanm karakterleri kodlayabilmek iin 1 ile 4 bayt aras deerleri kullanr. Bylece
de bu kod zc UNICODE sistemi iinde tanmlanm btn karakterleri temsil edebilir.
Bu durumu bir rnek zerinden gstermeye alalm:
harfler = "abcdefghijklmnoprstuvyz"
for s in harfler:
print("{:<5}{:<15}{:<15}".format(s,
str(s.encode("utf-8")),
len(s.encode("utf-8"))))

Buradan una benzer bir kt alyoruz:


a b'a' 1
b b'b' 1
c b'c' 1
b'\xc3\xa7' 2
d b'd' 1
e b'e' 1
f b'f' 1
g b'g' 1
b'\xc4\x9f' 2
h b'h' 1
b'\xc4\xb1' 2
i b'i' 1
j b'j' 1
k b'k' 1
l b'l' 1
m b'm' 1
n b'n' 1
o b'o' 1
b'\xc3\xb6' 2
p b'p' 1
r b'r' 1
s b's' 1
b'\xc5\x9f' 2
t b't' 1
u b'u' 1
b'\xc3\xbc' 2
v b'v' 1
y b'y' 1
z b'z' 1

452 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

Burada, s.encode("utf-8") komutunun baytlar (bytes ) trnden bir veri tipi verdiine
dikkat edin (baytlar veri tipini bir sonraki blmde ayrntl olarak inceleyeceiz). Karakter
dizilerinin aksine baytlarn format() adl bir metodu bulunmaz. Bu yzden, bu veri
tipini format() metoduna gndermeden nce str() fonksiyonu yardmyla karakter dizisine
dntrmemiz gerekiyor. Bu dntrme ilevini, alternatif olarak u ekilde de
yapabilirdik:
print("{:<5}{!s:<15}{:<15}".format(s,
s.encode("utf-8"),
len(s.encode("utf-8"))))

Hangi yntemi seeceiniz paa gnlnze kalm... Biz konumuza dnelim.


Yukardaki tabloda ilk stun Trk alfabesindeki tek tek hareri gsteriyor. kinci stun ise bu
harerin UTF-8 ile kodlandnda nasl grndn. Son stunda ise UTF-8 ile kodlanan Trk
harerinin ka baytlk yer kapladn gryoruz.
Bu tabloyu daha iyi anlayabilmek iin mesela buradaki harni ele alalm:
>>> ''.encode('utf-8')

b'\xc3\xa7'

Burada Pythonn kendi yerletirdii karakterleri karrsak (b ve \x gibi) elimizde u onaltl


say kalr:
c3a7

Bu onaltl saynn onlu sistemdeki karl udur:


>>> int('c3a7', 16)

50087

50087 saysnn ikili sayma sistemindeki karl ise udur:


>>> bin(50087)

'0b1100001110100111'

Grdnz gibi, bu say 16 bitlik, yani 2 baytlk bir saydr. Bunu nasl teyit edeceinizi
biliyorsunuz:
>>> (50087).bit_length()

16

http://www.leformat.info/info/charset/UTF-8/list.htm adresine gittiinizde de UTF-8


tablosunda harnin c3a7 saysyla eletirildiini greceksiniz.
Bir de UTF-8in a harni nasl temsil ettiine bakalm:
>>> "a".encode("utf-8")

b'a'

a har standart ASCII harerinden biri olduu iin Python dorudan bu harn kendisini
gsteriyor. Eer bu harn hangi sayya karlk geldiini grmek isterseniz u kodu
kullanabilirsiniz:

29.3. UNICODE 453


Python 3 iin Trke Klavuz, Srm 3

>>> ord("a")

97

Daha nce de sylediimiz gibi, UNICODE sistemi ASCII ile uyumludur. Yani ASCII sisteminde
tanmlanm bir harf hangi say deerine sahipse, UNICODE iindeki btn kod zcleri de
o harf iin ayn sayy kullanr. Yani mesela a har hem ASCIIde, hem UTF-8de 97 says ile
temsil edilir. Bu say 256dan kk olduu iin yalnzca 1 bayt ile temsil edilir. Ancak standart
ASCII dnda kalan karakterler, farkl kod zcler tarafndan farkl saylarla eletirilecektir.
Bununla ilgili yle bir alma yapabiliriz:
kod_zcler = ['UTF-8', 'cp1254', 'latin-1', 'ASCII']

harf = ''

for k in kod_zcler:
try:
print("'{}' karakteri {} ile {} olarak "
"ve {} saysyla temsil edilir.".format(harf, k,
harf.encode(k),
ord(harf)))
except UnicodeEncodeError:
print("'{}' karakteri {} ile temsil edilemez!".format(harf, k))

Bu program altrdmzda una benzer bir kt alrz:


'' karakteri UTF-8 ile b'\xc4\xb0' olarak ve 304 saysyla temsil edilir
'' karakteri cp1254 ile b'\xdd' olarak ve 304 saysyla temsil edilir.
'' karakteri latin-1 ile temsil edilemez!
'' karakteri ASCII ile temsil edilemez!

Bu ufak program kullanarak hangi karakterin hangi kod zc ile nasl temsil edildiini (veya
temsil edilip edilemediini) grebilirsiniz.

29.3.4 Eksik Karakterler ve encode Metodu

Dediimiz ve rneklerden de grdmz gibi, her karakter her kod zc ile


zlemeyebilir. Mesela Windows-1254 adl kod sayfasnda bulunan bir karakter
Windows-1250 adl kod sayfasnda bulunamadnda, bulunmayan karakterin yerine bir soru
iareti (veya baka bir simge) yerletirilecektir.
Aslnda siz bu olguya hi yabanc deilsiniz. nternette dolarken mutlaka anlamsz
karakterlerle dolu web sayfalaryla karlamsnzdr. Bu durumun sebebi, ilgili sayfann
dil kodlamasnn (encoding ) dzgn belirtilmemi olmasdr. Yani sayfann HTML kodlar
arasnda meta charset etiketi ya hi yazlmam ya da yanl yazlmtr. Eer bu etiket hi
yazlmamsa, Internet taraycnz dil kodlamasnn ne olduunu kendince tahmin etmeyece
alacak, ounlukla da yanl bir karar verecektir. Taraycnz metnin dilini dzgn
tespit edemedii iin de bu metni yanl bir karakter tablosu ile eletirecek, o karakter
tablosunda tanmlanmam karakterler yerine bir soru iareti veya baka anlamsz bir simge
yerletirecektir. Metni dzgn grntleyebilmek iin taraycnzn dil kodlamasnn yapld
men esini bulup, doru dil kodlamasn kendiniz seeceksiniz. Byle bir eyi hayatnz
boyunca en az bir kez yapmak zorunda kaldnza eminim...
Bir karakter kmesinde herhangi bir karakter bulunamadnda, bulunamayan bu karakterin
yerine neyin gelecei, tamamen aradaki yazlma baldr. rnein sz konusu olan bir Python

454 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

programysa, ilgili karakter bulunamadnda ntanml olarak bu karakterin yerine hibir ey


koyulmaz. Onun yerine program kmeye braklr... Ancak byle bir durumda ne yaplacan
isterseniz kendiniz de belirleyebilirsiniz.
Bunun iin karakter dizilerinin encode() metodunun errors adl parametresinden
yararlanacaz. Bu parametre drt farkl deer alabilir:
Parametre Anlam
strict Karakter temsil edilemiyorsa hata verilir
ignore Temsil edilemeyen karakter grmezden gelinir
replace Temsil edilemeyen karakterin yerine bir ? iareti koyulur
xmlcharrefreplace Temsil edilemeyen karakter yerine XML karl koyulur
Bu parametreleri yle kullanyoruz:
>>> "bu Trke bir cmledir.".encode("ascii", errors="strict")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xfc' in
position 4: ordinal not in range(128)

strict zaten ntanml deerdir. Dolaysyla eer errors parametresine herhangi bir deer
vermezsek Python sanki strict deerini vermiiz gibi davranacak ve ilgili karakter kodlamas
ile temsil edilemeyen bir karakter ile karlaldnda hata verecektir:
>>> "bu Trke bir cmledir.".encode("ascii")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\xfc' in
position 4: ordinal not in range(128)

Gelelim teki deerlerin ne yaptna:


>>> "bu Trke bir cmledir.".encode("ascii", errors="ignore")

b'bu Trke bir cmledir.'

Grdnz gibi, errors parametresine ignore deerini verdiimizde, temsil edilemeyen


karakterler grmezden geliniyor:
>>> "bu Trke bir cmledir.".encode("ascii", errors="replace")

b'bu T?rk?e bir c?mledir.'

Burada ise replace deerini kullandk. Bylece temsil edilemeyen karakterlerin yerine birer
? iareti koyuldu:
>>> "bu Trke bir cmledir.".encode("ascii", errors="xmlcharrefreplace")

b'bu T&#252;rk&#231;e bir c&#252;mledir.'

Son olarak ise xmlcharrefreplace deerinin ne yaptn gryoruz. Eer errors


parametresine xmlcharrefreplace deerini verecek olursak, temsil edilemeyen her bir harf
yerine o harn XML karl yerletirilir. Bu deer, programnzdan alacanz kty bir XML
dosyasnda kullanacanz durumlarda iinize yarayabilir.

29.3. UNICODE 455


Python 3 iin Trke Klavuz, Srm 3

29.3.5 Dosyalar ve Karakter Kodlama

Dosyalar konusunu anlatrken, Pythonda bir dosyann open() fonksiyonu ile alacan
sylemitik. Bildiiniz gibi open() fonksiyonunu u ekilde kullanyoruz:
>>> f = open(dosya_ad, dosya_ama_kipi)

Burada biz open() fonksiyonunu iki farkl parametre ile birlikte kullandk. Ancak aslnda
belirtmemiz gereken nemli bir parametresi daha var bu fonksiyonun. te bu parametrenin
ad encoding dir.
Gelin imdi bu parametrenin ne olduuna ve nasl kullanldna bakalm:

encoding

Tahmin edebileceiniz gibi, encoding parametresi bir dosyann hangi kod zc ile
alacan belirtmemizi salar. Pythonda dosyalar ntanml olarak locale adl bir modln
getpreferredencoding() adl fonksiyonunun gsterdii kod zc ile alr. Siz de
dosyalarnzn varsaylan olarak hangi kod zc ile alacan renmek iin u komutlar
yazabilirsiniz:
>>> import locale
>>> locale.getpreferredencoding()

te eer siz encoding parametresini belirtmezseniz, dosyalarnz yukardaki ktda grnen


kod zc ile alacaktr.
GNU/Linux datmlarnda bu kt ounlukla UTF-8 olacaktr. O yzden GNU/Linuxta
dosyalarnz muhtemelen encoding belirtmeseniz bile dzgn grnecektir. Ancak
Windowsta locale.getpreferredencoding() deeri cp1254 olaca iin, mesela UTF-8 ile
kodlanm dosyalarnzda zellikle Trke karakterler dzgn grntlenemeyecektir. O
yzden, dosyalarnzn hangi kod zc ile kodlanm olduunu open() fonksiyonuna
vereceiniz encoding parametresi araclyla her zaman belirtmelisiniz:
>>> f = open(dosya, encoding='utf-8')

Diyelim ki amak istediiniz dosya cp1254 adl kod zc ile kodlanm olsun. Eer siz bu
dosyay aarken cp1254 adl kod zcy deil de baka bir kod zcy yazarsanz elbette
dosyadaki karakterler dzgn grntlenemeyecektir.
rnein cp1254 ile kodlanm bir belgeyi UTF-8 ile amaya kalkrsanz veya siz hibir kod
zc belirtmediiniz halde kullandnz iletim sistemi ntanml olarak dosyalar amak
iin cp1254 harici bir kod zcy kullanyorsa, dosyay okuma esnasnda una benzer bir
hata alrsnz:
>>> f = open("belge.txt", encoding="utf-8")
>>> f.read(50)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
File "C:\Python33\lib\codecs.py", line 300, in decode
(result, consumed) = self._buffer_decode(data, self.errors, final)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xde in position 79: invalid
continuation byte

456 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, dosyamz bizim kullanmaya altmz kod zcden (UTF-8) farkl bir
kod zc ile (cp1254) kodlanm olduu iin, doal olarak karakterler doru saylarla
eletirilemiyor. Bu da kanlmaz olarak yukardaki hatann verilmesine sebep oluyor.
Aslnda siz bu hatay tanyorsunuz. encode() metodunu anlatrken bunun ne olduundan ve
bu hataya kar neler yapabileceinizden sz etmitik.
Hatrlarsanz bu tr hatalara kar ne tepki verileceini belirleyebilmek iin encode()
metodunda errors adl bir parametreyi kullanabiliyorduk. te open() fonksiyonunda da ayn
errors parametresi bulunur.

errors

Dediimiz gibi, bir dosyann doru grntlenebilmesi ve okunabilmesi iin, sahip olduu
kodlama biiminin doru olarak belirtilmesi gerekir. Ama okuyacanz dosyalarn hangi
kodlama sistemine sahip olduunu doru tahmin etmeniz her zaman mmkn olmayabilir.
Byle durumlarda, programnzn kmesini nlemek iin eitli stratejiler belirlemeniz
gerekir.
Bir nceki blmde verdiimiz rnekten de grdnz gibi, eer Python, almaya allan
dosyadaki karakterleri encoding parametresinde gsterilen kod zc ile zemezse
ntanml olarak bir hata mesaj retip programdan kacaktr. Ancak sizin istediiniz ey her
zaman bu olmayabilir. Mesela dosyadaki karakterler doru kodlanamasa bile programnzn
kmemesini tercih edebilirsiniz. te bunun iin errors parametresinden yararlanacaksnz.
Bu parametreyi encoding() metodundan hatrlyorsunuz. Bu parametre orada nasl
kullanlyorsa, open() fonksiyonunda da ayn ekilde kullanlr. Dikkatlice bakn:
>>> f = open(dosya_ad, encoding='utf-8', errors='strict')

Bu zaten errors parametresinin ntanml deeridir. Dolaysyla strict deerini belirtmeseniz


de ntanml olarak bu deeri belirtmisiniz gibi davranlacaktr.
>>> f = open(dosya_ad, encoding='utf-8', errors='ignore')

Burada ise ignore deerini kullanarak, Pythonn kodlanamayan karakterleri grmezden


gelmesini salyoruz.
>>> f = open(dosya_ad, encoding='utf-8', errors='replace')

replace deeri ise kodlanamayan karakterlerin yerine \ufffd karakterini yerletirecektir.


Bu karakter ilev bakmndan, encode() metodunu anlatrken grdmz ? iaretine
benzer. Bu karaktere teknik olarak UNICODE Deitirme Karakteri (UNICODE Replacement
Character ) ad verilir. Baz yerlerde bu karakteri elmas eklinde siyah bir kp iine
yerletirilmi soru iareti eklinde grebilirsiniz.
Peki encode() metodunu anlatrken errors parametresi ile birlikte kullanabildiimiz
xmlcharrefreplace deerini open() fonksiyonu ile birlikte kullanabilir miyiz?
Hayr, open() fonksiyonu, errors parametresinde bu deerin kullanlmasna izin vermez.

29.3. UNICODE 457


Python 3 iin Trke Klavuz, Srm 3

29.4 Konu ile ilgili Fonksiyonlar

Bu blmde, karakter kodlama ilemleri esnasnda iimize yarayacak baz fonksiyonlar ele
alacaz.

29.4.1 repr()

nceleyeceimiz ilk fonksiyonun ad repr(). Esasnda biz bu fonksiyonu nceki derslerimizde


de birka rnekte kullanmtk. Belki o zaman bu fonksiyonun ne ie yaradn
deneme-yanlma yoluyla anlam olabilirsiniz. Eer henz bu fonksiyonun grevini
anlamadysanz da mesele deil. Bu blmde bu fonksiyonu ve ilevini ayrntl bir ekilde
anlatmaya alacaz.
Dilerseniz repr() fonksiyonunu anlatmaya bir rnek ile balayalm.
imdi Pythonn etkileimli kabuunu aarak u kodu yazn:
>>> "Python programlama dili"

Bu kodu yazp ENTER dmesine bastnzda yle bir kt alacanz biliyorsunuz:


>>> 'Python programlama dili'

Dikkat ettiyseniz, yukardaki kodlarn ktsnda karakter dizisi trnak iaretleri iinde
gsteriliyor. Eer bu karakter dizisini print() fonksiyonu iine yazarsanz o trnak iaretleri
kaybolacaktr:
>>> print("Python programlama dili")

Python programlama dili

Peki bu iki farkl ktnn sebebi ne?


Python programlama dilinde nesneler iki farkl ekilde temsil edilir:
1. Pythonn grecei ekilde
2. Kullancnn grecei ekilde
Yukardaki ilk kullanm, yazdmz kodu Python programlama dilinin nasl grdn
gsteriyor. kinci kullanm ise ayn kodu bizim nasl grdmz gsteriyor. Zaten bu
yzden, etkileimli kabukta print() fonksiyonu iinde yazmadmz karakter dizilerinin
ktlarn ekranda grebildiimiz halde, ayn karakter dizilerini bir dosyaya yazp
kaydettiimizde ekranda kt olarak grebilmek iin bunlar print() fonksiyonu iine
yazmamz gerekiyor.
Bu sylediklerimiz biraz karmak gelmi olabilir. sterseniz ne anlatmaya altmz daha
ak bir rnek zerinde gsterelim. imdi tekrar etkileimli kabuu ap u kodu altralm:
>>> "birinci satr\n"

Bu komut bize u kty verdi:


'birinci satr\n'

imdi ayn kodu bir de yle yazalm:

458 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

>>> print("birinci satr\n")

birinci satr

Grdnz gibi, ilk kodun ktsnda satr ba karakteri (\n ) grnrken, ikinci kodun
ktsnda bu karakter grnmyor (ama ilevini yerine getiriyor. Yani satr bana geilmesini
salyor).
te bunun sebebi, ilk kodun Pythonn bak asn yanstrken, ikinci kodun bizim bak
amz yanstmasdr.
Peki bu bilgi bizim ne iimize yarar?
imdi yle bir rnek dnn:
Diyelim ki elimizde yle bir deiken var:
>>> a = "elma "

imdi bu deikeni ekrana kt olarak verelim:


>>> print(a)

elma

Grdnz gibi, bu ktya bakarak, a deikeninin tuttuu karakter dizisinin son tarafnda
bir adet boluk karakteri olduunu anlayamyoruz. Bu yzden bu deikeni yle bir program
iinde kullanmaya altmzda neden bozuk bir kt elde ettiimizi anlamak zor olabilir:
>>> print("{} kilo {} kald!".format(23, a))

23 kilo elma kald!

Grdnz gibi, elma karakter dizisinin son tarafnda bir boluk olduu iin elma ile kald
kelimeleri arasnda gereksiz bir aklk meydana geldi.
Bu boluu print() ile gremiyoruz, ama bu deikeni print() olmadan yazdrdmzda o
boluk da grnr:
>>> a

'elma '

Bu sayede programnzdaki aksaklklar giderme imkan kazanm olur, u kodu yazarak


gereksiz boluklar atabilirsiniz:
>>> print("{} kilo {} kald!".format(23, a.strip()))

23 kilo elma kald!

Daha nce de dediimiz gibi, banda print() olmayan ifadeler, bir dosyaya yazlp
altrldnda ktda grnmez. O halde biz yukardaki zellikten yazdmz programlarda
nasl yararlanacaz. te burada yardmmza repr() adl bir fonksiyon yetiecek. Bu
fonksiyonu yle kullanyoruz:
print(repr("karakter dizisi\n"))

Bu kodu bir dosyaya yazp kaydettiimizde yle bir kt alyoruz:

29.4. Konu ile ilgili Fonksiyonlar 459


Python 3 iin Trke Klavuz, Srm 3

'karakter dizisi\n'

Grdnz gibi hem trnak iaretleri, hem de satr ba karakteri ktda grnyor. Eer
repr() fonksiyonunu kullanmasaydk yle bir kt alacaktk:
karakter dizisi

repr() fonksiyonu zellikle yazdmz programlardaki hatalar zmeye alrken ok iimize


yarar. nk print() fonksiyonu, kullancnn gzne daha cazip grnecek bir kt
retebilmek iin arkaplanda neler olup bittiini kullancdan gizler. te arkaplanda neler
dndn, print() fonksiyonunun bizden neleri gizlediini grebilmek iin bu repr()
fonksiyonundan yararlanabiliriz.

Not: repr() fonksiyonu ile ilgili gerek hayattan bir rnek iin
istihza.com/blog/windows-python-3-2de-bir-hata.html adresindeki yazmz okuyabilirsiniz.

Btn bu aklamalar bize unu sylyor: repr() fonksiyonu, bir karakter dizisinin Python
tarafndan nasl temsil edildiini gsterir. Yukarda biz bu fonksiyonun nasl kullanldna dair
ayrntlar verdik. Ancak bu fonksiyonun, yine yukardaki ileviyle balantl olmakla birlikte
biraz daha farkl grnen bir ilevi daha bulunur.
Hatrlarsanz, ilk derslerimizde r adl bir ka dizisinden sz etmitik. Bu ka dizisini yle
kullanyorduk:
print(r"\n")

Bildiiniz gibi, \n ka dizisi bir alt satra gememizi salyor. te r adl ka dizisi \n ka
dizisinin bu ilevini basklayarak, bizim \n ka dizisinin kendisini kt olarak verebilmemizi
salyor.
O halde bu noktada size yle bir soru sormama izin verin:
Acaba bir deikene atanm ka dizilerinin ilevini nasl basklayabiliriz? Yani mesela
elimizde yle bir deiken bulunuyor olsun:
yeni_satr = "\n"

Biz bu deikenin deerini nasl ekrana yazdracaz?


Eer bunu dorudan print() fonksiyonuna gnderirsek ne olacan biliyorsunuz: Yeni satr
karakteri ilevini yerine getirecek ve biz de yeni satr karakterinin kendisini deil, yapt iin
sonucunu (yani satr bana geildiini) greceiz.
te bu tr durumlar iin de repr() fonksiyonundan yararlanabilirsiniz:
print(repr('\n'))

Bylece satr ba karakterinin ilevi basklanacak ve biz ktda bu karakterin kendisini


greceiz.
Hatrlarsanz ASCII konusunu anlatrken yle bir rnek vermitik:
for i in range(128):
if i % 4 == 0:
print("\n")

print("{:<3}{:>8}\t".format(i, repr(chr(i))), sep="", end="")

460 Blm 29. Karakter Kodlama (Character Encoding )


Python 3 iin Trke Klavuz, Srm 3

te burada, repr() fonksiyonunun yukarda szn ettiimiz ilevinden yararlanyoruz.


Eer bu kodlarda repr() fonksiyonunu kullanmazsak, ASCII tablosunu oluturan karakterler
arasndaki \n, \a, \t gibi ka dizileri ekranda grnmeyecek, bunun yerine bu ka dizileri
dorudan ilevlerini yerine getirecek, bu da bizim istediimiz ASCII tablosunu retmemize
engel olacaktr.

29.4.2 ascii()

ascii() fonksiyonu biraz nce rendiimiz repr() fonksiyonuna ok benzer. rnein:


>>> repr("asds")

"'asds'"

>>> ascii("asds")

"'asds'"

Bu iki fonksiyon, ASCII tablosunda yer almayan karakterlere kar tutumlar ynnden
birbirlerinden ayrlr. rnein:
>>> repr("")

"''"

>>> ascii("")

"'\\u0130'"

Grdnz gibi, repr() fonksiyonu ASCII tablosunda yer almayan karakterleri de


grndkleri gibi temsil ediyor. ascii() fonksiyonu ise bu karakterlerin UNICODE kod
konumlarn (code points ) gsteriyor.
Bir rnek daha verelim:
>>> repr("")

"''"

>>> ascii("")

"'\\u20ac'"

ascii() fonksiyonunun UNICODE kod konumlarn gsterme zelliinin bir benzerini daha
nce rendiimiz encode() metodu yardmyla da elde edebilirsiniz:
>>> "".encode("unicode_escape")

b'\\u20ac'

Ancak ascii() fonksiyonunun str tipinde, encode() metodunun ise bytes tipinde bir kt
verdiine dikkat edin.

29.4.3 ord()

Bu fonksiyon, bir karakterin say karln verir:

29.4. Konu ile ilgili Fonksiyonlar 461


Python 3 iin Trke Klavuz, Srm 3

>>> ord("\n")

10

>>> ord("")

8364

29.4.4 chr()

Bu fonksiyon, bir saynn karakter karln verir:


>>> chr(10)

'\n'

>>> chr(8364)

''

462 Blm 29. Karakter Kodlama (Character Encoding )


BLM 30

Baytlar (Bytes) ve Bayt Dizileri (Bytearrays)

Bu blme gelinceye kadar veri tipi olarak karakter dizilerinden, listelerden ve dosyalardan
sz etmitik. Bu blmde ise Python programlama dilindeki iki veri tipinden daha sz
edeceiz. Birbirleriyle dorudan balantl olduklar iin bu blmde birlikte ele alacamz
bu veri tiplerinin ad baytlar(bytes ) ve bayt dizileri (bytearrays ).
Bu blmde yalnzca baytlar ve bayt dizileri adl veri tiplerinden sz etmeyeceiz. Bu iki yeni
veri tipini bilgi daarcmza eklemenin yansra, nceki blmlerde rendiimiz konular
zihnimizde pekitirmeye ve salamlatrmaya da devam edeceiz.

30.1 Giri

Bilgisayar teknolojisi ve bilimi asndan karakter tamamen soyut bir kavramdr. Son birka
blmdr stne basa basa tekrar ettiimiz gibi, karakter dediimiz ey, bilgisayarlarn
anlayabildii tek kavram olan saylara biz insanlarn atad birtakm iaretlerden ibarettir.
Dolaysyla bilgisayarlar asndan karakterler deil, ikili sayma dzenindeki birtakm saylar,
yani bitler ve baytlar vardr.
Teknik olarak 1 bit, ikili sayma sistemindeki her bir basamaa verilen isimdir. Zaten bit
kelimesinin de ngilizcede ikili basamak anlamna gelen binary digit ifadesinin ksaltmas
olduunu geen blmde renmitiniz.
rnein ikili sayma sistemindeki 0, bir bitlik bir say iken, 100 bitlik bir saydr. Bu bitlerin
8 tanesi bir araya gelince bayt denen birimi oluturur. Yani bayt, 8 adet bitten oluan bir
birimdir. Nasl bir dzinede 10, bir destede de 12 e olmasn biz insanlar tercih etmi ve
belirlemisek, bir baytta da 8 bit olmasn yine biz insanlar tercih etmi ve belirlemiizdir.
nceki derslerimizde de rendiimiz gibi, 8 adet bit, yani 1 bayt, Geniletilmi ASCII
sisteminde bir adet karakteri temsil etmek iin kullanlabilecek en byk birim olarak
tasarlanmtr. Yani Geniletilmi ASCII tablolarnn en sonundaki 255 numaral karakteri
temsil edebilmek iin 8 adet bit, yani toplam 1 bayt kullanmamz gerekir. Standart ASCII
sistemi ise 7 bitlik bir sistem olduu iin, bir adet karakteri temsil etmek iin kullanlabilecek
en byk birimin 7 bit olduunu biliyorsunuz. Dolaysyla ASCII sistemindeki son karaktere
karlk gelen 127. sayy temsil edebilmek iin toplam 7 bit yeterlidir.
Farkl bir sistem olan UTF-8 ise birden fazla bayt kullanarak ok sayda karakteri temsil etmeye
imkan tanr. UTF-8 ile, duruma gre 1, 2, 3 veya 4 bayt kullanarak, UNICODE sistemi iinde
tanmlanm btn karakterleri temsil edebilirsiniz. UTF-8, deiken boyutlu bir kodlama
sistemi olmas sayesinde, bir karakteri temsil edebilmek iin ka bayt gerekiyorsa, o karakteri
temsil etmek iin o kadar bayt kullanr. Ama mesela UTF-32 adl kod zc hangi karakter

463
Python 3 iin Trke Klavuz, Srm 3

olursa olsun hepsini 4 bayt (32 bit) ile temsil eder. Bu durumda aslnda tek baytla temsil
edilebilecek a, b, c gibi karakterler de bou bouna 4 bayt yer kaplam olur. Zaten UTF-8in
bu kadar yaygn ve gzde olmasnn nedeni de hem ok sayda karakteri kodlayabilmesi, hem
de bu ii yaparken tasarruu olmay baarabilmesidir.
Python programlama dilinde karakter dizileri UNICODE kod konumlar eklinde temsil
edilir. Dolaysyla str ad verilen veri tipi esasnda karakter dizilerini birtakm UNICODE kod
konumlar eklinde gsteren soyut bir yapdr. Yani biz Pythonda karakter dizileri zerinde
ilem yaparken aslnda baytlarla deil, UNICODE kod konumlar ile muhatap oluyoruz. Ancak
UNICODE kod konumlar da tamamen soyut kavramlardr. Bunlar bilgisayarn belleinde
bu ekilde temsil edemezsiniz ya da bu kod konumlarn herhangi bir a zerinden baka
bilgisayarlara iletemezsiniz. Bu kod konumlarn anlaml bir ekilde kullanabilmek iin
ncelikle bunlar bilgisayarlarn anlayabilecei bir biim olan baytlara evirmeniz gerekir.
nk dediimiz gibi bilgisayarlar yalnzca bitler ve baytlardan anlar. te kod zclerin
grevi de zaten bu kod konumlarn baytlara evirmektir.
Esasnda programclk maceranz boyunca genellikle metin ihtiyalarnz UNICODE kod
konumlar zerinden halledeceksiniz. Python sistemdeki ntanml kod zcy kullanarak
bu kod konumlarn alttan alta bayta evirip bellekte saklayacaktr. Ama eer yazdnz
programlarda herhangi bir ekilde dorudan baytlarla muhatap olmanz gerekirse str veri
tipini deil, bytes adl baka bir veri tipini kullanacaksnz. rnein ikili (binary ) dosyalar
zerinde eitli almalar yapacaksanz ve bu ikili dosyalara birtakm veriler girecekseniz,
gireceiniz bu veriler bytes tipinde olacaktr.
Btn bu sebeplerden tr, str ve bytes veri tipleri arasndaki fark anlamak, yazdnz
programlarn kararll ve salaml asndan byk nem tar. O anda elinizde olan
verinin hangi tipte olduunu bilmezseniz, bu verinin, programnzn almas esnasnda
size ne tr tuzaklar kurabileceini de kestiremezsiniz. rnein btn karakterlerin 1 bayt
olduunu ve bunlarn da yalnzca 0 ile 127 aras saylarla temsil edilebileceini zanneden
yazlmclarn tasarlad programlara Trke karakterler girdiinizde nasl bu programlar
patr patr dklyorsa, eer siz de baytlar ve karakterler arasndaki fark anlamazsanz sizin
yazdnz programlar da hi beklemediiniz bir anda tkezleyebilir.
rnein yazdnz bir programn bir aamasnda programa yalnzca tek karakterlik verilerin
girilmesi temeli zerinden bir ilem yaptnz dnn. Yani programnz iinde yapacanz
bir ilem, birden fazla karakter giriinin engellenmesini gerektiriyor olsun.
Bunun iin yle bir ey yazm olun:
a = "k"

if len(a) > 1:
print("Ltfen yalnzca tek bir karakter giriniz!")
else:
print("Teekkrler!")

Ben burada temsili olarak a adl bir deiken oluturdum ve rnek olmas asndan da bunun
deerini k olarak belirledim. Bu deerlerle programmz dzgn bir ekilde alr. nk a
deikeninin deeri tek bir karakter olan k har. Ama eer a deikeninin deeri mesela kz
gibi bir ey olsayd programmz Ltfen yalnzca tek bir karakter giriniz! uyars verecekti...
imdi bu a deikeninin sizin tarafnzdan belirlenmediini, bu deerin baka bir kaynaktan
geldiini dnn. Eer size bu deeri gnderen kaynak, bu deeri UNICODE kod konumu
olarak gnderiyorsa programnz dzgn alr. Ama peki ya gelen bu veri bayt olarak
geliyorsa ne olacak?

464 Blm 30. Baytlar (Bytes) ve Bayt Dizileri (Bytearrays)


Python 3 iin Trke Klavuz, Srm 3

Yukarda verdiimiz rnein neden nemli olduunu, daha dorusu bu rnekle ne demek
istediimiz ve nereye varmaya altmz anlamam olabilirsiniz. Ama endie etmenize
hi gerek yok. Zira bu blmde yukarda sorduumuz sorunun cevabn derinlemesine ele
alacaz. Bu blmn sonuna vardmzda neler olup bittiini ve baytlarn neden bu kadar
nemli olduunu gayet iyi anlyor olacaksnz.

30.2 Eskisi ve Yenisi

Gelin isterseniz tam olarak ne ile kar karya olduumuzu daha iyi anlayabilmek iin Python3
ncesi durumun nasl olduuna bakalm. Eer gemite Python programlama dilinin karakter
dizileri ve baytlar nasl ele aldn bilirsek bugnk durumu ve dolaysyla genel olarak
karakter dizisi ve bayt kavramn ok daha net bir ekilde kavrayabiliriz.
Pythonn 2.x srmlerinde, bir karakter dizisi tanmladnzda Python bu karakter dizisini bir
bayt dizisi olarak temsil ediyordu. rnein:
>>> kardiz = "e"

Burada kardiz adl deikenin deeri, bir baytlk bir karakter dizisidir. Bunu len() fonksiyonu
ile teyit edelim:
>>> len(kardiz)

Bir de una bakalm:


>>> kardiz = ""

Burada ise kardiz adl deikenin deerinin ka baytlk bir karakter dizisi olduu, yani bir
bakma len() fonksiyonunun ne kt verecei iletim sisteminden iletim sistemine farkllk
gsterir. Eer kullandnz iletim sistemi Windows ise muhtelemen len(kardiz) komutu
1 kts verecektir. Ama eer bu komutu GNU/Linux datmlarndan birinde veriyorsanz
alacanz kt byk ihtimalle 2 olacaktr.
Dediimiz gibi, Python2de str veri tipi bize bir dizi bayt verir. Dolaysyla bu veri tipinin iinde
tuttuu karakter dizisinin ka bayt ile gsterilecei, sistemdeki ntanml kod zcnn
hangisi olduuna baldr. Kullandnz iletim sisteminde ntanml kod zcnn hangisi
olduunu u komutla bulabilirsiniz:
>>> import locale
>>> locale.getpreferredencoding()

Eer Windows kullanyorsanz buradan alacanz kt muhtemelen cp1254 olacaktr. cp1254,


Microsoftun Trke iin zel olarak kulland bir kod sayfas olduu iin, 128 ile 256
saylar arasnda Trke karakterleri ierir. O yzden bu kodlama sisteminde Trke
karakterler 1 bayt ile gsterilebilir. Bu kod sayfasnn ieriinde hangi karakterlerin
hangi saylara karlk geldiini grmek iin en.wikipedia.org/wiki/Windows-1254 adresindeki
tabloyu inceleyebilirsiniz.
Ama eer yukardaki komutlarn kts UTF-8 veya baka bir kod zc ise, Trke karakterler
1 bayt ile gsterilemeyecei iin len(kardiz) komutu 1 deil, 2 kts verecektir.
Bir de una bakalm:

30.2. Eskisi ve Yenisi 465


Python 3 iin Trke Klavuz, Srm 3

>>> len("")

Bu komutu hangi iletim sisteminde verdiinize bal olarak yukardaki komuttan alacanz
kt farkl olacaktr. str tipi Python2de karakter dizilerini bayt olarak temsil eder. Bu temsilin
de hangi kurallara gre yaplaca kullanlan kod zcye baldr. Eer karakter dizileri
baytlara evrilirken cp1254 adl kod zc kullanlrsa, bu kod zc simgesini tek bayt
ile gsterilebildii iin yukardaki komut 1 kts verir. Ama UTF-8 adl kod zc simgesini
3 baytla gsterebildii iin yukardaki komutun kts da buna paralel olarak 3 olacaktr.
str veri tipi ile gsterilen bu karakter dizilerinin iindeki baytlara ulamak iin u yntemi
kullanabilirsiniz:
>>> ""[0]

'\xc5'

>>> ""[1]

'\x9f'

Grdnz gibi, str veri tipi gerekten de bize bir dizi bayt veriyor. Eer karakter dizilerini
baytlarna gre deil de sahip olduklar karakter saysna gre saymak isterseniz bunlar
UNICODE olarak tanmlanz gerekiyor:
>>> len(u'')

Python3 ile birlikte yukarda bahsettiimiz durumda baz deiiklikler oldu. Artk str veri tipi
UNICODE kod konumlarn dndryor. Dolaysyla artk her karakter dizisi, sahip olduklar
karakter saysna gre saylabiliyor:
>>> len("")

>>> len("")

te eer Python2deki str veri tipini elde etmek istiyorsanz, Python3te bytes adl yeni veri
tipini kullanmanz gerekiyor.

30.3 Bayt Tanmlamak

Bildiiniz gibi Python programlama dilinde her veri tipinin kendine zg bir tanmlanma
biimi var. rnein bir liste tanmlamak iin yle bir ey yazyoruz:
>>> liste = []

Bylece bo bir liste tanmlam olduk. Ayn ekilde karakter dizilerini de yle tanmlyorduk:
>>> kardiz = ''

Bu ekilde de bo bir karakter dizisi tanmlam olduk. te bo bir bayt tanmlamak iin de
u yapy kullanyoruz:

466 Blm 30. Baytlar (Bytes) ve Bayt Dizileri (Bytearrays)


Python 3 iin Trke Klavuz, Srm 3

>>> bayt = b''

Gelin tanmladmz bu veri tipinin bayt olduunu teyit edelim:


>>> type(bayt)

<class 'bytes'

Grdnz gibi, gerekten de bayt tipinde bir veri tanmlamz. Nasl karakter dizileri str,
listeler list ifadesiyle gsteriliyorsa, baytlar da bytes ifadesi ile gsterilir.
Peki bu ekilde bir bayt veri tipi tanmlamak ne iimize yarar?
Hatrlarsanz bayt veri tipini ikili (binary ) dosyalar anlatrken de grmtk. Orada da
sylediimiz gibi, ikili dosyalar okuduunuzda elde edeceiniz ey karakter dizisi deil bayttr.
Ayn ekilde, ikili dosyalara da ancak baytlar yazabilirsiniz. Dolaysyla eer ikili dosyalarla
birtakm ilemler yapacaksanz bu bayt veri tipini youn olarak kullanacanzdan hi pheniz
olmasn. Yani bayt veri tipi kolayca grmezden gelebileceiniz gereksiz bir veri tipi deildir.

30.4 bytes() Fonksiyonu

Bayt veri tipi temel olarak ASCII karakterleri kabul eder. Dolaysyla ASCII tablosu dnda
kalan karakterleri dorudan bayt olarak temsil edemezsiniz:
>>> b''

File "<stdin>", line 1


SyntaxError: bytes can only contain ASCII literal characters.

Ama ASCII dnda kalan karakterleri de bayta dntrmenin bir yolu var. Bunun iin
bytes() adl bir fonksiyondan yararlanacaz:
>>> b = bytes("", "utf-8")

Grdnz gibi, ilgili karakterin hangi kod zc ile kodlanacan belirterek, bayt tipinde
bir veri oluturabiliyoruz.
Tahmin edebileceiniz gibi, bytes() fonksiyonu, belirttiimiz kod zc ile kodlanamayan
karakterlerle karlalmas durumunda ne yaplacan belirlememizi salayan errors adl bir
parametreye de sahiptir:
>>> b = bytes("Frat", "ascii", errors="xmlcharrefreplace")
>>> b

b'F&#305;rat'

nceki derslerimizde errors parametresinin hangi deerleri alabileceini tartmtk. Orada


anlattmz eyler burada da geerlidir.

30.5 Baytlarn Metotlar

Btn veri tiplerinde olduu gibi, bytes adl veri tipinin de birtakm metotlar bulunur. Bu
metotlarn listesini almak iin u komutu kullanabileceinizi biliyorsunuz:

30.4. bytes() Fonksiyonu 467


Python 3 iin Trke Klavuz, Srm 3

>>> dir(bytes)

Listeye baktnzda bu metotlar karakter dizilerinin metotlar ile hemen hemen ayn
olduunu greceksiniz. Baytlarn metotlar arasnda olup da karakter dizilerinin metotlar
arasnda olmayan metotlar u ekilde elde edebilirsiniz:
>>> for i in dir(bytes):
... if i not in dir(str):
... print(i)

decode
fromhex

Grdnz gibi, decode() ve fromhex() adl metotlar baytlarda var, ama karakter dizilerinde
yok. O yzden biz de bu blmde yalnzca bu iki metodu incelemekle yetineceiz. nk teki
metotlar zaten karakter dizilerinden tanyorsunuz.

30.5.1 decode

Hatrlarsanz karakter dizilerinin encode() adl bir metodu vard. Bu metot yardmyla
karakter dizilerini belli bir kodlama biimine gre kodlayabiliyor, yani bunlar baytlara
evirebiliyorduk. Mesela harni UTF-8 ile kodlayalm:
>>> "".encode("utf-8")

b'\xc4\xb0'

Ayn har cp1254 ile kodlarsak u kty elde ederiz:


>>> "".encode("cp1254")

b'\xdd'

Tahmin edebileceiniz gibi, bu har ASCII ile kodlayamayz:


>>> "".encode("ascii")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u0130' in position 0:
ordinal not in range(128)

te bu kodlama ilemini tersine evirebilmek, yani baytlar belli bir kodlama biimine gre
karakter dizilerine dntrebilmek iin decode() metodundan yararlanacaz:
>>> b"\xc4\xb0".decode("utf-8")

''

Bu baytlar bir de baka kodlama sistemleri ile kodlamay deneyelim:


>>> b"\xc4\xb0".decode("cp1254")

''

Grdnz gibi, cp1254 adl kod zc bu bayt zebiliyor, ama yanl zyor! nk
bu baytn gsterdii say cp1254 adl kod sayfasnda ye deil, baka bir karaktere karlk

468 Blm 30. Baytlar (Bytes) ve Bayt Dizileri (Bytearrays)


Python 3 iin Trke Klavuz, Srm 3

geliyor. Aslnda baka iki karaktere, yani C4 ve B0 ile gsterilen ve karakterlerine karlk
geliyor... Bu durumu http://en.wikipedia.org/wiki/Windows-1254 adresine gidip kendiniz de
grebilirsiniz.
Bu baytlar bir de ASCII ile zmeye alalm:
>>> b"\xc4\xb0".decode("ascii")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 0: ordinal
not in range(128)

Elbette, bu karakter 128den byk bir sayya karlk geldii iin ASCII tarafndan
zlemeyecektir.

30.5.2 fromhex

Bu metot, onaltl sayma sistemindeki bir saydan oluan bir karakter dizisini alp, bayta
dntrr. Bu metodu yle kullanyoruz:
>>> bytes.fromhex("c4b0")

b'\xc4\xb0'

Grdnz gibi, bu metot bir onaltl say olan c4b0 alp, bize bir bayt nesnesi veriyor.

30.6 Bayt Dizileri

bytes adl veri tipi ile elde ettiimiz veri tpk karakter dizileri gibi, zerinde deiiklik
yaplamayan bir veridir. Dolaysyla bir bytes nesnesi zerinde deiiklik yapabilmek iin o
nesneyi tekrar tanmlamamz gerekir:
>>> b = b'PDF'
>>> v = b'-1.7'
>>> b = b + v
>>> b

b'PDF-1.7'

Ama Python programlama dilinde bytes veri tipi dnda, baytlara ilikin ikinci veri tipi daha
bulunur. bytearray adl bu veri tipi, bytes veri tipinin aksine, zerinde deiiklik yaplabilen
bir veri tipidir.
Pythonda bytearray veri tipini u ekilde tanmlyoruz:
>>> pdf = bytearray(b'PDF-1.7')

Grdnz gibi, bir bayt dizisi tanmlayabilmek iin bytearray() adl bir fonksiyondan
faydalanyoruz.

30.6. Bayt Dizileri 469


Python 3 iin Trke Klavuz, Srm 3

30.7 Bayt Dizilerinin Metotlar

Bayt dizileri bir bakma listelerle baytlarn karm gibidir. dir(bytearray) gibi bir komutla
bu veri tipinin metotlarn inceleyecek olursanz, bu veri tipinin hem baytlardan hem de
listelerden birtakm metotlar aldn grrsnz.
Bu veri tipi listelerin u metotlarna sahiptir:
1. append
2. clear
3. copy
4. count
5. extend
6. index
7. insert
8. pop
9. remove
10. reverse
Bu veri tipi baytlarn ise u metotlarna sahiptir:
1. capitalize
2. center
3. count
4. decode
5. endswith
6. expandtabs
7. nd
8. fromhex
9. index
10. isalnum
11. isalpha
12. isdigit
13. islower
14. isspace
15. istitle
16. isupper
17. join
18. ljust

470 Blm 30. Baytlar (Bytes) ve Bayt Dizileri (Bytearrays)


Python 3 iin Trke Klavuz, Srm 3

19. lower
20. lstrip
21. maketrans
22. partition
23. replace
24. rnd
25. rindex
26. rjust
27. rpartition
28. rsplit
29. rstrip
30. split
31. splitlines
32. startswith
33. strip
34. swapcase
35. title
36. translate
37. upper
38. zll

30.7. Bayt Dizilerinin Metotlar 471


BLM 31

Szlkler

u ana kadar Python programlama dilinde veri tipi olarak karakter dizilerini, saylar, listeleri,
demetleri ve dosyalar rendik. Yeni veri tipleri rendike Pythondaki hareket alanmzn
da genilediini siz de farketmisinizdir. Bu blmde yine Pythondaki nemli veri tiplerinden
birini inceleyeceiz. Bu defa inceleyeceimiz veri tipinin ad szlk. ngilizcede buna
dictionary diyorlar.
Szlkler de, tpk daha nceki derslerimizde rendiimiz karakter dizileri, saylar, listeler,
demetler ve dosyalar gibi programlama maceramz boyunca ilerimizi bir hayli kolaylatracak
ve hareket imkanmz geniletecek veri tiplerinden biridir.
teki veri tiplerinde olduu gibi, szlklerin de birtakm metotlar vardr. te bu blmde
hem genel olarak szlklerden sz edeceiz, hem de bu veri tipinin metotlarn en ince
ayrntsna kadar inceleyeceiz.
Szlk denen veri tipi Python programlama dilinin son derece kullanl ve ie yarar
aralarndan bir tanesidir. Programlama alannda ilerledike, bu veri tipinin neler
yapabileceini grp aracanz rahatlkla syleyebilirim.
Esasnda biz daha nceki derslerimizin birinde szlk adl bu veri tipinden stnkr de olsa
sz etmitik. Yani aslnda bu veri tipiyle tanklmz eskiye dayanyor.
Hatrlayacaksnz, karakter dizilerinin str.maketrans() ve translate() adl metotlarn
anlatrken, Trkeye zg karakterleri ve bunlarn noktasz karlklarn ieren eviri_tablosu
adn verdiimiz yle bir deiken tanmlamtk:

eviri_tablosu = {"": "O",


"": "c",
"": "U",
"": "C",
"": "I",
"": "i",
"": "G",
"": "o",
"": "s",
"": "u",
"": "S",
"": "g"}

Burada eviri_tablosu deikeni iinde gsterdiimiz biimin Pythondaki adnn szlk


olduunu da ifade etmitik. te bu blmde, orada yle bir deinip getiimiz bu veri tipini
ok daha ayrntl bir ekilde ele alma imkanmz olacak.

472
Python 3 iin Trke Klavuz, Srm 3

Hem eski bilgilerimize dayanarak, hem de yukarda anlattklarmzdan yola karak szlk veri
tipinin ne olduuna dair halihazrda kafamzda bir kir olumu olduunu syleyebiliriz.
Szlkler teki veri tiplerine kyasla biraz farkl bir grne sahip bir veri tipidir. Biz birazdan
szlklerin yapsn derinlemesine inceleyeceiz.
Ancak szlklerin yapsn incelemeye gemeden nce renmemiz gereken bir ey var.
Tpk teki veri tiplerinde olduu gibi, szlklerle de alabilmek iin ncelikle bu veri tipini
tanmlam olmamz gerekiyor. O yzden isterseniz szlklerin yapsndan sz etmeden nce
bir szl nasl tanmlayacamzdan bahsedelim.

31.1 Szlk Tanmlamak

Dediimiz gibi, karakter dizilerini anlatrken verdiimiz szlk rnei sayesinde szlklerin
neye benzediini az ok biliyoruz. Gelin isterseniz szlklerin nasl tanmlandn inceleyerek
bu veri tipinin derinliklerine doru ilk kulalarmz atalm.
Python programlama dilindeki szlk veri tipi, gerek hayatta szlk denince aklnza gelen
eye ok benzer. Mesela gerek hayatta kitap kelimesinin ngilizce bir szlkteki karl
book kelimesidir. Dolaysyla kitap ve book kelimeleri arasndaki ilikiyi herhalde u ekilde
temsil edebiliriz:
kitap: book
Bu manzara bize kitap kelimesinin karlnn book olduunu ak bir ekilde gsteriyor.
Eer bu durumu Pythondaki szlk veri tipiyle gstermek isteseydik yle bir ey yazacaktk:
>>> kelimeler = {"kitap": "book"}

Burada, ierii szlk veri tipi olan kelimeler adl bir deiken tanmladk. Grdnz gibi,
listelere benzer bir ekilde szlk veri tipi de iinde farkl veri tiplerini barndran, kapsayc
bir veri tipidir. Burada szlmz iki adet karakter dizisinden oluuyor.
Yukardaki szl nasl tanmladmza ok dikkat edin. Nasl ki listelerin ayrt edici zellii
keli parantezlerdi, szlklerin ayrt edici zellii de kme parantezleridir.
Esasnda szlk dediimiz ey en basit haliyle yle grnr:
>>> szlk = {}

Bu rnek bo bir szlktr. sterseniz yukardaki veri tipinin gerekten de bir szlk olduunu
kantlayalm:
>>> type(szlk)

<class 'dict'>

Szlklerin Python programlama dilindeki teknik karl dict ifadesidir. type(szlk)


sorgusu <class dict> kts verdiine gre, szlk adl deikenin gerekten de bir szlk
olduunu syleyebiliyoruz.
Yukarda yle bir szlk rnei verdiimizi hatrlyorsunuz:
>>> kelimeler = {"kitap": "book"}

Python programlama diline zellikle yeni balayanlar, szlklerin grn nedeniyle bir
szlkteki e says konusunda tereddte kaplabilir, rnein yukardaki szln 2 eden

31.1. Szlk Tanmlamak 473


Python 3 iin Trke Klavuz, Srm 3

olutuu yanlgsna debilir. O halde bu noktada size yle bir soru sormama izin verin:
Acaba bu szlkte ka e var? Hemen bakalm:
>>> len(kelimeler)

Demek ki elimizdeki veri tipi bir adet eye sahip bir szlkm. Grdnz gibi, "kitap":
"book" ifadesi tek bana bir e durumundadr. Yani burada kitap karakter dizisini ayr,
book karakter dizisini ayr bir e olarak almyoruz. Bu ikisi tek bir szlk esi oluturuyor.
Hatrlarsanz, listelerde eleri birbirinden ayrmak iin virgl iaretlerinden yararlanyorduk.
Szlklerde de birden fazla eyi birbirinden ayrmak iin virgl iaretlerinden yararlanacaz:
>>> kelimeler = {"kitap": "book", "bilgisayar": "computer"}

Bir nceki rnek tek eliydi. Bu szlk ise 2 eye sahiptir:


>>> len(kelimeler)

lk derslerimizden bu yana srekli olarak vurguladmz gibi, Python programlama dilinde


doru kod yazmak kadar okunakl kod yazmak da ok nemlidir. Mesela bir szl yle
tanmladmzda kodlarmzn pek okunakl olmayacan syleyebiliriz:
szlk = {"kitap": "book", "bilgisayar": "computer", "programlama": "programming",
"dil": "language", "defter": "notebook"}

Teknik olarak baktmzda bu kodlarda hibir problem yok. Ancak szlkleri byle saa doru
uzayacak ekilde tanmladmzda okunakll azaltm oluyoruz. Bu yzden yukardaki
szl yle yazmay tercih edebiliriz:
szlk = {"kitap" : "book",
"bilgisayar" : "computer",
"programlama": "programming",
"dil" : "language",
"defter" : "notebook"}

Bu ekilde szlkteki eler arasndaki iliki daha belirgin, yazdnz kodlar da daha okunakl
bir hale gelecektir.
Pythonda bir szlk oluturmann baka yollar da olmakla birlikte, en temel szlk
oluturma yntemi yukardaki rneklerde gsterdiimiz gibidir. Biz ilerleyen sayfalarda
szlk oluturmann farkl yntemlerini de ele alacaz. Ancak imdilik szlk tanmlama
konusunu burada noktalayp szlklerle ilgili nemli bir konuya daha deinelim.

31.2 Szlk elerine Erimek

Yukardaki rneklerden bir szln en basit ekilde nasl tanmlanacan rendik. Peki
tanmladmz bir szln elerine nasl erieceiz?
Hemen basit bir rnek verelim. Daha nce tanmladmz u szle bir bakalm mesela:
szlk = {"kitap" : "book",
"bilgisayar" : "computer",
"programlama": "programming",

474 Blm 31. Szlkler


Python 3 iin Trke Klavuz, Srm 3

"dil" : "language",
"defter" : "notebook"}

Bu szlkte birtakm Trke kelimeler ve bunlarn ngilizce karlklar var. imdi mesela bu
szlkteki kitap adl eye erielim:
print(szlk["kitap"])

Bu kodlar altrdmzda yle bir kt alrz:


book

Yukardaki rnekten anladmz gibi, szlk elerine erimek iin yle bir forml
kullanyoruz:
szlk[szlk_esinin_ad]

Ayn ekilde szlk deikeni iindeki bilgisayar esinin karln almak istersek yle bir
kod yazyoruz:
print(szlk["bilgisayar"])

Bu da bize computer ktsn veriyor.


Karakter dizilerini anlatrken verdiimiz eviri_tablosu adl szle ve orada anlattklarmza
geri dnelim imdi. Artk szlk adl veri tipiyle iyiden iyiye tantmza gre, orada
anlattklarmz zihninizde daha net bir hale gelmi olmal.
Oradaki tablomuz yleydi:

eviri_tablosu = {"": "O",


"": "c",
"": "U",
"": "C",
"": "I",
"": "i",
"": "G",
"": "o",
"": "s",
"": "u",
"": "S",
"": "g"}

Mesela bu szlkteki esinin karln elde etmek iin yle bir kod yazdmz gayet
iyi hatrlyorsunuz:

print(eviri_tablosu[""])

Bu kodlar bir dosyaya kaydedip altrdmzda yle bir kt alyorduk:


O

Grdnz gibi szlkteki adl eyi parantez iinde belirttiimiz zaman, Python bize bu
enin karsndaki deeri veriyor. Dolaysyla szlk iinde esinin karl O har
olduu iin de ktmz O oldu.
Szln teki elerini ise u ekilde alabiliyoruz:

31.2. Szlk elerine Erimek 475


Python 3 iin Trke Klavuz, Srm 3

print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])
print(eviri_tablosu[""])

Ancak kod tekrarndan kanmak iin yukardaki kodlar u ekilde sadeletirme imkanmzn
da olduunu biliyorsunuz:
for i in eviri_tablosu:
print(eviri_tablosu[i])

Grdnz gibi, szlk iinde iki nokta st ste iaretinin sol tarafnda grnen eleri
keli parantez iinde yazarak, iki nokta st ste iaretinin sa tarafndaki deerleri elde
edebiliyoruz.
Eer bir szlk iinde bulunmayan bir eye erimeye alrsak Python bize KeyError tipinde
bir hata mesaj verecektir. Mesela yukardaki szl temel alacak olursak yle bir sorgu
hata verecektir:
>>> print(eviri_tablosu["Z"])

Traceback (most recent call last):


File "deneme.py", line 14, in <module>
print(eviri_tablosu["Z"])
KeyError: 'Z'

Szlkte Z kayd bulunmad iin doal olarak Pythonn bize bir hata mesaj gstermekten
baka aresi kalmyor.
Szlkler ile ilgili epey bilgi edindik. Dilerseniz bu rendiklerimizi rnek bir uygulama
zerinde somutlatrmaya alalm. Mesela Pythondaki szlkleri kullanarak basit bir telefon
defteri uygulamas yazalm:
telefon_defteri = {"ahmet z" : "0532 532 32 32",
"mehmet su": "0543 543 42 42",
"seda naz" : "0533 533 33 33",
"eda ala" : "0212 212 12 12"}

kii = input("Telefon numarasn renmek iin bir kii ad girin: ")

cevap = "{} adl kiinin telefon numaras: {}"

print(cevap.format(kii, telefon_defteri[kii]))

Burada ncelikle isimler ve telefon numaralarndan oluan, szlk veri tipinde bir telefon
defteri oluturduk:
telefon_defteri = {"ahmet z" : "0532 532 32 32",
"mehmet su": "0543 543 42 42",
"seda naz" : "0533 533 33 33",
"eda ala" : "0212 212 12 12"}

476 Blm 31. Szlkler


Python 3 iin Trke Klavuz, Srm 3

Bu kodlarda bilmediimiz hibir ey yok. Szlklere dair rendiklerimizi kullanarak


oluturduumuz olduka basit bir szlktr bu.
Daha sonra kullancdan, telefon numarasn renmek iin bir kii ad girmesini istiyoruz.
Bunu da u kodlar yardmyla yapyoruz:
kii = input("Telefon numarasn renmek iin bir kii ad girin: ")

Ardndan da telefon defterinde sorgulama yapacak olan kullancya gstereceimiz cevap iin
bir ablon oluturuyoruz:
cevap = "{} adl kiinin telefon numaras: {}"

Mesela kullanc ahmet z ismini sorgulamsa ona yle bir cevap vereceiz:
"ahmet z adl kiinin telefon numaras 0532 532 32 32"

Eer aranan isim telefon defterinde varsa, bir nceki admda tanmladmz cevap ablonuna
gre kullancy bilgilendiriyoruz. Ama eer eer isim defterde yoksa, programmz hata
veriyor. Bunu nlemek iin yle bir kod yazabilirsiniz:
telefon_defteri = {"ahmet z" : "0532 532 32 32",
"mehmet su": "0543 543 42 42",
"seda naz" : "0533 533 33 33",
"eda ala" : "0212 212 12 12"}

kii = input("Telefon numarasn renmek iin bir kii ad girin: ")

if kii in telefon_defteri:
cevap = "{} adl kiinin telefon numaras: {}"
print(cevap.format(kii, telefon_defteri[kii]))
else:
print("Aradnz kii telefon rehberinde yok!")

Grdnz gibi, if kii in telefon_defteri satr yardmyla ncelikle aranan ismin


szlkte olup olmadn denetledik. Eer aranan isim szlkte yer alyorsa bu telefon
numarasn kullanclarmza gsteriyoruz. Aksi durumda aranan kiinin telefon rehberinde
olmad konusunda kullanclarmz bilgilendiriyoruz.
Grdnz gibi, szlkler gerekten de bize Python programlama maceramzda yepyeni
olanaklarn kapsn aabilecek kadar gl bir veri tipi. Bu veri tipini programlarnzda bolca
kullanacaksnz.
Yukarda verdiimiz telefon defteri uygulamasna yle bir baktnzda bu uygulamann
aslnda gelitirilmeye bir hayli ak olduu dikkatinizi ekmitir. Mesela biz bu uygulamada
sadece kendi tanmladmz bir telefon defteri zerinden sorgulama yapmaya izin verdik.
rnein kullanc bu telefon defterine kendi isim-telefon iftlerini giremiyor. Bu veri tipini
etkili bir ekilde kullanmamz salayacak aralardan henz yoksun olduumuz iin yukarda
tanmladmz uygulama ok basit kald. O halde, szlk veri tipini daha verimli ve etkili
bir biimde kullanabilmek iin hi vakit kaybetmeden bu veri tipinin derinliklerine doru yol
almaya devam edelim.

31.2. Szlk elerine Erimek 477


Python 3 iin Trke Klavuz, Srm 3

31.3 Szlklerin Yaps

Yukardaki rneklerden, Pythonda bir szln nasl tanmlanacan ve bir szln


elerine nasl eriileceini rendik. Gelin isterseniz imdi szlk veri tipinin yapsna ilikin
baz ayrntlar inceleyelim.
Mesela u rnei tekrar nmze alalm:
szlk = {"kitap": "book"}

Burada iki nokta st ste iaretinden nce ve sonra birer tane karakter dizisi gryoruz.
Bu karakter dizileri kitap ve book. Dediimiz gibi, szlkler de tpk listeler gibi, farkl
veri tiplerinin bir araya gelmesi ile oluan birleik/kapsayc bir veri tipidir. Dolaysyla bir
szlk iinde sadece karakter dizilerini deil, baka veri tiplerini de grebilirsiniz. lerleyen
sayfalarda szlklere ilikin daha karmak rnekler verdiimizde szlklerin hangi veri
tiplerini ierebileceini de greceiz.
Ne dedik? Szlk iinde iki nokta st ste iaretinin solunda ve sanda kitap ve book adl
karakter dizileri var. Teknik olarak, iki nokta st ste iaretinin solundaki karakter dizisine
anahtar (key ), sandaki karakter dizisine ise deer (value ) ad verilir. Bu bilgilere bakarak
szlk iin yle bir tanm verebiliriz:
Szlkler; anahtar ve deer iftlerinin birbirleriyle eletirildii bir veri tipidir.
Dolaysyla szlkler bu anahtar ve deer iftleri arasnda birebir iliki kurar.
Mesela yukardaki rnekte kitap esi anahtar, book esi ise deerdir. te szlk
dediimiz ey, bu anahtar ve deer ifti arasnda birebir iliki kuran bir veri tipidir. Yani szlk
adl veri tipi, bir anahtar bir deerle eletirme grevi grr.
Szlklerin bu zelliini, szlk elerine eriirken gayet net bir ekilde grebiliyoruz.
Yukardaki rneklerde tanmladmz szlklerde sadece karakter dizilerini kullandk. Ama
aslnda szlkler farkl veri tiplerinden oluabilir. Mesela:
szlk = {"sfr": 0,
"bir" : 1,
"iki" : 2,
"" : 3,
"drt" : 4,
"be" : 5}

Burada szlk iinde hem saylar hem de karakter dizilerini kullandk. Ayn ekilde szlk
iinde listelere de yer verebiliriz:

szlk = {"Ahmet zkoparan": ["stanbul", "retmen", 34],


"Mehmet Yaz" : ["Adana", "Mhendis", 40],
"Seda Bayrak" : ["skenderun", "Doktor", 30]}

Mesela bu szlkte Seda Bayrak adl kiinin bilgilerine ulamak istersek yle bir kod
yazabiliriz:
print(szlk["Seda Bayrak"])

Bu kod bize yle bir kt verecektir:


['skenderun', 'Doktor', 30]

478 Blm 31. Szlkler


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, szlk iinde Seda Bayrak adl enin karsndaki bilgi listesine
ulaabildik.
stersek szlkleri, ilerinde baka szlkleri barndracak ekilde de tanmlayabiliriz:

kiiler = {"Ahmet zkoparan": {"Memleket": "stanbul",


"Meslek" : "retmen",
"Ya" : 34},

"Mehmet Yaz" : {"Memleket": "Adana",


"Meslek" : "Mhendis",
"Ya" : 40},

"Seda Bayrak" : {"Memleket": "skenderun",


"Meslek" : "Doktor",
"Ya" : 30}}

Bylece yle kodlar yazabiliriz:


print(kiiler["Mehmet Yaz"]["Memleket"])
print(kiiler["Seda Bayrak"]["Ya"])
print(kiiler["Ahmet zkoparan"]["Meslek"])

Yukardaki yapnn benzerini listeler konusundan hatrlyor olmalsnz. ie gemi listelerin


elerine ularken de buna benzer bir szdiziminden yararlanyorduk. rnein:
liste = [["Ahmet", "Mehmet", "Aye"],
["Sedat", "Serkan", "Selin"],
["Zeynep", "Nur", "Eda"]]

Burada bir liste iinde i ie gemi farkl liste ile kar karyayz. Mesela ilk listenin ilk
esi olan Ahmet adl eye erimek istersek yle bir kod yazmamz gerekiyor:
print(liste[0][0])

te i ie gemi szlklerin elerine ulamak iin de buna benzer bir kod yazmamz
gerekiyor. rnein kiiler adl szlkteki Mehmet Yaz adl kiinin yana ulamak istersek
yle bir ey yazacaz:
print(kiiler["Mehmet Yaz"]["Ya"])

Gelin isterseniz kiiler adl szl kullanarak basit bir irtibat listesi uygulamas yazalm.
Bylece szlklere elimizi altrm oluruz:

kiiler = {"Ahmet zkoparan": {"Memleket": "stanbul",


"Meslek" : "retmen",
"Ya" : 34},

"Mehmet Yaz" : {"Memleket": "Adana",


"Meslek" : "Mhendis",
"Ya" : 40},

"Seda Bayrak" : {"Memleket": "skenderun",


"Meslek" : "Doktor",
"Ya" : 30}}

isim = "Hakknda ayrntl bilgi edinmek \


istediiniz kiinin adn girin: "

31.3. Szlklerin Yaps 479


Python 3 iin Trke Klavuz, Srm 3

arama = input(isim)

ayrnt = input("Memleket/Meslek/Ya? ")

print(kiiler[arama][ayrnt])

Tpk bir nceki telefon defteri uygulamamz gibi, bu irtibat listesi uygulamas da gelitirilmeye
aktr. Ancak henz bu iki uygulamay gelitirmemizi salayacak bilgilerden yoksunuz. Bu
uygulamalar istediimiz kvama sokabilmek iin szlklere dair renmemiz gereken baka
eyler de var.
Szlklerin teki veri tiplerinden nemli bir fark, szlk iinde yer alan elerin herhangi bir
sralama mantna sahip olmamasdr. Yani szlkteki eler asndan sra diye bir kavram
yoktur.
rnein bir liste, demet veya karakter dizisi iindeki elere; bu elerin o liste, demet veya
karakter dizisi iindeki sralarna gre eriebilirsiniz:
>>> liste = ["Ahmet", "Mehmet", "Zeynep"]
>>> liste[0]

'Ahmet'

>>> liste[-1]

'Zeynep'

Ancak szlkler asndan byle bir ey sz konusu deildir:


>>> szlk = {'elma': 'apple',
... 'armut': 'pear',
... 'ilek': 'strawberry'}
>>> szlk[0]

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
KeyError: 0

Grdnz gibi, szlkler zerinde sralamaya dayal bir sorgulama yapmaya altmzda
Python bize bir hata mesaj gsteriyor.
Bu durumun etkilerini urada da grebilirsiniz:
Dikkatlice bakn:
>>> szlk = {'a': '0', 'b': '1', 'c': '2'}
>>> szlk

{'a': '0', 'c': '2', 'b': '1'}

Bu kty iyi inceleyin. Greceiniz gibi, ktda grnen eler bizim szl tanmladmz
sradaki gibi deil. Biz szl a, b ve c eklinde sralayarak tanmladk, ama kt a, c
ve b eklinde oldu. O yzden szlkler zerinde alrken elerin srasna dayal herhangi
bir ilem yapmak hi mantkl deildir. nk szlkteki eleri tanmlarken kullandnz
sralama dzeninin ktda da aynen korunacann herhangi bir garantisi bulunmaz.

480 Blm 31. Szlkler


Python 3 iin Trke Klavuz, Srm 3

31.4 Szlklere e Eklemek

Tpk listeler gibi, szlkler de byyp klebilen bir veri tipidir. Yani bir szl ilk kez
tanmladktan sonra istediimiz zaman bu szle yeni eler ekleyebilir veya varolan eleri
karabiliriz. Biz imdi bir szle nasl e ekleyeceimizi inceleyeceiz.
Diyelim ki elimizde yle bo bir szlk var:
>>> szlk = {}

Bu listeye e eklemek iin yle bir forml kullanacaz:


>>> szlk[anahtar] = deer

Bu forml bir rnek zerinden somutlatralm:


>>> szlk["Ahmet"] = "Adana"

Bylece szle, anahtar Ahmet, deeri ise Adana olan bir e eklemi olduk.
Szlmzn son durumunu kontrol edelim:
>>> print(szlk)

{'Ahmet': 'Adana'}

Grdnz gibi, Ahmet esi szle eklendi. Artk bu eye normal yollardan ulaabiliriz:
>>> print(szlk["Ahmet"])

Adana

Elimiz alsn diye szle e eklemeye devam edelim:


>>> szlk["Mehmet"] = "stanbul"
>>> szlk

{'Ahmet': 'Adana', 'Mehmet': 'stanbul'}

>>> szlk["Seda"] = "Mersin"


>>> szlk

{'Ahmet': 'Adana', 'Mehmet': 'stanbul', 'Seda': 'Mersin'}

>>> szlk["Eda"] = "Tarsus"


>>> szlk

{'Ahmet': 'Adana', 'Eda': 'Tarsus', 'Mehmet': 'stanbul', 'Seda': 'Mersin'}

zellikle son ktya dikkatlice bakn. Szle en son Eda esini eklemitik. Ama szl
ekrana bastmzda bu enin szln sonuna deil ortasna bir yere yerletiini gryoruz.
Bu durumun, szlklerin srasz bir veri tipi olmasndan kaynaklandn biliyorsunuz.
Gelin pratik olmas asndan birka rnek daha verelim.
Elimizde yle bir szlk olsun:
>>> personel = {"Mehmet z": "AR-GE Mdr",
... "Samet Sz": "Genel Direktr",
... "Sedat Gn": "Proje Mdr"}

31.4. Szlklere e Eklemek 481


Python 3 iin Trke Klavuz, Srm 3

imdi bu szle "Turgut zben": "Mhendis" anahtar-deer iftini ekleyelim:

>>> personel["Turgut zben"] = "Mhendis"

Szlmzn son halini grelim:


>>> print(personel)

{'Samet Sz': 'Genel Direktr', 'Mehmet z': 'AR-GE Mdr', 'Turgut zben':
'Mhendis', 'Sedat Gn': 'Proje Mdr'}

Grdnz gibi eklemek istediimiz e szle eklenmi. Ancak bu enin szln en


sonuna deil, szlk iine rastgele bir ekilde yerletirildiine dikkatinizi ekmek isterim.
nk, dediimiz gibi, szlkler srasz bir veri tipidir.
Gelin bu konuyu daha iyi anlamak iin bir rnek daha verelim.
nce notlar adnda bo bir szlk tanmlayalm:
>>> notlar = {}

Bu szle rencilerin snavdan aldklar notlar ekleyeceiz:


>>> notlar["Ahmet"] = 45
>>> notlar["Mehmet"] = 77
>>> notlar["Seda"] = 98
>>> notlar["Deniz"] = 95
>>> notlar["Ege"] = 95
>>> notlar["Zeynep"] = 100

Szlmzn son halini grelim:


>>> print(notlar)

{'Seda': 98, 'Ege': 95, 'Mehmet': 77, 'Zeynep': 100, 'Deniz': 95, 'Ahmet': 45}

Bu noktada szlklerin nemli bir zelliinden bahsetmemiz uygun olacak. Bir szle deer
olarak btn veri tiplerini verebiliriz. Yani:
>>> szlk = {}
>>> szlk = {'a': 1}
>>> szlk = {'a': (1,2,3)}
>>> szlk = {'a': 'kardiz'}
>>> szlk = {'a': [1,2,3]}

Grdnz gibi, szlkler deer olarak her trl veri tipini kabul ediyor. Ama durum szlk
anahtarlar asndan byle deildir. Yani szlklere anahtar olarak her veri tipini atayamayz.
Bir deerin anahtar olabilmesi iin, o enin deitirilemeyen (immutable ) bir veri tipi
olmas gerekir. Pythonda imdiye kadar rendiimiz u veri tipleri deitirilemeyen veri
tipleridir:
1. Demetler
2. Saylar
3. Karakter Dizileri
u veri tipleri ise deitirilebilen veri tipleridir:
1. Listeler

482 Blm 31. Szlkler


Python 3 iin Trke Klavuz, Srm 3

2. Szlkler
Dolaysyla bir szle ancak u veri tiplerini ekleyebiliriz:
1. Demetler
2. Saylar
3. Karakter Dizileri
u kodlar dikkatlice inceleyin:
nce bo bir szlk oluturalm:
>>> szlk = {}

Bu szle anahtar olarak bir demet ekleyelim:


>>> l = (1,2,3)
>>> szlk[l] = 'falanca'
>>> szlk

{(1, 2, 3): 'falanca'}

Bir say ekleyelim:


>>> l = 45
>>> szlk[l] = 'falanca'
>>> szlk

{45: 'falanca', (1, 2, 3): 'falanca'}

Bir karakter dizisi ekleyelim:


>>> l = 'kardiz'
>>> szlk[l] = 'falanca'
>>> szlk

{'kardiz': 'falanca', 45: 'falanca', (1, 2, 3): 'falanca'}

Yukardakiler, deitirilemeyen veri tipleri olduu iin szlklere anahtar olarak eklenebildi.
Bir de unlara bakalm:
Szlmze anahtar olarak bir liste eklemeye alalm:
>>> l = [1,2,3]
>>> szlk[l] = 'falanca'

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

Kmemize bir szlk eklemeye alalm:


>>> l = {"a": 1, "b": 2, "c": 3}
>>> szlk[l] = 'falanca'

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

31.4. Szlklere e Eklemek 483


Python 3 iin Trke Klavuz, Srm 3

Szlklerle alrken szlklerin bu zelliine kar uyank olmalyz.

31.5 Szlk eleri zerinde Deiiklik Yapmak

Szlkler deitirilebilir veri tipleridir. Dolaysyla szlkler zerinde rahatlkla istediimiz


deiiklii yapabiliriz.
Szlkler zerinde deiiklik yapma ilemi, biraz nce rendiimiz, szlklere yeni e
ekleme ilemiyle ayndr. Dikkatlice bakn:
>>> notlar = {'Seda': 98, 'Ege': 95, 'Mehmet': 77,
... 'Zeynep': 100, 'Deniz': 95, 'Ahmet': 45}

Szlmz bu. imdi bu szlkteki Ahmet adl kiinin 45 olan notunu 65 olarak
deitirelim:
>>> notlar["Ahmet"] = 65
>>> print(notlar)

{'Seda': 98, 'Ege': 95, 'Mehmet': 77, 'Zeynep': 100, 'Deniz': 95, 'Ahmet': 65}

Grdnz gibi Ahmetin notu 65 olarak deimi...

31.6 Szlk reteleri (Dictionary Comprehensions )

Hatrlarsanz listeleri anlatrken liste reteleri ad bir kavramdan sz etmitik. Liste


retelerini kullanarak tek satrda ve hzl bir ekilde listeler oluturabiliyorduk. Ayn ey
szlkler iin de geerlidir. Tpk liste retelerinde olduu gibi, szlk reteleri sayesinde
tek satrda ve hzl bir ekilde szlkler retebiliriz.
rnein elimizde, Trke alfabedeki hareri ieren harer adl yle bir liste olduunu
dnn:
>>> harfler = 'abcdefghijklmnoprstuvyz'

Amacmz bu harerin her birine bir numara vermek. Yani nihai olarak yle bir szlk elde
etmek istiyoruz:
{'': 8,
'v': 26,
'': 22,
'u': 24,
't': 23,
'': 18,
'': 10,
'p': 19,
's': 21,
'r': 20,
'': 25,
'y': 27,
'': 3,
'z': 28,
'e': 5,
'd': 4,

484 Blm 31. Szlkler


Python 3 iin Trke Klavuz, Srm 3

'g': 7,
'f': 6,
'a': 0,
'c': 2,
'b': 1,
'm': 15,
'l': 14,
'o': 17,
'n': 16,
'i': 11,
'h': 9,
'k': 13,
'j': 12}

Bunun iin birka farkl yntemden yararlanabiliriz. rnein:


>>> szlk = {}
>>> for i in harfler:
... szlk[i] = harfler.index(i)

veya:
>>> szlk = {}
>>> for i in range(len(harfler)):
... szlk[harfler[i]] = i

te bu ilemleri szlk retelerini kullanarak ok daha hzl ve pratik bir ekilde


halledebiliriz. Dikkatlice bakn:
>>> szlk = {i: harfler.index(i) for i in harfler}

Bir rnek daha verelim. Diyelim ki elinizde yle bir isim listesi var:
isimler = ["ahmet", "mehmet", "frat", "zeynep", "selma", "abdullah", "cem"]

Amacnz, bu isimleri ve her bir ismin ka harften olutuunu gsteren bir szlk elde etmek.
Yani nihai olarak yle bir ey olsun istiyorsunuz elinizde:
{'zeynep': 6,
'cem': 3,
'abdullah': 8,
'ahmet': 5,
'mehmet': 6,
'frat': 5,
'selma': 5}

te bu grev iin de szlk retelerinden yararlanabilirsiniz:


>>> isimler = ["ahmet", "mehmet", "frat", "zeynep", "selma", "abdullah", "cem"]
>>> szlk = {i: len(i) for i in isimler}
>>> szlk

{'zeynep': 6, 'cem': 3, 'abdullah': 8, 'ahmet': 5, 'mehmet': 6, 'frat': 5, 'selma': 5}

Bildiiniz gibi szlkler, her biri birbirinden : iareti ile ayrlan birtakm anahtar-deer
iftlerinden oluuyor. te yukardaki szlk reteci yapsnda biz : iaretinin sol tarafna
isimler adl listedeki her bir eyi; sa tarafna da bu elerin uzunluklarn bir rpda
ekliyoruz.

31.6. Szlk reteleri (Dictionary Comprehensions ) 485


BLM 32

Szlklerin Metotlar

Tpk teki veri tiplerinde olduu gibi, szlklerin de birtakm metotlar bulunur. Bu blmde
szlklerin u metotlarn inceleyeceiz:
1. clear()
2. copy()
3. fromkeys()
4. get()
5. items()
6. keys()
7. pop()
8. popitem()
9. setdefault()
10. update()
11. values()
lk olarak keys() metoduyla balayalm.

32.1 keys()

Szlkleri tarif ederken, szlklerin anahtar-deer iftlerinden oluan bir veri tipi olduunu
sylemitik. Bir szl normal yollardan ekrana yazdrrsanz size hem anahtarlar hem de
bunlara karlk gelen deerleri verecektir. Ama eer bir szln sadece anahtarlarn almak
isterseniz keys() metodundan yararlanabilirsiniz:
>>> szlk = {"a": 0,
... "b": 1,
... "c": 2,
... "d": 3}
>>> print(szlk.keys())

dict_keys(['b', 'c', 'a', 'd'])

486
Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, szlk.keys() komutu bize bir dict_keys nesnesi veriyor. Bu nesneyi
programnzda kullanabilmek iin isterseniz, bunu listeye, demete veya karakter dizisine
dntrebilirsiniz:
>>> liste = list(szlk.keys())
>>> liste

['b', 'c', 'a', 'd']

>>> demet = tuple(szlk.keys())


>>> demet

('b', 'c', 'a', 'd')

>>> kardiz = "".join(szlk.keys())


>>> kardiz

'bcad'

Son rnekte szlk anahtarlarn karakter dizisine dntrmek iin str() fonksiyonunu
deil, karakter dizilerinin join() adl metodunu kullandmza dikkat edin. nk tuple()
ve list() fonksiyonlarnn aksine str() fonksiyonu, szlkteki anahtarlarn nasl bir lte
gre karakter dizisine evrileceine dair bir kural iermez. Zira siz bu szlk anahtarlarn
pek ok farkl ekilde karakter dizisine evirebilirsiniz. rnein eleri karakter dizisi iine
yerletirirken elerin arasna virgl koymak isteyebilirsiniz:
>>> kardiz = ', '.join(szlk.keys())
>>> kardiz

'b, c, a, d'

Eer szlk anahtarlarn str() fonksiyonu yardmyla karakter dizisine dntrmeye


kalkrsanz beklemediiniz bir kt alrsnz.

32.2 values()

keys() metodu bir szln anahtarlarn veriyor. Bir szln deerlerini ise values()
metodu verir:
>>> szlk
{'b': 1, 'c': 2, 'a': 0, 'd': 3}

>>> print(szlk.values())

dict_values([1, 2, 0, 3])

Grdnz gibi, bu metottan bir dict_values nesnesi alyoruz. Tpk keys() metodunda
olduu gibi, values() metodunda da bu kty baka veri tiplerine dntrme imkanna
sahibiz:
>>> liste = list(szlk.values())
>>> liste

[1, 2, 0, 3]

32.2. values() 487


Python 3 iin Trke Klavuz, Srm 3

>>> demet = tuple(szlk.values())


>>> demet

(1, 2, 0, 3)

Yalnz bu verileri karakter dizisine dntrmeye altnzda ufak bir problemle


karlacaksnz:
>>> kardiz = "".join(szlk.values())

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: sequence item 0: expected str instance, int found

Bunun sebebi, szlkteki deerlerin int tipinde olmasdr. Bildiiniz gibi, sadece ayn tip
verileri birbiriyle birletirebiliriz. Eer birletirmek istediimiz veriler birbirinden farkl tipte
ise, bunlar birletirmeden nce bir dntrme ilemi yapmamz gerekir:
>>> kardiz = "".join([str(i) for i in szlk.values()])
>>> kardiz

'1203'

Grdnz gibi, szlkteki deerlerin her birini, tek bir liste reteci iinde karakter dizisine
dntrdk ve ortaya kan listeyi karakter dizilerinin join() metodu yardmyla, elerin
arasnda hibir boluk brakmadan kardiz adl bir karakter dizisi iine yerletirdik. Elbette
eer isteseydik bu elerin her birinin arasna bir virgl de koyabilirdik:
>>> kardiz = ", ".join([str(i) for i in szlk.values()])
>>> kardiz

'1, 2, 0, 3'

32.3 items()

Bu metot, bir szln hem anahtarlarn hem de deerlerini ayn anda almamz salar:
>>> szlk.items()

dict_items([('a', 0), ('c', 2), ('b', 1)])

Grdnz gibi, tek bir liste iinde iki eli demetler halinde hem anahtarlar hem de
deerleri grebiliyoruz. Bu metot sklkla for dngleri ile birlikte kullanlarak bir szln
anahtar ve deerlerinin maniple edilebilmesini salar:
>>> for anahtar, deer in szlk.items():
... print("{} = {}".format(anahtar, deer))
...
a = 0
c = 2
b = 1

488 Blm 32. Szlklerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

32.4 get()

Bu metot szlklerin en kullanl metotlarndan biridir. Bu metot pek ok durumda iinizi bir
hayli kolaylatrr.
Diyelim ki yle bir program yazdk:
#!/usr/bin/env python3.0

ing_szlk = {"dil": "language", "bilgisayar": "computer", "masa": "table"}

sorgu = input("Ltfen anlamn renmek istediiniz kelimeyi yaznz:")

print(ing_szlk[sorgu])

Bu program altrdmzda eer kullanc ing_szlk adyla belirttiimiz szlk iinde


bulunan kelimelerden birini yazarsa, o kelimenin karln alacaktr. Diyelim ki kullancmz
soruya dil diye cevap verdi. Bu durumda ekrana dil kelimesinin szlkteki karl olan
language yazdrlacaktr. Peki ya kullanc szlkte tanml olmayan bir kelime yazarsa ne
olacak? yle bir durumda programmz hata verecektir. Programmz iin doru yol, hata
vermektense, kullancy kelimenin szlkte olmad konusunda bilgilendirmektir. Bunu
klasik bir yaklamla u ekilde yapabiliriz:
ing_szlk = {"dil": "language", "bilgisayar": "computer", "masa": "table"}

sorgu = input("Ltfen anlamn renmek istediiniz kelimeyi yaznz:")

if sorgu not in ing_szlk:


print("Bu kelime veritabanmzda yoktur!")

else:
print(ing_szlk[sorgu])

Ama akas bu pek verimli bir yaklam saylmaz. Yukardaki yntem yerine szlklerin get()
metodundan faydalanabiliriz. Bakalm bunu nasl yapyoruz:
ing_szlk = {"dil": "language", "bilgisayar": "computer", "masa": "table"}

sorgu = input("Ltfen anlamn renmek istediiniz kelimeyi yaznz:")

print(ing_szlk.get(sorgu, "Bu kelime veritabanmzda yoktur!"))

Grdnz gibi, burada ok basit bir metot yardmyla btn dertlerimizi hallettik.
Szlklerin get() adl metodu, parantez iinde iki adet argman alr. Birinci argman
sorgulamak istediimiz szlk esidir. kinci argman ise bu enin szlkte bulunmad
durumda kullancya hangi mesajn gsterileceini belirtir. Buna gre, yukarda yaptmz
ey, nce sorgu deikenini szlkte aramak, eer bu e szlkte bulunamyorsa da
kullancya, Bu kelime veritabanmzda yoktur! cmlesini gstermekten ibarettir...
Gelin isterseniz bununla ilgili bir rnek daha yapalm.
Diyelim ki bir havadurumu program yazmak istiyoruz. Bu programda kullanc bir ehir ad
girecek. Program da girilen ehre ait havadurumu bilgilerini ekrana yazdracak. Bu program
klasik yntemle u ekilde yazabiliriz:

32.4. get() 489


Python 3 iin Trke Klavuz, Srm 3

#!/usr/bin/env python3

soru = input("ehrinizin adn tamam kk harf olacak ekilde yazn:")

if soru == "istanbul":
print("gk grltl ve saanak yal")

elif soru == "ankara":


print("ak ve gneli")

elif soru == "izmir":


print("bulutlu")

else:
print("Bu ehre ilikin havadurumu bilgisi bulunmamaktadr.")

Yukardaki, gayet geerli bir yntemdir. Ama biz istersek bu kodlar get metodu yardmyla
ok daha verimli ve sade bir hale getirebiliriz:
#!/usr/bin/env python3

soru = input("ehrinizin adn tamam kk harf olacak ekilde yazn:")

cevap = {"istanbul": "gk grltl ve saanak yal",


"ankara": "ak ve gneli", "izmir": "bulutlu"}

print(cevap.get(soru, "Bu ehre ilikin havadurumu bilgisi bulunmamaktadr."))

32.5 clear()

Szlklerin, inceleyeceimiz ilk metodu clear(). Bu kelime ngilizcede temizlemek


anlamna gelir. Grevi szlkteki eleri temizlemektir. Yani ii dolu bir szl bu metot
yardmyla tamamen boaltabiliriz:
>>> lig = {"ampiyon": "Adana Demirspor", "ikinci": "Mersin dman Yurdu",
... "nc": "Adana Genlerbirlii"}

sterseniz szlmz boaltmadan nce bu szlkle biraz alalm:


Szlmzn elerine yle ulayoruz:
>>> lig

{'ampiyon': 'Adana Demirspor', 'ikinci': 'Mersin dman Yurdu',


'nc': 'Adana Genlerbirlii'}

Eer bu szln elerine tek tek erimek istersek yle yapyoruz:


>>> lig["ampiyon"]

'Adana Demirspor'

>>> lig["nc"]

'Adana Genlerbirlii'

490 Blm 32. Szlklerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

imdi geldi bu szln btn elerini silmeye:


>>> lig.clear()

imdi szlmzn durumunu tekrar kontrol edelim:


>>> lig

{}

Grdnz gibi artk lig adl szlmz bombo. clear() metodunu kullanarak bu
szln btn elerini sildik. Ama tabii ki bu ekilde szl silmi olmadk. Bo da olsa
bellekte hl lig adl bir szlk duruyor. Eer siz ligi ortadan kaldrmak isterseniz del adl
bir paracktan yararlanmanz gerekir:
>>> del lig

Kontrol edelim:
>>> lig

NameError: name 'lig' is not defined

Grdnz gibi artk lig diye bir ey yok... Bu szl bellekten tamamen kaldrdk.
clear() adl metodun ne olduunu ve ne ie yaradn grdmze gre baka bir metoda
geebiliriz.

32.6 copy()

Diyelim ki elimizde yle bir szlk var:


>>> hava_durumu = {"stanbul": "yamurlu", "Adana": "gneli", ... "zmir": "bulutlu"}

Biz bu szl kopyalamak istiyoruz. Hemen yle bir ey deneyelim:


>>> yedek_hava_durumu = hava_durumu

Artk elimizde ayn szlkten iki tane var:


>>> hava_durumu

{'stanbul': 'yamurlu', 'Adana': 'gneli', 'zmir': 'bulutlu'}

>>> yedek_hava_durumu

{'stanbul': 'yamurlu', 'Adana': 'gneli', 'zmir': 'bulutlu'}

imdi hava_durumu adl szle bir e ekleyelim:


>>> hava_durumu["Mersin"] = "sisli"

>>> hava_durumu

{'stanbul': 'yamurlu', 'Adana': 'gneli', 'Mersin': 'sisli', 'zmir': 'bulutlu'}

imdi bir de yedek_hava_durumu adl szln durumuna bakalm:

32.6. copy() 491


Python 3 iin Trke Klavuz, Srm 3

>>> yedek_hava_durumu

{'stanbul': 'yamurlu', 'Adana': 'gneli', 'Mersin': 'sisli', 'zmir': 'bulutlu'}

Grdnz gibi, hava_durumu adl szle yaptmz ekleme yedek_hava_durumu adl


szl de etkiledi. Hatrlarsanz buna benzer bir durumla daha nce listeleri anlatrken de
karlamtk. nk varolan bir szl veya listeyi baka bir deikene atadmzda aslnda
yaptmz ey bir kopyalama ileminden ziyade bellekteki ayn nesneye gnderme yapan iki
farkl isim belirlemekten ibaret. Yani szlmz bellekteki bir nesne olarak dnrsek, bu
nesneye atfta bulunan, hava_durumu ve yedek_hava_durumu adl iki farkl isim belirlemi
oluyoruz. Eer istediimiz ey bellekteki nesneden iki adet oluturmak ve bu iki farkl
nesneyi iki farkl isimle adlandrmak ise yukardaki yntemi kullanmak istemediiniz sonular
dourabilir. Yani amacnz bir szl yedekleyip orijinal szl korumaksa ve yukardaki
yntemi kullandysanz, hi farknda olmadan orijinal szl de deitirebilirsiniz. te byle
durumlarda imdadmza szlklerin copy metodu yetiecek. Bu metodu kullanarak varolan
bir szl gerek anlamda kopyalayabilir, yani yedekleyebiliriz...
>>> hava_durumu = {"stanbul": "yamurlu", "Adana": "gneli", ... "zmir": "bulutlu"}

imdi bu szl yedekliyoruz. Yani kopyalyoruz:


>>> yedek_hava_durumu = hava_durumu.copy()

Bakalm hava_durumu adl szle ekleme yapnca yedek_hava_durumu adl szln


durumu ne oluyor?
>>> hava_durumu["Mersin"] = "sisli"

>>> hava_durumu

{'stanbul': 'yamurlu', 'Adana': 'gneli', 'Mersin': 'sisli', 'zmir':


'bulutlu'}

yedek_hava_durumu adl szle bakalm:


>>> yedek_hava_durumu

{'stanbul': 'yamurlu', 'Adana': 'gneli', 'zmir': 'bulutlu'}

Grdnz gibi bu defa szlklerin birinde yaplan deiiklik brn etkilemedi... copy
metodu saolsun!...

32.7 fromkeys()

fromkeys() metodu teki metotlardan biraz farkldr. Bu metot mevcut szlk zerinde
ilem yapmaz. fromkeys()in grevi yeni bir szlk oluturmaktr. Bu metot yeni bir szlk
olutururken listeler veya demetlerden yararlanr. yle ki:
>>> elemanlar = "Ahmet", "Mehmet", "Can"

>>> adresler = dict.fromkeys(elemanlar, "Kadky")

>>> adresler

492 Blm 32. Szlklerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

{'Ahmet': 'Kadky', 'Mehmet': 'Kadky', 'Can': 'Kadky'}

Grdnz gibi ncelikle elemanlar adl bir demet tanmladk. Daha sonra da adresler
adl bir szlk tanmlayarak, fromkeys() metodu yardmyla anahtar olarak elemanlar
demetindeki elerden oluan, deer olarak ise Kadky ieren bir szlk meydana
getirdik.
En bata tanmladmz elemanlar demeti liste de olabilirdi. Hatta tek bana bir karakter
dizisi dahi yazabilirdik oraya...

32.8 pop()

Bu metodu listelerden hatrlyoruz. Bu metot listelerle birlikte kullanldnda, listenin en son


esini silip, silinen eyi de ekrana basyordu. Eer bu metodu bir sra numaras ile birlikte
kullanrsak, listede o sra numarasna karlk gelen e siliniyor ve silinen bu e ekrana
baslyordu. Bu metodun szlklerdeki kullanm da az ok buna benzer. Ama burada fark
olarak, pop metodunu argmansz bir ekilde kullanamyoruz. Yani pop metodunun parantezi
iinde mutlaka bir szlk esi belirtmeliyiz:
>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("prasa", "fasulye"),
... "iecekler": ("su", "kola", "ayran")}

>>> sepet.pop("meyveler")

Bu komut, szlkteki meyveler anahtarn silecek ve sildii bu enin deerini ekrana


basacaktr. Eer silmeye altmz anahtar szlkte yoksa Python bize bir hata mesaj
gsterecektir:
>>> sepet.pop("tatllar")

KeyError: 'tatllar'

Bir program yazarken byle bir durumla karlamak istemeyiz ou zaman. Yani
bir szlk iinde arama yaparken, aranan enin szlkte bulunmad bir durumda
kullancya mekanik ve anlamsz bir hata gstermek yerine, daha anlalr bir mesaj iletmeyi
tercih edebiliriz. Hatrlarsanz szlklerin get() metodunu kullanarak benzer bir ey
yapabiliyorduk. u anda incelemekte olduumuz pop() metodu da bize byle bir imkan verir.
Bakalm:
>>> sepet.pop("tatllar", "Silinecek e yok!")

Bylelikle szlkte bulunmayan bir eyi silmeye altmzda Python bize bir hata mesaj
gstermek yerine, Silinecek e yok! eklinde daha anlaml bir mesaj verecektir...

32.9 popitem()

popitem() metodu da bir nceki blmde rendiimiz pop() metoduna benzer. Bu


iki metodun grevleri hemen hemen ayndr. Ancak pop() metodu parantez iinde bir
parametre alrken, popitem() metodunun parantezi bo, yani parametresiz olarak kullanlr.
Bu metot bir szlkten rastgele eler silmek iin kullanlr. Daha nce de pek ok kez
sylediimiz gibi, szlkler srasz veri tipleridir. Dolaysyla popitem() metodunun eleri

32.8. pop() 493


Python 3 iin Trke Klavuz, Srm 3

silerken kullanabilecei bir sra kavram yoktur. Bu yzden bu metot eleri rastgele silmeyi
tercih eder...
>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("prasa", "fasulye")}

>>> sepet.popitem()

Bu komut szlkten rastgele bir anahtar, deerleriyle birlikte szlkten silecektir. Eer szlk
bosa bu metot bize bir hata mesaj gsterir.

32.10 setdefault()

Bu metot epey enteresan, ama bir o kadar da yararl bir aratr... Bu metodun ne ie yaradn
dorudan bir rnek zerinde grelim:
>>> sepet = {"meyveler": ("elma", "armut"), "sebzeler": ("prasa", "fasulye")}

>>> sepet.setdefault("iecekler", ("su", "kola"))

Bu komut yardmyla szlmz iinde iecekler adl bir anahtar oluturduk. Bu anahtarn
deeri ise (su, kola) oldu... Bir de una bakalm:
>>> sepet.setdefault("meyveler", ("erik", "ilek"))

('elma', 'armut')

Grdnz gibi, szlkte zaten meyveler adl bir anahtar bulunduu iin, Python ayn
ad tayan ama deerleri farkl olan yeni bir meyveler anahtar oluturmad. Demek ki
bu metot yardmyla bir szlk iinde arama yapabiliyor, eer aradmz anahtar szlkte
yoksa, setdefault() metodu iinde belirttiimiz zellikleri tayan yeni bir anahtar-deer ifti
oluturabiliyoruz.

32.11 update()

nceleyeceimiz son metot update() metodu... Bu metot yardmyla oluturduumuz


szlkleri yeni verilerle gncelleyeceiz. Diyelim ki elimizde yle bir szlk var:
>>> stok = {"elma": 5, "armut": 10, "peynir": 6, "sosis": 15}

Stoumuzda 5 adet elma, 10 adet armut, 6 kutu peynir, 15 adet de sosis var. Diyelim ki daha
sonraki zamanlarda bu stoa mal giri-k oldu ve stoun son hali yle:
>>> yeni_stok = {"elma": 3, "armut": 20, "peynir": 8, "sosis": 4, "sucuk": 6}

Yapmamz gereken ey, stoumuzu yeni bilgilere gre gncellemek olacaktr. te bu ilemi
update() metodu ile yapabiliriz:
>>> stok.update(yeni_stok)

>>> print(stok)

{'peynir': 8, 'elma': 3, 'sucuk': 6, 'sosis': 4, 'armut': 20}

494 Blm 32. Szlklerin Metotlar


Python 3 iin Trke Klavuz, Srm 3

Bylelikle mallarn son miktarlarna gre stok bilgilerimizi gncellemi olduk...

32.11. update() 495


BLM 33

Kmeler ve Dondurulmu Kmeler

Bu blmde Pythondaki iki veri tipini daha inceleyeceiz. nceleyeceimiz veri tiplerinin ad
kme ve dondurulmu kme.
zellikle kmeleri rendiimizde, bu veri tipinin kendine has birtakm zellikleri sayesinde
bunlarn kimi zaman hi tahmin bile edemeyeceimiz yerlerde iimize yaradn greceiz.
Normalde uzun uzun kod yazmay gerektiren durumlarda kmeleri kullanmak, bir-iki satrla
ilerimizi halletmemizi salayabilir.
Bu blmde kmeler dnda, bir de dondurulmu kmelerden sz edeceiz. Bu iki veri tipi
birbiriyle ilikilidir. O yzden bu iki veri tipini tek blmde ele alacaz.
sterseniz anlatmaya nce kmelerle balayalm.

33.1 Kmeler

Tpk listeler, demetler, karakter dizileri, saylar ve dosyalar gibi kmeler de Pythondaki veri
tiplerinden biridir. Adndan da az ok tahmin edebileceiniz gibi kmeler, matematikten
bildiimiz kme kavramyla sk skya balantldr. Bu veri tipi, matematikteki kmelerin
sahip olduu btn zellikleri tar. Yani matematikteki kmelerden bildiimiz kesiim,
birleim ve fark gibi zellikler Pythondaki kmeler iin de geerlidir.

33.1.1 Kme Oluturmak

Kmelerin bize sunduklarndan faydalanabilmek iin elbette ncelikle bir kme oluturmamz
gerekiyor. Kme oluturmak ok kolay bir ilemdir. rnein bo bir kmeyi yle
oluturuyoruz:
>>> bo_kme = set()

Listeler, demetler ve szlklerin aksine kmelerin ayrt edici bir iareti yoktur. Kme
oluturmak iin set() adl zel bir fonksiyondan yararlanyoruz.
Yukardaki bo veri tipinin bir kme olduunu nasl teyit edeceinizi biliyorsunuz:
>>> type(bo_kme)

<class 'set'>

Grdnz gibi, Python programlama dilinde kmeler set ifadesiyle gsteriliyor.

496
Python 3 iin Trke Klavuz, Srm 3

Yukarda bo bir kme oluturduk. inde e de barndran kmeleri ise u ekilde


oluturuyoruz:
>>> kme = set(["elma", "armut", "kebap"])

Bylelikle, iinde e barndran ilk kmemizi baaryla oluturduk. Dikkat ederseniz, kme
olutururken listelerden faydalandk. Grdnz gibi set() fonksiyonu iindeki eler bir
liste iinde yer alyor. Dolaysyla yukardaki tanmlamay yle de yapabiliriz:
>>> liste = ["elma", "armut", "kebap"]
>>> kme = set(liste)

Bu daha temiz bir grnt oldu. Elbette kme tanmlamak iin mutlaka liste kullanmak
zorunda deiliz. stersek demetleri de kme haline getirebiliriz:
>>> demet = ("elma", "armut", "kebap")
>>> kme = set(demet)

Hatta ve hatta karakter dizilerinden dahi kme yapabiliriz:


>>> kardiz = "Python Programlama Dili iin Trke Kaynak"
>>> kme = set(kardiz)

Kullandmz karakter dizisinin byle uzun olmasna da gerek yok. Tek karakterlik dizilerden
bile kme oluturabiliriz:
>>> kardiz = "a"
>>> kme = set(kardiz)

Ama saylardan kme oluturamayz:


>>> n = 10
>>> kme = set(n)

TypeError: 'int' object is not iterable

Peki szlkleri kullanarak kme oluturabilir miyiz? Elbette, neden olmasn?


>>> bilgi = {"iletim sistemi": "GNU", "sistem ekirdei": "Linux",
... "datm": "Ubuntu GNU/Linux"}

>>> kme = set(bilgi)

Kme oluturmann son bir ynteminden daha sz edelim. En bata sylediimiz gibi, listeler,
demetler, szlkler ve karakter dizilerinin aksine kmelerin [ ], ( ), { }, gibi ayrt edici bir
iareti yoktur. Ama eer istersek szlkleri oluturmak iin kullandmz zel iaretleri kme
oluturmak iin de kullanabiliriz. Dikkatlice bakn:
>>> kme = {'Python', 'C++', 'Ruby', 'PHP'}

Grdnz gibi, aslnda szlklerin ayrt edici iareti olan ssl parantezleri kullanarak ve
eleri birbirinden virglle ayrarak da kme adl veri tipini elde edebiliyoruz. Teyit edelim
bunu:
>>> type(kme)

<class 'set'>

33.1. Kmeler 497


Python 3 iin Trke Klavuz, Srm 3

Ancak bu yapy kullanarak bo bir kme oluturamazsnz:


>>> kme = {}

Bu ekilde oluturduunuz ey bir kme deil, szlk olacaktr:


>>> type(kme)

<class 'dict'>

Bo bir kme oluturmak iin set() fonksiyonunu kullanmanz gerektiini biliyorsunuz:


>>> kme = set(kme)
>>> type(kme)

<class 'set'>

Bylece kmeleri nasl oluturacamz rendik. Eer oluturduunuz kmeyi ekrana


yazdrmak isterseniz, ne yapacanz biliyorsunuz. Tanmladnz kme deikenini
kullanmanz yeterli olacaktr:
>>> kme

{'iletim sistemi', 'sistem ekirdei', 'datm'}

Bu arada, bir szl kmeye evirdiinizde, elbette szln yalnzca anahtarlar kmeye
eklenecektir. Szln deerleri ise byle bir ilemin sonucunda ortadan kaybolur.
Eer bir szl kmeye evirirken hem anahtarlar hem de deerleri korumak gibi bir
niyetiniz varsa yle bir ey yazabilirsiniz:
Szlmz u:
>>> bilgi = {"iletim sistemi": "GNU", "sistem ekirdei": "Linux",
... "datm": "Ubuntu GNU/Linux"}

Bu szlkteki anahtar-deer iftlerini bir kme iine, ift eli demetler olarak yerletirebiliriz:
>>> liste = [(anahtar, deer) for anahtar, deer in bilgi.items()]
>>> kme = set(liste)

Grdnz gibi, liste retelerini kullanarak nce bir liste oluturuyoruz. Bu liste her bir
anahtar ve deeri tek tek bir demet iine yerletiriyor. Daha sonra da bu listeyi set()
fonksiyonuna gndererek kmemizi oluturuyoruz.

33.1.2 Kmelerin Yaps

Bir nceki balk altnda kmelerin nasl tanmlanacan inceledik. Gelin imdi de biraz
kmelerin yapsndan bahsedelim.
rnein yle bir kme tanmlayalm:
>>> kardiz = "Python Programlama Dili"
>>> kme = set(kardiz)
>>> print(kme)

{'g', 'D', 'a', ' ', 'o', 'n', 'm', 'l', 'i', 'h', 't', 'r', 'P', 'y'}

498 Blm 33. Kmeler ve Dondurulmu Kmeler


Python 3 iin Trke Klavuz, Srm 3

Burada bir ey dikkatinizi ekmi olmal. Bir eyi kme olarak tanmlayp ekrana
yazdrdmzda elde ettiimiz kt, o e iindeki her bir alt eyi tek bir kez ieriyor. Yani
mesela Python Programlama Dili iinde iki adet P karakteri var, ama ktda bu iki P
karakterinin yalnzca biri grnyor. Buradan anlyoruz ki, kmeler ayn eyi birden fazla
tekrar etmez. Bu ok nemli bir zelliktir ve pek ok yerde iimize yarar. Ayn durum karakter
dizisi dnda kalan teki veri tipleri iin de geerlidir. Yani mesela eer bir listeyi kme haline
getiriyorsak, o listedeki eler kme iinde yalnzca bir kez geecektir. Listede ayn eden
iki- tane bulunsa bile, kmemiz bu eleri teke indirecektir.
>>> liste = ["elma", "armut", "elma", "kebap", "eker", "armut",
... "ilek", "aa", "eker", "kebap", "eker"]

>>> for i in set(liste):


... print(i)
...
aa
elma
eker
kebap
ilek
armut

Grdnz gibi, liste iinde birden fazla bulunan eler, Pythondaki kmeler yardmyla
teke indirilebiliyor.
rendiimiz bu bilgi sayesinde, daha nce grdmz count() metodunu da kullanarak,
yle bir kod yazabiliriz:
>>> liste = ["elma", "armut", "elma", "kiraz",
... "ilek", "kiraz", "elma", "kebap"]

>>> for i in set(liste):


... print("{} listede {} kez geiyor!".format(i, liste.count(i)))

kebap listede 1 kez geiyor!


elma listede 3 kez geiyor!
kiraz listede 2 kez geiyor!
armut listede 1 kez geiyor!
ilek listede 1 kez geiyor!

Burada set(liste) ifadesini kullanarak, liste elerini eiz ve benzersiz bir hale getirdik.
Kmelerin nemli bir zellii de, tpk szlkler gibi, herhangi bir ekilde e sras kavramna
sahip olmamasdr.
Dikkatlice bakn:
>>> arayz_takmlar = {'Tkinter', 'PyQT', 'PyGobject'}
>>> arayz_takmlar

{'PyGobject', 'PyQT', 'Tkinter'}

Szlklerde karlatmz durumun aynsnn kmeler iin de geerli olduuna dikkatinizi


ekmek isterim. Grdnz gibi, arayz_takmlar adl kmenin eleri, e tanmlama
srasn ktda korumuyor. Biz Tkinter esini kmenin ilk srasna yerletirmitik, ama bu
e ktda en sona gitti... Aynen szlklerde olduu gibi, kmelerde de elerin tanmlanma
srasna bel balayarak herhangi bir ilem yapamazsnz. Bu durumun bir yansmas olarak,
kme elerine sralarna gre de eriemezsiniz:

33.1. Kmeler 499


Python 3 iin Trke Klavuz, Srm 3

>>> arayz_takmlar[0]

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: 'set' object does not support indexing

Tpk hata mesajnda da sylendii gibi, kme adl veri tipi asndan e sras diye bir kavram
yoktur...
Esasnda tek bir kme pek bir ie yaramaz. Kmeler ancak birden fazla olduunda
bunlarla yararl iler yapabiliriz. nk kmelerin en nemli zellii, baka kmelerle
karlatrlabilme kabiliyetidir. Yani mesela kmelerin kesiimini, birleimini veya farkn
bulabilmek iin ncelikle elimizde birden fazla kme olmas gerekiyor. te biz de imdi bu
tr ilemleri nasl yapacamz reneceiz. O halde hi vakit kaybetmeden yolumuza devam
edelim.

33.1.3 Kme reteleri (Set Comprehensions )

Bildiiniz gibi liste reteleri, liste oluturmann ksa ve temiz bir yoludur. Ayn ekilde szlk
reteleri de szlk oluturmann ksa ve temiz bir yoludur.
te liste retelerini ve szlk retelerini kullanarak nasl tek satrda ve hzl bir ekilde
listeler ve szlkler retebiliyorsak, ayn ekilde kme retelerini kullanarak tek satrda ve
hzl bir ekilde kmeler de retebiliriz.
rnein elimizde yle bir liste olduunu dnelim:
import random

liste = [random.randint(0, 10000) for i in range(1000)]

Bu arada, buradaki random adl modle imdilik taklmayn. Birka blm sonra bu modl
inceleyeceiz. Biz imdilik random un da tpk sys ve os gibi bir modl olduunu ve rastgele
saylar retmemizi saladn bilelim yeter. Yukardaki kodlarda da bu modl 0 ile 10000
arasnda rstgele 1000 adet say retmemizi salad.
imdi amacmz bu liste iinde yer alan saylardan, deeri 100 den kk olanlar bulmak.
Bunun iin u kodlar kullanabiliriz:
import random

liste = [random.randint(0, 10000) for i in range(1000)]

yzden_kk_saylar = [i for i in liste if i < 100]


print(yzden_kk_saylar)

Ancak ortaya kan listede ayn saylardan birka tane olabilir. te eer birbirinin ayn
olmayan saylardan olumu bir listeyi hzl ve pratik bir ekilde elde etmek istiyorsanz kme
retelerini kullanabilirsiniz:
import random

liste = [random.randint(0, 10000) for i in range(1000)]

500 Blm 33. Kmeler ve Dondurulmu Kmeler


Python 3 iin Trke Klavuz, Srm 3

kme = {i for i in liste if i < 100}


print(kme)

Grdnz gibi, kme retelerinin szdizimi, liste ve szlk retelerinin szdizimine ok


benziyor.

33.1.4 Kmelerin Metotlar

Daha nceki veri tiplerinde olduu gibi, kmelerin de metotlar vardr. Artk biz bir veri tipinin
metotlarn nasl listeleyeceimizi ok iyi biliyoruz. Nasl liste iin list(); demet iin tuple();
szlk iin de dict() fonksiyonlarn kullanyorsak, kmeler iin de set() adl fonksiyondan
yararlanacaz:
>>> dir(set)

['__and__', '__class__', '__contains__', '__delattr__', '__doc__',


'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__iand__', '__init__', '__ior__', '__isub__', '__iter__',
'__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__',
'__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__',
'__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__',
'__str__', '__sub__', '__subclasshook__', '__xor__', 'add',
'clear','copy', 'difference', 'difference_update', 'discard',
'intersection', 'intersection_update', 'isdisjoint', 'issubset',
'issuperset', 'pop', 'remove', 'symmetric_difference',
'symmetric_difference_update', 'union', 'update']

Hemen iimize yarayacak metotlar alalm:


>>> for i in dir(set):
... if "__" not in i:
... print(i)
...
add
clear
copy
difference
difference_update
discard
intersection
intersection_update
isdisjoint
issubset
issuperset
pop
remove
symmetric_difference
symmetric_difference_update
union
update

Grdnz gibi kmelerin epey metodu var. Bu arada if "__" not in i satrnda
_ yerine __ kullandmza dikkat edin. Neden? nk eer sadece _
kullanrsak symmetric_difference ve symmetric_difference_update metotlar ktmzda yer
almayacaktr.

33.1. Kmeler 501


Python 3 iin Trke Klavuz, Srm 3

Unutmadan syleyelim: Kmeler de, tpk listeler ve szlkler gibi, deitirilebilir bir veri
tipidir.

clear()

Kmelerle ilgili olarak inceleyeceimiz ilk metot clear(). Bu metodu daha nce szlkleri
alrken de grmtk. Szlklerde bu metodun grevi szln iini boaltmak idi. Burada
da ayn vazifeyi grr:
>>> km = set("adana")
>>> for i in km:
... print(i)
...
a
d
n

>>> km.clear()
>>> km
set()

Burada nce km adl bir kme oluturduk. Daha sonra da clear() metodunu kullanarak bu
kmenin btn elerini sildik. Artk elimizde bo bir kme var.

copy()

Listeler ve szlkleri incelerken copy() adl bir metot renmitik. Bu metot ayn zamanda
kmelerle birlikte de kullanlabilir. stelik ilevi de ayndr:
>>> km = set("kahramanmara")
>>> yedek = km.copy()
>>> yedek

{'a', 'r', 'h', 'k', 'm', '', 'n'}

>>> km

{'a', 'h', 'k', 'm', 'n', 'r', ''}

Burada bir ey dikkatinizi ekmi olmal. km adl kmeyi yedek adyla kopyaladk, ama
bu iki kmenin ktlarna baktmz zaman e sralamasnn birbirinden farkl olduunu
gryoruz. Biliyorsunuz, tpk szlklerde olduu gibi, kmeler de srasz veri tipleridir. Bu
yzden, elde ettiimiz ktda eler rastgele diziliyor. Dolaysyla elere sralarna gre
eriemiyoruz. Aynen szlklerde olduu gibi...

add()

Kmelerden bahsederken, bunlarn deitirilebilir bir veri tipi olduunu sylemitik.


Dolaysyla kmeler, zerlerinde deiiklik yapmamza msaade eden metotlar da ierir.
rnein add() bu tr metotlardan biridir. Add kelimesi Trkede eklemek anlamna gelir.
Adndan da anlalaca gibi, bu metot yardmyla kmelerimize yeni eler ilave edebileceiz.
Hemen bunun nasl kullanldna bakalm:

502 Blm 33. Kmeler ve Dondurulmu Kmeler


Python 3 iin Trke Klavuz, Srm 3

>>> kme = set(["elma", "armut", "kebap"])


>>> kme.add("ilek")
>>> print(kme)

{'elma', 'armut', 'kebap', 'ilek'}

Grdnz gibi, add() metodunu kullanarak, kmemize ilek adl yeni bir e ekledik.
Eer kmede zaten varolan bir e eklemeye alrsak kmede herhangi bir deiiklik
olmayacaktr. nk, daha nce de sylediimiz gibi, kmeler her bir eyi tek bir sayda
barndrr.
Eer bir kmeye birden fazla eyi ayn anda eklemek isterseniz for dngsnden
yararlanabilirsiniz:
>>> yeni = [1,2,3]
>>> for i in yeni:
... kme.add(i)
...

>>> kme

{1, 2, 3, 'elma', 'kebap', 'ilek', 'armut'}

Burada yeni adl listeyi kmeye for dngs ile ekledik. Ama bu ilemi yapmann baka bir
yolu daha vardr. Bu ilem iin Pythonda ayr bir metot bulunur. Bu metodun ad update()
metodudur. Sras gelince bu metodu da greceiz.
Bu arada, yeri gelmiken kmelerin nemli bir zelliinden daha sz edelim. Bir kmeye
herhangi bir e ekleyebilmemiz iin, o enin deitirilemeyen (immutable ) bir veri tipi
olmas gerekiyor. Bildiiniz gibi Pythondaki u veri tipleri deitirilemeyen veri tipleridir:
1. Demetler
2. Saylar
3. Karakter Dizileri
u veri tipleri ise deitirilebilen veri tipleridir:
1. Listeler
2. Szlkler
3. Kmeler
Dolaysyla bir kmeye ancak u veri tiplerini ekleyebiliriz:
1. Demetler
2. Saylar
3. Karakter Dizileri
u kodlar dikkatlice inceleyin:
nce bo bir kme oluturalm:
>>> kme = set()

Bu kmeye bir demet ekleyelim:

33.1. Kmeler 503


Python 3 iin Trke Klavuz, Srm 3

>>> l = (1,2,3)
>>> kme.add(l)
>>> kme

{(1, 2, 3)}

Bir say ekleyelim:


>>> l = 45
>>> kme.add(l)
>>> kme

{45, (1, 2, 3)}

Bir karakter dizisi ekleyelim:


>>> l = 'Jacques Derrida'
>>> kme.add(l)
>>> kme

{'Jacques Derrida', 45, (1, 2, 3)}

Yukardakiler, deitirilemeyen veri tipleri olduu iin kmelere eklenebilir.


Bir de unlara bakalm:
Kmemize bir liste eklemeye alalm:
>>> l = [1,2,3]
>>> kme.add(l)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

Kmemize bir szlk eklemeye alalm:


>>> l = {"a": 1, "b": 2, "c": 3}
>>> kme.add(l)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'

Kmemize bir kme eklemeye alalm:


>>> l = {1, 2, 3}
>>> kme.add(l)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

Grdnz gibi, tpk szlklerde olduu gibi, bir kmeye herhangi bir veri ekleyebilmemiz
iin o verinin deitirilemeyen bir veri tipi olmas gerekiyor.

504 Blm 33. Kmeler ve Dondurulmu Kmeler


Python 3 iin Trke Klavuz, Srm 3

difference()

Bu metot iki kmenin farkn almamz salar. rnein:


>>> k1 = set([1, 2, 3, 5])
>>> k2 = set([3, 4, 2, 10])

>>> k1.difference(k2)

{1, 5}

Demek ki k1in k2den fark buymu. Peki k2nin k1den farkn bulmak istersek ne yapacaz?
>>> k2.difference(k1)

{10, 4}

Grdnz gibi, birinci kullanmda, k1de bulunup k2de bulunmayan eleri elde ediyoruz.
kinci kullanmda ise bunun tam tersi. Yani ikinci kullanmda k2de bulunup k1de bulunmayan
eleri alyoruz.
sterseniz uzun uzun difference() metodunu kullanmak yerine sadece eksi (-) iaretini
kullanarak da ayn sonucu elde edebilirsiniz:
>>> k1 - k2

...veya...
>>> k2 - k1

Hayr, madem eksi iaretini kullanabiliyoruz, o halde art iaretini de kullanabiliriz! gibi bir
kir doru deildir.

difference_update()

Bu metot, difference() metodundan elde edilen sonuca gre bir kmenin gncellenmesini
salar. Yani? Hemen bir rnek verelim:
>>> k1 = set([1, 2, 3])
>>> k2 = set([1, 3, 5])
>>> k1.difference_update(k2)
>>> print(k1)

{2}

>>> print(k2)

{1, 3, 5}

Grdnz gibi, bu metot k1in k2den farkn ald ve bu fark kullanarak k1i yeniden
oluturdu. k1 ile k2 arasndaki tek fark 2 adl e idi. Dolaysyla difference_update()
metodunu uyguladmzda k1in elerinin silinip yerlerine 2 adl enin geldiini gryoruz.

33.1. Kmeler 505


Python 3 iin Trke Klavuz, Srm 3

discard()

Bir nceki blmde rendiimiz add() metodu yardmyla, nceden oluturduumuz bir
kmeye yeni eler ekleyebiliyorduk. Bu blmde reneceimiz discard() metodu ise
kmeden e silmemizi salayacak:
>>> hayvanlar = set(["kedi", "kpek", "at", "ku", "inek", "deve"])
>>> hayvanlar.discard("kedi")
>>> print(hayvanlar)

{'ku', 'inek', 'deve', 'kpek', 'at'}

Eer kme iinde bulunmayan bir e silmeye alrsak hi bir ey olmaz. Yani hata mesaj
almayz:
>>> hayvanlar.discard("ylan")

Burada etkileimli kabuk sessizce bir alt satra geecektir. Bu metodun en nemli zellii
budur. Yani olmayan bir eyi silmeye altmzda hata vermemesi.

remove()

Bu metot da bir nceki blmde grdmz discard() metoduyla ayn ilevi yerine getirir.
Eer bir kmeden e silmek istersek remove() metodunu da kullanabiliriz:
>>> hayvanlar.remove("kpek")

Peki discard() varken remove() metoduna ne gerek var? Ya da tersi.


Bu iki metot ayn ilevi yerine getirse de aralarnda nemli bir fark vardr. Hatrlarsanz
discard() metoduyla, kmede olmayan bir eyi silmeye alrsak herhangi bir hata mesaj
almayacamz sylemitik. Eer remove() metodunu kullanarak, kmede olmayan bir eyi
silmeye alrsak, discard() metodunun aksine, hata mesaj alrz:
>>> hayvanlar.remove("fare")

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
KeyError: 'fare'

Bu iki metot arasndaki bu fark nemli bir farktr. Bazen yazdnz programlarda, duruma
gre her iki zellie de ihtiyacnz olabilir.

intersection()

intersection kelimesi Trkede kesiim anlamna gelir. Adndan da anladmz gibi,


intersection() metodu bize iki kmenin kesiim kmesini verecektir:
>>> k1 = set([1, 2, 3, 4])
>>> k2 = set([1, 3, 5, 7])
>>> k1.intersection(k2)

{1, 3}

506 Blm 33. Kmeler ve Dondurulmu Kmeler


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, bu metot bize k1 ve k2nin kesiim kmesini veriyor. Dolaysyla bu iki kme
arasndaki ortak elemanlar bulmu oluyoruz.
Hatrlarsanz, difference() metodunu anlatrken, difference() kelimesi yerine - iaretini de
kullanabileceimiz, sylemitik. Benzer bir durum intersection() metodu iin de geerlidir.
ki kmenin kesiimini bulmak iin & iaretinden yararlanabiliriz:
>>> k1 & k2

{1, 3}

Python programclar genellikle uzun uzun intersection yazmak yerine & iaretini
kullanrlar...
sterseniz bu metot iin rnek bir program verelim. Bylece gerek hayatta bu metodu nasl
kullanabileceimizi grm oluruz:

tr = ""

parola = input("Sisteme giri iin bir parola belirleyin: ")

if set(tr) & set(parola):


print("Parolanzda Trke harfler kullanmayn!")

else:
print("Parolanz kabul edildi!")

Burada eer kullanc, parola belirlerken iinde Trke bir harf geen bir kelime yazarsa
programmz kendisini Trke harf kullanmamas konusunda uyaracaktr. Bu kodlarda
kmeleri nasl kullandmza dikkat edin. Programda asl ii yapan ksm u satrdr:
if set(tr) & set(parola):
print("Parolanzda Trke harfler kullanmayn!")

Burada aslnda yle bir ey demi oluyoruz:


Eer set(tr) ve set(parola) kmelerinin kesiim kmesi bo deilse, kullancya
Parolanzda Trke harer kullanmayn! uyarsn gster!
set(tr) ve set(parola) kmelerinin kesiim kmesinin bo olmamas, kullancnn girdii
kelime iindeki harerden en az birinin tr adl deiken iinde getii anlamna gelir. Burada
basite, tr deikeni ile parola deikeni arasndaki ortak eleri sorguluyoruz. Eer kullanc
herhangi bir Trke harf iermeyen bir kelime girerse set(tr) ve set(parola) kmelerinin
kesiim kmesi bo olacaktr. sterseniz kk bir deneme yapalm:

>>> tr = ""
>>> parola = "ilek"
>>> set(tr) & set(parola)

{''}

Burada kullancnn ilek adl kelimeyi girdiini varsayyoruz. Byle bir durumda set(tr)
ve set(parola) kmelerinin kesiim kmesi harni ierecek, dolaysyla da programmz
kullancya uyar mesaj gsterecektir. Eer kullancmz kalem gibi Trke harf iermeyen
bir kelime girerse:

33.1. Kmeler 507


Python 3 iin Trke Klavuz, Srm 3

>>> tr = ""
>>> parola = "kalem"
>>> set(tr) & set(parola)

set()

Grdnz gibi, elde ettiimiz kme bo. Dolaysyla byle bir durumda programmz
kullancya herhangi bir uyar mesaj gstermeyecektir.
intersection() metodunu pek ok yerde kullanabilirsiniz. Hatta iki dosya arasndaki
benzerlikleri bulmak iin dahi bu metottan yararlanabilirsiniz. lerde dosya ilemleri
konusunu ilerken bu metottan nasl yararlanabileceimizi de anlatacaz.

intersection_update()

Hatrlarsanz difference_update() metodunu ilerken yle bir ey demitik:


Bu metot, difference() metodundan elde edilen sonuca gre bir kmenin gncellenmesini
salar.
te intersection_update metodu da buna ok benzer bir ilevi yerine getirir. Bu metodun
grevi, intersection() metodundan elde edilen sonuca gre bir kmenin gncellenmesini
salamaktr:
>>> k1 = set([1, 2, 3])
>>> k2 = set([1, 3, 5])
>>> k1.intersection_update(k2)
>>> print(k1)

{1, 3}

>>> print(k2)

{1, 3, 5}

Grdnz gibi, intersection_update() metodu k1in btn elerini sildi ve yerlerine k1 ve


k2nin kesiim kmesinin elemanlarn koydu.

isdisjoint()

Bu metodun ok basit bir grevi vardr. isdisjoint() metodunu kullanarak iki kmenin kesiim
kmesinin bo olup olmad sorgulayabilirsiniz. Hatrlarsanz ayn ii bir nceki blmde
grdmz intersection() metodunu kullanarak da yapabiliyorduk. Ama eer hayattan tek
beklentiniz iki kmenin kesiim kmesinin bo olup olmadn, yani bu iki kmenin ortak
eleman ierip iermediini renmekse, basite isdisjoint() metodundan yararlanabilirsiniz:
>>> a = set([1, 2, 3])
>>> b = set([2, 4, 6])
>>> a.isdisjoint(b)

False

Grdnz gibi, a ve b kmesinin kesiimi bo olmad iin, yani bu iki kme ortak en az bir
e barndrd iin, isdisjoint() metodu False kts veriyor. Burada temel olarak u soruyu
sormu oluyoruz:

508 Blm 33. Kmeler ve Dondurulmu Kmeler


Python 3 iin Trke Klavuz, Srm 3

a ve b ayrk kmeler mi?


Python da bize cevap olarak, Hayr deil, anlamna gelen False ktsn veriyor... nk a
ve b kmelerinin ortak bir eleman var (2 ).
Bir de una bakalm:
>>> a = set([1, 3, 5])
>>> b = set([2, 4, 6])
>>> a.isdisjoint(b)

True

Burada a ve b kmeleri ortak hi bir elemana sahip olmad iin Doru anlamna gelen True
ktsn elde ediyoruz.

issubset()

Bu metot yardmyla, bir kmenin btn elemanlarnn baka bir kme iinde yer alp yer
almadn sorgulayabiliriz. Yani bir kmenin, baka bir kmenin alt kmesi olup olmadn
bu metot yardmyla renebiliriz. Eer bir kme baka bir kmenin alt kmesi ise bu metot
bize True deerini verecek; eer deilse False ktsn verecektir:
>>> a = set([1, 2, 3])
>>> b = set([0, 1, 2, 3, 4, 5])
>>> a.issubset(b)

True

Bu rnekte True ktsn aldk, nk a kmesinin btn eleri b kmesi iinde yer alyor.
Yani a, bnin alt kmesidir.

issuperset()

Bu metot, bir nceki blmde grdmz issubset() metoduna benzer. Matematik


derslerinde grdmz kmeler konusunda hatrladnz b kmesi a kmesini kapsar
ifadesini bu metotla gsteriyoruz. nce bir nceki derste grdmz rnee bakalm:
>>> a = set([1, 2, 3])
>>> b = set([0, 1, 2, 3, 4, 5])
>>> a.issubset(b)

True

Buradan, a kmesi b kmesinin alt kmesidir, sonucuna ulayoruz. Bir de una bakalm:
>>> a = set([1, 2, 3])
>>> b = set([0, 1, 2, 3, 4, 5])
>>> b.issuperset(a)

True

Burada ise, b kmesi a kmesini kapsar, sonucunu elde ediyoruz. Yani b kmesi a kmesinin
btn elemanlarn iinde barndryor.

33.1. Kmeler 509


Python 3 iin Trke Klavuz, Srm 3

union()

union() metodu iki kmenin birleimini almamz salar. Hemen bir rnek verelim:
>>> a = set([2, 4, 6, 8])
>>> b = set([1, 3, 5, 7])
>>> a.union(b)

{1, 2, 3, 4, 5, 6, 7, 8}

nceki blmlerde grdmz baz metotlarda olduu gibi, union() metodu da bir ksayola
sahiptir. union() metodu yerine | iaretini de kullanabiliriz:
>>> a | b

union() metodu yerine, bu metodun ksayolu olan | iareti Python programclar tarafndan
daha sk kullanlr.

update()

Hatrlarsanz add() metodunu anlatrken yle bir rnek vermitik:


>>> kme = set(["elma", "armut", "kebap"])
>>> yeni = [1, 2, 3]

>>> for i in yeni:


... kme.add(i)
...
>>> kme

{1, 2, 3, 'elma', 'armut', 'kebap'}

Bu rnei verdikten sonra da yle bir ey demitik:


Burada yeni adl listeyi kmeye for dngs ile ekledik. Ama bu ilemi yapmann baka bir
yolu daha vardr. Bu ilem iin Pythonda ayr bir metot bulunur.
te bu metodu renmenin vakti geldi. Metodumuzun ad update(). Bu metot, bir kmeyi
gncellememizi salar. sterseniz yukardaki rnei, bu metodu kullanarak tekrar yazalm:
>>> kme = set(["elma", "armut", "kebap"])
>>> yeni = [1, 2, 3]
>>> kme.update(yeni)
>>> print(kme)

{1, 2, 3, 'elma', 'armut', 'kebap'}

Grdnz gibi, for dngsn kullanmaya gerek kalmadan ayn sonucu elde edebildik.

symmetric_difference()

Daha nceki blmlerde difference() metodunu kullanarak iki kme arasndaki farkl eleri
bulmay renmitik. rnein elimizde yle iki kme var diyelim:

510 Blm 33. Kmeler ve Dondurulmu Kmeler


Python 3 iin Trke Klavuz, Srm 3

>>> a = set([1, 2, 5])


>>> b = set([1, 4, 5])

Eer a kmesinin b kmesinden farkn bulmak istersek yle yapyoruz:


>>> a.difference(b)

{2}

Demek ki a kmesinde bulunup b kmesinde bulunmayan e 2 imi.


Bir de b kmesinde bulunup a kmesinde bulunmayan elere bakalm:
>>> b.difference(a)

{4}

Bu da bize 4 ktsn verdi. Demek ki bu e b kmesinde bulunuyor, ama a kmesinde


bulunmuyormu. Peki ya kmelerin ikisinde de bulunmayan eleri ayn anda nasl alacaz?
ite bu noktada yardmmza symmetric_difference() adl metot yetiecek:
>>> a.symmetric_difference(b)

{2, 4}

Bylece iki kmede de bulunmayan eleri ayn anda alm olduk.

symmetric_difference_update()

Daha nce difference_update ve intersection_update gibi metotlar renmitik.


symmetric_difference_update() metodu da bunlara benzer bir ilevi yerine getirir:
>>> a = set([1,2, 5])
>>> b = set([1,4, 5])
>>> a.symmetric_difference_update(b)
>>> print(a)

{2, 4}

Grdnz gibi, a kmesinin eski eleri gitti, yerlerine symmetric_difference() metoduyla


elde edilen kt geldi. Yani a kmesi, symmetric_difference() metodunun sonucuna gre
gncellenmi oldu...

pop()

nceleyeceimiz son metot pop() metodu olacak. Geri bu metot bize hi yabanc deil.
Bu metodu listeler konusundan hatrlyoruz. Orada rendiimize gre, bu metot listenin
bir esini silip ekrana basyordu. Aslnda buradaki fonksiyonu da farkl deil. Burada da
kmelerin elerini silip ekrana basyor:
>>> a = set(["elma", "armut", "kebap"])
>>> a.pop()

'elma'

33.1. Kmeler 511


Python 3 iin Trke Klavuz, Srm 3

Peki bu metot hangi lte gre kmeden e siliyor? Herhangi bir lt yok. Bu metot,
kme elerini tamamen rastgele siliyor.
Bylelikle Pythonda Listeler, Demetler, Szlkler ve Kmeler konusunu bitirmi olduk. Bu
konular sk sk tekrar etmek, hi olmazsa arada srada gz gezdirmek baz eylerin zihnimizde
yer etmesi asndan olduka nemlidir.

33.2 Dondurulmu Kmeler (Frozenset)

Daha nce de sylediimiz gibi, kmeler zerinde deiiklik yapabiliyoruz. Zaten kmelerin
add() ve remove() gibi metotlarnn olmas bu durumu teyit ediyor. Ancak kimi durumlarda,
eleri zerinde deiiklik yaplamayan kmelere de ihtiya duyabilirsiniz. Hatrlarsanz
listeler ve demetler arasnda da buna benzer bir iliki var. Demetler ou zaman, zerinde
deiiklik yaplamayan bir liste gibi davranr. te Python ayn imkan bize kmelerde de
salar. Eer eleri zerinde deiiklik yaplamayan bir kme oluturmak isterseniz set()
yerine frozenset() fonksiyonunu kullanabilirsiniz. Dilerseniz hemen bununla ilgili bir rnek
verelim:
>>> dondurulmu = frozenset(["elma", "armut", "ayva"])

Dondurulmu kmeleri bu ekilde oluturuyoruz. imdi bu dondurulmu kmenin


metotlarna bakalm:
>>> dir(dondurulmu)

['__and__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__',


'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__',
'__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__',
'__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__',
'__subclasshook__', '__xor__', 'copy', 'difference', 'intersection',
'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']

Grdnz gibi, add(), remove(), update() gibi, deiiklik yapmaya ynelik metotlar listede
yok.
Dondurulmu kmeler ile normal kmeler arasnda ilev olarak hibir fark yoktur. Bu ikisi
arasndaki fark, listeler ile demetler arasndaki fark gibidir.

512 Blm 33. Kmeler ve Dondurulmu Kmeler


BLM 34

Fonksiyonlar

lk derslerimizden bu yana bir ey zellikle dikkatinizi ekmi olmal: lk andan itibaren hep
fonksiyon diye bir kavramdan sz ettik; stelik yazdmz kodlarda da bu fonksiyon denen
eyi bolca kullandk. Evet, belki bu kavram imdiye dek enine boyuna inceleme frsatmz hi
olmad, ama yine de adnn fonksiyon olduunu sylediimiz pek ok ara tandk bu noktaya
gelinceye kadar.
Herhalde, Fonksiyon denince aklnza ilk ne geliyor? diye bir soru sorsam, vereceiniz cevap
print() fonksiyonu olacaktr. Gerekten de bu fonksiyonu ilk derslerimizden bu yana o kadar
sk kullandk ki, fonksiyon denince aklnza ilk bu fonksiyonun gelmesi gayet doal.
Elbette rendiimiz tek fonksiyon print() deildi. Bunun dnda type() diye bir
fonksiyondan da sz etmitik. print() kadar olmasa da, type() fonksiyonunu da yazdmz
kodlarda epey kullandk. print() ve type() dnda, fonksiyon olarak str(), int() ve
benzeri aralarla da tantk. Bunlarn dnda pek ok baka fonksiyon da Pythonla birlikte
hayatmza girdi.
te bu blmde, en batan bu yana sklkla szn ettiimiz, ama hibir zaman tam
anlamyla ele almadmz bu kavram daha iyi anlayabilmek iin, fonksiyon konusunu ayrntl
olarak ele alacaz. Bu blmde amacmz fonksiyonlar enine boyuna inceleyerek, okurun
bilgi daarcnda fonksiyonlara ilikin salam bir altyap oluturmaktr. Okur, bu blm
bitirdikten sonra fonksiyonlara ilikin olarak bilmesi gereken her eyi renmi olacak.

34.1 Fonksiyon Nedir ve Ne e Yarar?

Biz imdiye dek karlatmz print(), len(), type() ve open() gibi rnekler sayesinde
fonksiyon denen eyi az ok tandmz syleyebiliriz. Dolaysyla fonksiyonun ne demek
olduunu eklen de olsa biliyoruz ve hatta fonksiyonlar kodlarmz iinde etkili bir ekilde
kullanabiliyoruz.
lk derslerimizden bu yana rendiimiz fonksiyonlara yle bir bakacak olursak,
fonksiyonlarn grnne ve yapsna dair herhalde u tespitleri yapabiliriz:
1. Her fonksiyonun bir ad bulunur ve fonksiyonlar sahip olduklar bu adlarla anlr. (print
fonksiyonu, open fonksiyonu, type fonksiyonu, input fonksiyonu, len fonksiyonu vb.)
2. ekil olarak, her fonksiyonun isminin yannda birer parantez iareti bulunur. (open(),
print(), input(), len() vb.)
3. Bu parantez iaretlerinin iine, fonksiyonlara ilevsellik kazandran baz parametreler
yazlr. (open(dosya_ad), print("Merhaba Zalim Dnya!"), len("kahramanmara")

513
Python 3 iin Trke Klavuz, Srm 3

vb.)
4. Fonksiyonlar farkl sayda parametre alabilir. rnein print() fonksiyonu toplam 256
adet parametre alabilirken, input() fonksiyonu yalnzca tek bir parametre alr.
5. Fonksiyonlarn isimli ve isimsiz parametreleri vardr. print() fonksiyonundaki sep,
end ve le parametreleri isimli parametrelere rnekken, mesela print("Merhaba
Dnya!") kodunda Merhaba Dnya! parametresi isimsiz bir parametredir. Ayn ekilde
input("Adnz: ") gibi bir kodda Adnz: parametresi isimsiz bir parametredir.
6. Fonksiyonlarn, isimli ve isimsiz parametreleri dnda, bir de varsaylan deerli
parametreleri vardr. rnein print() fonksiyonunun sep, end ve le parametreleri
varsaylan deerli parametrelere birer rnektir. Eer bir parametrenin varsaylan bir
deeri varsa, o parametreye herhangi bir deer vermeden de fonksiyonu kullanabiliriz.
Python bu parametrelere, belirli deerleri ntanml olarak kendisi atayacaktr. Tabii
eer istersek, varsaylan deerli parametrelere kendimiz de baka birtakm deerler
verebiliriz.
Fonksiyon kavramnn tam olarak ne olduunu henz bilmiyor da olsak, imdiye
kadar rendiimiz fonksiyonlara bakarak fonksiyonlar hakknda yukardaki karmlar
yapabiliyoruz. Demek ki aslnda fonksiyonlar hakknda alttan alta pek ok ey renmiiz.
O halde, fonksiyonlar hakknda imdiden bildiklerimize gvenerek, fonksiyon kavramnn ne
olduundan ziyade ne ie yarad konusuna rahatlkla eilebiliriz. Zaten fonksiyonlarn ne
ie yaradn rendikten sonra, fonksiyonlarn ne olduunu da hemencecik anlayacaksnz.
Fonksiyonlarn ne ie yaradn en genel ve en kaba haliyle tarif etmek istersek yle bir
tanmlama yapabiliriz:
Fonksiyonlarn grevi, karmak ilemleri bir araya toplayarak, bu ilemleri
tek admda yapmamz salamaktr. Fonksiyonlar ou zaman, yapmak
istediimiz ilemler iin bir ablon vazifesi grr. Fonksiyonlar kullanarak,
bir veya birka admdan oluan ilemleri tek bir isim altnda toplayabiliriz.
Pythondaki fonksiyon kavram baka programlama dillerinde rutin veya
prosedr olarak adlandrlr. Gerekten de fonksiyonlar rutin olarak tekrar
edilen grevleri veya prosedrleri tek bir ad/at altnda toplayan aralardr.
Dilerseniz yukardaki soyut ifadeleri basit bir rnek zerinde somutlatrmaya alalm.
rnein print() fonksiyonunu ele alalm.
Bu fonksiyonun grevini biliyorsunuz: print() fonksiyonunun grevi, kullancnn girdii
parametreleri ekrana kt olarak vermektir. Her ne kadar print() fonksiyonunun grevini,
ekrana kt vermek olarak tanmlasak da, aslnda bu fonksiyon, ekrana kt vermenin
yansra, baka bir takm ilave ilemler de yapar. Yani bu fonksiyon, aslnda ald
parametreleri sadece ekrana kt olarak vermekle yetinmez. rnein u komutu inceleyelim:

>>> print("Frat", "zgl", "1980", "Adana")

Burada print() fonksiyonu toplam drt adet parametre alyor. Fonksiyonumuz, grevi
gerei, bu parametreleri ekrana kt olarak verecek. Bu komutu altrdmzda yle bir
kt alyoruz:

Frat zgl 1980 Adana

Dikkat ederseniz, burada salt bir ekrana kt verme ileminden fazlas var. Zira print()
fonksiyonu ald parametreleri u ekilde de ekrana verebilirdi:

514 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Fratzgl1980Adana

Veya u ekilde:
F

r
a
t

z
g

l
1
9
8
0
A
d
a
n
a

Neticede bunlar da birer kt verme ilemidir. Ama dediimiz gibi, print() fonksiyonu ald
parametreleri sadece ekrana kt olarak vermekle yetinmiyor. Gelin isterseniz ne demek
istediimizi biraz daha aklayalm:
print() fonksiyonunun yukardaki komutu nasl algladn nceki derslerimizde
renmitik. Yukardaki komut Python tarafndan u ekilde alglanyor:

>>> print("Frat", "zgl", "1980", "Adana", sep=" ", end="\n",


... file=sys.stdout, flush=False)

Yani print() fonksiyonu;


1. Kendisine verilen Frat, zgl, 1980 ve Adana parametrelerini ekrana basyor,
2. sep= parametresinin etkisiyle, bu parametreler arasna birer boluk ekliyor,
3. end=\n parametresinin etkisiyle, sonuncu parametreyi de ekrana bastktan sonra bir
alt satra geiyor,
4. le=sys.stdout parametresinin etkisiyle, kt konumu olarak komut ekrann kullanyor.
Yani ktlar ekrana veriyor.
5. ush=False parametresinin etkisiyle, ktlar ekrana gnderilmeden nce tamponda
bekletiliyor.
Eer print() gibi bir fonksiyon olmasayd, yukarda listediimiz btn bu ilemleri kendimiz
yapmak zorunda kalacaktk. Yani ekranda gstermek istediimiz ifadeleri ekrana kt olarak
vermenin yansra, bunlarn ekranda nasl grneceini de tek tek kendimiz elle ayarlamak
zorunda kalacaktr. Ekrana kt verme ile ilgili pek ok ilem tek bir print() fonksiyonu
altnda birletirildii iin, her ihtiya duyduumuzda o ilemleri tek tek bizim yapmamza
gerek kalmyor.
Ayn ey mesela input() fonksiyonu iin de geerlidir. Bu fonksiyonu kullanarak,
programmz kullanan kiilerle etkileim iine girebiliyoruz. Tpk print() fonksiyonunda

34.1. Fonksiyon Nedir ve Ne e Yarar? 515


Python 3 iin Trke Klavuz, Srm 3

olduu gibi, input() fonksiyonu da aslnda alttan alta epey karmak ilemler gerekletirir.
Ama o karmak ilemlerin tek bir input() fonksiyonu iinde bir araya getirilmi
olmas sayesinde, sadece input() gibi basit bir komut vererek kullanclarmzla iletiime
geebiliyoruz.
Bu adan bakldnda fonksiyonlar deikenlere benzer. Bildiiniz gibi, her defasnda bir
deeri tekrar tekrar yazmak yerine bir deikene atayarak o deere kolayca eriebiliyoruz.
rnein:
>>> kurum = "Sosyal Sigortalar Kurumu"

Burada tanmladmz kurum adl deiken sayesinde, Sosyal Sigortalar Kurumu ifadesini
kullanmamz gereken her yerde sadece deiken adn kullanarak, deikenin tuttuu deere
ulaabiliyoruz. te fonksiyonlar da buna benzer bir ilev grr: rnein ekrana bir kt
vermemiz gereken her yerde, yukarda verdiimiz karmak admlar tek tek gerekletirmeye
almak yerine, bu karmak ve rutin admlar bir araya getiren print() gibi bir fonksiyondan
yararlanarak ilerimizi ok daha kolay bir ekilde halledebiliriz.
Bu anlattklarmz fonksiyonlarn ne ie yarad konusunda size bir kir vermi olabilir.
Dilerseniz bu anlattklarmz bir rnek araclyla biraz daha somutlatrmaya alalm:
Hatrlarsanz Kullancyla Veri Alverii balkl blmde yle bir rnek vermitik:
isim = "Frat"
soyisim = "zgl"
isis = "Ubuntu"
ehir = "stanbul"

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

Bu program altrdmzda yle bir kt alyoruz:


isim : Frat
soyisim : zgl
iletim sistemi: Ubuntu
ehir : stanbul

Bu program, belli deerleri kullanarak bir kayt oluturma ilemi gerekletiriyor. Mesela
yukardaki rnekte, Frat zgl adl ahsa ait isim, soyisim, iletim sistemi ve ehir bilgilerini
alarak, bu kii iin bir kayt oluturuyoruz.
Peki Frat zgl adl kiinin yansra, Mehmet ztaban adl baka bir kii iin de kayt
oluturmak istersek ne yapacaz?
Aklnza yle bir ey yazmak gelmi olabilir:
isim1 = "Frat"
soyisim1 = "zgl"
isis1 = "Ubuntu"
ehir1 = "stanbul"

print("isim : ", isim1)


print("soyisim : ", soyisim1)
print("iletim sistemi: ", isis1)
print("ehir : ", ehir1)

516 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

print("-"*30)

isim2 = "Mehmet"
soyisim2 = "ztaban"
isis2 = "Debian"
ehir2 = "Ankara"

print("isim : ", isim2)


print("soyisim : ", soyisim2)
print("iletim sistemi: ", isis2)
print("ehir : ", ehir2)

print("-"*30)

Programa her yeni kayt ekleniinde, her yeni kii iin benzer satrlar tekrar tekrar
yazabilirsiniz. Peki ama bu yntem sizce de ok skc deil mi? stelik bir o kadar da hataya
ak bir yntem. Muhtemelen ilk kayd ekledikten sonra, ikinci kayd eklerken birinci kayttaki
bilgileri kopyalayp, bu kopya zerinden ikinci kayd oluturuyorsunuz. Hatta muhtemelen
kopyalayp yaptrdktan sonra yeni kayd dzenlerken baz hatalar da yapyor ve dzgn
alan bir program elde edebilmek iin o hatalar dzeltmekle de urayorsunuz.
Btn bu ileri kolaylatracak bir zm olsa ve bizi ayn eyleri tekrar tekrar yazmaktan
kurtarsa sizce de ok gzel olmaz myd? Mesela tpk print() fonksiyonu gibi,
kayt_olutur() adl bir fonksiyon olsa, biz sadece gerekli bilgileri bu fonksiyonun
parantezleri iine parametre olarak yazsak ve bu fonksiyon bize istediimiz bilgileri ieren
bir kayt olutursa ne ho olurdu, deil mi? Yani rnein bahsettiimiz bu hayali
kayt_olutur() fonksiyonunu u ekilde kullanabilseydik...

kayt_olutur("Mehmet", "ztaban", "Debian", "Ankara")

... ve bu komut bize u kty verebilseydi...


------------------------------
isim : Mehmet
soyisim : ztaban
iletim sistemi: Debian
ehir : Ankara
------------------------------

... ne kadar gzel olurdu, deil mi?


te byle bir ey Pythonda mmkndr. Nasl Python gelitiricileri print(), input()
ve benzeri fonksiyonlar tanmlayp, karmak ilemleri tek admda yapabilmemiz iin bize
sunmu ve bylece bizi her defasnda tekerlei yeniden icat etme klfetinden kurtarmsa,
biz de kendi fonksiyonlarmz tanmlayarak, kendimizi ayn ilemleri tekrar tekrar yapma
zahmetinden kurtarabiliriz.
Gelin imdi bu ii nasl yapabileceimizi tartalm.

34.2 Fonksiyon Tanmlamak ve armak

Bir nceki blmde, kayt_olutur() adl hayali bir fonksiyondan sz etmitik. Tasarmza
gre bu fonksiyon u ekilde kullanlacak:

34.2. Fonksiyon Tanmlamak ve armak 517


Python 3 iin Trke Klavuz, Srm 3

kayt_olutur("Ahmet", "Gr", "Pardus", "zmir")

Bu komutu verdiimizde ise yle bir kt almay planlyoruz:


------------------------------
isim : Ahmet
soyisim : Gr
iletim sistemi: Pardus
ehir : zmir
------------------------------

Dediimiz gibi, byle bir ey yapmak Pythonla mmkndr. Ancak tabii ki kayt_olutur()
adl byle bir fonksiyonu kullanabilmenin belli n koullar var. Nasl say adl bir deikeni
kullanabilmek iin ncelikle bu ada sahip bir deiken tanmlam olmamz gerekiyorsa,
ayn ekilde kayt_olutur() adl bir fonksiyonu kullanabilmek iin de ncelikle bu ada
sahip bir fonksiyonu tanmlam olmamz gerekiyor. Zira mesela input() ve print() gibi
fonksiyonlar kullanabiliyor olmamz, Python gelitiricilerinin bu fonksiyonlar tanmlayp dilin
iine gmm olmalar sayesindedir.
te biz de kayt_olutur() adl fonksiyonu kullanabilmek iin bu ada sahip fonksiyonu
aadaki ekilde tanmlamalyz:
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

print("-"*30)

lk bakta bu kodlar size hibir ey ifade etmemi olabilir. Ama hi endie etmeyin. Biz
birazdan bu satrlarn ne anlama geldiini btn ayrntlaryla anlatacaz. Siz imdilik
anlamadnz ksmlar grmezden gelip okumaya devam edin.
Yukardaki kodlar yardmyla fonksiyonumuzu tanmlam olduk. Artk elimizde, tpk print()
veya input() gibi, kayt_olutur() adl ev yapm bir fonksiyon var. Dolaysyla bu
yeni fonksiyonumuzu, daha nce rendiimiz fonksiyonlar nasl kullanyorsak ayn ekilde
kullanabiliriz. Yani aadaki gibi komutlar yazabiliriz:

kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")


kayt_olutur("Mehmet", "ztaban", "Debian", "Ankara")

Yalnz fonksiyonumuzu tanmlayp bitirdikten sonra, bu fonksiyonu kullanrken, kodlarmzn


hizalamasna dikkat ediyoruz. Fonksiyonu kullanmak iin yazdmz kodlar def ifadesinin
hizasna getiriyoruz. Yani:
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

print("-"*30)

518 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")


kayt_olutur("Mehmet", "ztaban", "Debian", "Ankara")

Yukardaki yapy kullanarak, istediiniz sayda kayt oluturabilirsiniz. Mesela:


kayt_olutur("lkay", "Kaya", "Mint", "Adana")
kayt_olutur("Seda", "Kara", "SuSe", "Erzurum")

Grdnz gibi, yukardaki yntem sayesinde kodlarmzdaki tekrar eden ksmlar ortadan
kalkt. Yukardaki fonksiyonun bize nasl bir kolaylk saladn daha net grebilmek iin,
fonksiyon kullanarak sadece u 11 satrla elde ettiimiz kty, fonksiyon kullanmadan elde
etmeyi deneyebilirsiniz:
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

print("-"*30)

kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")


kayt_olutur("Mehmet", "ztaban", "Debian", "Ankara")
kayt_olutur("lkay", "Kaya", "Mint", "Adana")
kayt_olutur("Seda", "Kara", "SuSe", "Erzurum")

Bu anlattklarmz size ok karmak gelmi olabilir. Ama endie etmenize hi gerek yok. Biraz
sonra, yukarda yazdmz kodlarn hepsini didik didik edeceiz. Ama ncelikle yukardaki
kod parasn yapsal olarak bir incelemenizi istiyorum. Fonksiyonu tanmladmz aadaki
kod parasna yle bir baktnzda neler gryorsunuz?
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

print("-"*30)

kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")

Bu kodlar incelediinizde u noktalar dikkatinizi ekiyor olmal:


1. Kodlar def adl bir ifade ile balam.
2. Bunun ardndan kayt_olutur ifadesini gryoruz.
3. Bu ifadeyi, iinde birtakm kelimeler barndran bir parantez ifti izliyor.
4. Parantezin iinde, isim, soyisim, isis ve ehir adl deerler var.
5. def ile balayan bu satr iki nokta st ste iareti ile son buluyor.
6. lk satrn ardndan gelen ksm ilk satra gre girintili bir ekilde yazlm.

34.2. Fonksiyon Tanmlamak ve armak 519


Python 3 iin Trke Klavuz, Srm 3

7. kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul") satr nceki satrlara


gre girintisiz yazlm.
Eer bu kodlara dikkatlice bakacak olursanz, aslnda bu kodlarn topu topu iki paradan
olutuunu greceksiniz. sterseniz yukardaki yapy biraz sadeletirelim:
def kayt_olutur(parametre1, parametre2, parametre3, parametre4):
(...)

kayt_olutur(parametre1, parametre2, parametre3, parametre4)

Bu yapnn ilk paras udur:


def kayt_olutur(parametre1, parametre2, parametre3, parametre4):
(...)

kinci paras ise u:


kayt_olutur(parametre1, parametre2, parametre3, parametre4)

Teknik olarak sylemek gerekirse, ilk paraya fonksiyon tanm (function denition ), ikinci
paraya ise fonksiyon ars (function call ) ad verilir. Dolaysyla bir fonksiyonun yaam
dngs iki aamadan oluur. Buna gre bir fonksiyon nce tanmlanr;
def kayt_olutur(parametre1, parametre2, parametre3, parametre4):
(...)

...sonra da arlr;
kayt_olutur(parametre1, parametre2, parametre3, parametre4)

Aslnda biz imdiye kadar grdmz print(), type(), open() vb. fonksiyonlarda bu
fonksiyon ars ksmyla zaten tanmtk. Zira u komut tam anlamyla bir fonksiyon
arsdr (yani bir fonksiyon arma ilemidir):

print("Frat", "zgl", "Adana", 32)

Grdnz gibi, yukardaki komutun yap olarak u komuttan hibir fark yok:

kayt_olutur("Frat", "zgl", "Ubuntu", "stanbul")

Bu iki fonksiyon arasndaki tek fark, print() fonksiyonunu Python gelitiricilerinin;


kayt_olutur() fonksiyonunu ise sizin tanmlam olmanzdr.
Elbette bu iki fonksiyon yap olarak birbirinin ayn olsa da, ilev olarak birbirinden farkldr.
print() fonksiyonunun grevi kendisine parametre olarak verilen deerleri ekrana kt
vermek iken, kayt_olutur() fonksiyonunun grevi kendisine parametre olarak verilen
deerleri kullanarak bir kayt oluturmaktr.
Bu derse gelinceye kadar rendiimiz print(), type() ve open() gibi fonksiyonlara teknik
olarak gml fonksiyonlar (builtin functions ) ad verilir. Bu fonksiyonlara bu adn verilmi
olmasnn sebebi, bu fonksiyonlarn gerekten de Python programlama dili iine gml
bir vaziyette olmalardr. Dikkat ederseniz kendi yazdmz fonksiyonlar kullanabilmek iin
ncelikle fonksiyonu tanmlamamz gerekiyor. Gml fonksiyonlar ise Python gelitiricileri
tarafndan halihazrda tanmlanm olduu iin bunlar biz herhangi bir tanmlama ilemi
yapmaya gerek kalmadan dorudan arabiliyoruz.

520 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Bylece bir fonksiyonun yap olarak neye benzediini stnkr de olsa incelemi olduk.
Buraya kadar anlatlan ksmda baz noktalar anlamakta zorlanm olabilirsiniz. Eer yleyse
hi endielenmeyin. Bu gayet doal.
Gelin isterseniz imdi yukarda anlattklarmzn iini doldurmaya alalm.

34.3 Fonksiyonlarn Yaps

sterseniz biraz da fonksiyonlarn yapsndan sz edelim. Bylelikle ne ile kar karya


olduumuzu anlamak zihninizde biraz daha kolaylar.
Dedik ki, bir fonksiyonun ilk parasna fonksiyon tanm (function denition ) ad verilir. Bir
fonksiyonu tanmlamak iin def adl bir paracktan yararlanyoruz. rnein:
def bir_fonksiyon():
(...)

Burada def parac, tanmladmz eyin bir fonksiyon olduunu gsteriyor. bir_fonksiyon
ifadesi ise tanmladmz bu fonksiyonun addr. Fonksiyonu tanmladktan sonra, arrken
bu ad kullanacaz.
def bir_fonksiyon(): ifadesinin sonundaki iki nokta iaretinden de tahmin edebileceiniz
gibi, sonraki satra yazacamz kodlar girintili olacak. Yani mesela:
def selamla():
print("Elveda Zalim Dnya!")

Yukarda selamla() adl bir fonksiyon tanmlam olduk. Bu fonksiyonun grevi ekrana Elveda
Zalim Dnya! kts vermektir.
Bu noktada yle bir soru akla geliyor: Acaba fonksiyon gvdesindeki ksm iin ne kadarlk
bir girinti oluturacaz?
Girintilemeye ilikin olarak nceki derslerde bahsettiimiz btn kurallar burada da
geerlidir. Fonksiyon gvdesine, def ifadesinden itibaren 4 (drt) bolukluk bir girinti
veriyoruz. def ifadesinden itibaren girintili olarak yazdmz ksmn tamam o fonksiyonun
gvdesini oluturur ve btnyle o fonksiyona aittir.
Bu kodlarla yaptmz ey bir fonksiyon tanmlama ilemidir. Eer bu kodlar bir dosyaya
kaydedip altrrsak herhangi bir kt almayz. nk henz fonksiyonumuzu armadk.
Bu durumu print(), input() ve benzeri gml fonksiyonlara benzetebilirsiniz. Tpk
yukarda bizim yaptmz gibi, gml fonksiyonlar da Python gelitiricileri tarafndan bir
yerlerde tanmlanm vaziyette dururlar, ama biz bu fonksiyonlar yazdmz programlarda
arana kadar bu fonksiyonlar almaz.
Daha nce de dediimiz gibi, bir fonksiyonun yaam dngs iki aamadan oluur: Fonksiyon
tanm ve fonksiyon ars. Yukarda bu dngnn sadece fonksiyon tanm aamas
mevcut. Unutmayn, bir fonksiyon arlmadan asla almaz. Bir fonksiyonun alabilmesi
iin o fonksiyonun tanmlandktan sonra arlmas gerekir. rnein input() fonksiyonu
Pythonn derinliklerinde bir yerlerde tanmlanm vaziyette durur. Bu fonksiyon, biz onu
arana kadar, bulunduu yerde sessizce bekler. Ayn ekilde selamla() adl fonksiyon
da programmz iinde tanmlanm vaziyette, bizim onu aracamz an bekliyor. Bu
sylediklerimizi destekleyecek aklayc bilgileri biraz sonra vereceiz. Biz imdilik fonksiyon
tanm ksmn incelemeye devam edelim.

34.3. Fonksiyonlarn Yaps 521


Python 3 iin Trke Klavuz, Srm 3

Bu arada yukardaki fonksiyon tanmnn yapsna ok dikkat edin. ki nokta st ste


iaretinden sonraki satrda girintili olarak yazlan btn kodlar (yani fonksiyonun gvde ksm)
fonksiyonun bir parasdr. Girintinin dna kld anda fonksiyon tanmlama ilemi de sona
erer.
rnein:
def selamla():
print("Elveda Zalim Dnya!")

selamla()

te burada fonksiyonumuzu arm olduk. Dikkat edin! Dediim gibi, iki nokta st ste
iaretinden sonraki satrda girintili olarak yazlan btn kodlar fonksiyona aittir. selamla()
satr ise fonksiyon tanmnn dnda yer alr. Bu satrla birlikte girintinin dna kld iin
artk fonksiyon tanmlama safhas sona ermi oldu.
Biz yukardaki rnekte, selamla() adl fonksiyonu tanmlar tanmlamaz armay tercih ettik.
Ama elbette siz bir fonksiyonu tanmlar tanmlamaz armak zorunda deilsiniz. Yazdnz
bir program iinde fonksiyonlarnz tanmladktan sonra, ihtiyacnza bal olarak, programn
herhangi baka bir yerinde fonksiyonlarnz arabilirsiniz.
Fonksiyonlarla ilgili sylediklerimizi toparlayacak olursak yle bir bilgi listesi ortaya
karabiliriz:
1. Pythonda kabaca iki tip fonksiyon bulunur. Bunlardan biri gml fonksiyonlar (builtin
functions ), teki ise zel fonksiyonlardr (custom functions ). Burada zel ifadesi,
kullancnn ihtiyalarna gre kullanc tarafndan zel olarak retilmi anlamna gelir.
2. Gml fonksiyonlar; Python gelitiricileri tarafndan tanmlanp dilin iine gmlm
olan print(), open(), type(), str(), int() vb. fonksiyonlardr. Bu fonksiyonlar
halihazrda tanmlanp hizmetimize sunulduu iin bunlar biz herhangi bir tanmlama
ilemi yapmadan dorudan kullanabiliriz.
3. zel fonksiyonlar ise, gml fonksiyonlarn aksine, Python gelitiricileri tarafndan
deil, bizim tarafmzdan tanmlanmtr. Bu fonksiyonlar dilin bir paras olmadndan,
bu fonksiyonlar kullanabilmek iin bunlar ncelikle tanmlamamz gerekir.
4. Pythonda bir fonksiyonun yaam dngs iki aamadan oluur: Tanmlanma ve
arlma.
5. Bir fonksiyonun arlabilmesi (yani kullanlabilmesi) iin mutlaka birisi tarafndan
tanmlanm olmas gerekir.
6. Fonksiyonu tanmlayan kii Python gelitiricileri olabilecei gibi, siz de olabilirsiniz. Ama
neticede ortada bir fonksiyon varsa, bir yerlerde o fonksiyonun tanm da vardr.
7. Fonksiyon tanmlamak iin def adl bir ifadeden yararlanyoruz. Bu ifadeden sonra,
tanmlayacamz fonksiyonun adn belirleyip iki nokta st ste iareti koyuyoruz. ki
nokta st ste iaretinden sonra gelen satrlar girintili olarak yazlyor. Daha nce
rendiimiz btn girintileme kurallar burada da geerlidir.
8. Fonksiyonun adn belirleyip iki nokta st ste koyduktan sonra, alt satrda girintili
olarak yazdmz btn kodlar fonksiyonun gvdesini oluturur. Doal olarak, bir
fonksiyonun gvdesindeki btn kodlar o fonksiyona aittir. Girintinin dna kld
anda fonksiyon tanm da sona erer.

522 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Fonksiyonlarla ilgili rendiklerimizi toparladmza gre, gelin isterseniz fonksiyonlarla ilgili


bir rnek yaparak, bu yapy daha iyi anlamaya alalm:
def sistem_bilgisi_gster():
import sys
print("\nSistemde kurulu Python'n;")
print("\tana srm numaras:", sys.version_info.major)
print("\talt srm numaras:", sys.version_info.minor)
print("\tminik srm numaras:", sys.version_info.micro)

print("\nKullanlan iletim sisteminin;")


print("\tad:", sys.platform)

Burada sistem_bilgisi_gster() adl bir fonksiyon tanmladk. Bu fonksiyonun grevi,


kullancnn sistemindeki Python srm ve iletim sistemine dair birtakm bilgiler vermektir.
Bu arada, bu kodlarda, daha nceki derslerimizde rendiimiz sys modlnden ve bu modl
iindeki deikenlerden yararlandmz gryorsunuz. Bu kodlarda sys modlnn iindeki
u aralar kullandk:
1. version_info.major : Pythonn ana srm numaras (rn. 3)
2. version_info.minor : Pythonn alt srm numaras (rn. 4)
3. version_info.micro : Pythonn minik srm numaras (rn. 0)
4. platform : Kullanlan iletim sisteminin ad (rn. win32 veya linux2)
Yukarda tanmladmz fonksiyonu nasl aracamz biliyorsunuz:
sistem_bilgisi_gster()

Bu fonksiyon tanm ve arsn eksiksiz bir program iinde gsterelim:


def sistem_bilgisi_gster():
import sys
print("\nSistemde kurulu Python'n;")
print("\tana srm numaras:", sys.version_info.major)
print("\talt srm numaras:", sys.version_info.minor)
print("\tminik srm numaras:", sys.version_info.micro)

print("\nKullanlan iletim sisteminin;")


print("\tad:", sys.platform)

sistem_bilgisi_gster()

Bu kodlar bir dosyaya kaydedip altrdmzda una benzer bir kt alacaz:


Sistemde kurulu Python'n;
ana srm numaras: 3
alt srm numaras: 3
minik srm numaras: 0

Kullanlan iletim sisteminin;


ad: linux

Demek ki bu kodlarn altrld sistem Pythonn 3.3.0 srmnn kurulu olduu bir
GNU/Linux iletim sistemi imi...

34.3. Fonksiyonlarn Yaps 523


Python 3 iin Trke Klavuz, Srm 3

34.4 Fonksiyonlar Ne e Yarar?

imdiye kadar sylediklerimizden ve verdiimiz rneklerden fonksiyonlarn ne ie yaradn


anlam olmalsnz. Ama biz yine de fonksiyonlarn faydas zerine birka sz daha
syleyelim. Bylece fonksiyonlarn ne ie yarad konusunda aklmzda hibir phe kalmaz...
sterseniz bir rnek zerinden ilerleyelim.
Diyelim ki, bir saynn karesini bulan bir program yazmak istiyoruz. imdiye kadarki
bilgilerimizi kullanarak yle bir ey yazabiliriz:
say = 12
kt = "{} saysnn karesi {} saysdr"
print(kt.format(say, say**2))

Yukardaki program altrdmzda yle bir kt elde edeceiz:


12 saysnn karesi 144 saysdr

Gayet gzel. imdi yle bir durum hayal edin: Diyelim ki byk bir program iinde, farkl
farkl yerlerde yukardaki ilemi tekrar tekrar yapmak istiyorsunuz. Byle bir durumda yle
bir ey yazmanz gerekebilir:
say = 12
kt = "{} saysnn karesi {} saysdr"
print(kt.format(say, say**2))

####programla ilgili baka kodlar###

say = 15
print(kt.format(say, say**2))

###programla ilgili baka kodlar###

say = 29
print(kt.format(say, say**2))

Buradaki sorun, ayn eyleri tekrar tekrar yazmak zorunda kalmamzdr. Bu kk rnekte pek
belli olmuyor olabilir, ama zellikle byk programlarda ayn kodlarn program iinde srekli
olarak tekrarlanmas pek ok probleme yol aar. rnein kodlarda bir deiiklik yapmak
istediinizde, tekrarlanan ksmlar bulup hepsinin zerinde tek tek deiiklik yapmanz
gerekir. Mesela kt adl deikenin ieriini deitirmek isterseniz, yaptnz deiiklik
programnzn pek ok ksmn etkileyebilir. rnein, kt deikenini u ekle getirdiinizi
dnn:
kt = "{} saysnn karesi {}, karekk {} saysdr"

Byle bir durumda, program iinde geen btn print(kt.format(say, say**2))


satrlarn bulup, nc {} iaretine ait ilemi parantez iine eklemeniz gerekir. Tahmin
edebileceiniz gibi, son derece skc, yorucu ve stelik hata yapmaya ak bir ilemdir bu.
te bu tr problemlere kar fonksiyonlar ok iyi bir zmdr.
Yukarda bahsettiimiz kare bulma ilemi iin u ekilde basit bir fonksiyon tanmlayabiliriz:
def kare_bul():
say = 12

524 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

kt = "{} saysnn karesi {} saysdr"


print(kt.format(say, say**2))

Bu fonksiyonu tanmladk. imdi de fonksiyonumuzu aralm:


kare_bul()

Kodlarmz tam olarak yle grnyor:


def kare_bul():
say = 12
kt = "{} saysnn karesi {} saysdr"
print(kt.format(say, say**2))

kare_bul()

Burada fonksiyonumuz def kare_bul(): satryla balyor, print(kt.format(say,


say**2)) satryla bitiyor. Daha sonra gelen kare_bul() kodu, girintinin dnda yer ald
iin fonksiyon tanmna ait deildir.
Bu kodlar bir dosyaya kaydedip altrdmzda alacamz kt u olacaktr:
12 saysnn karesi 144 saysdr

kare_bul() adl fonksiyonu bir kez tanmladktan sonra bu fonksiyonu programnz iinde
gereken her yerde arabilirsiniz:
kare_bul()

####programla ilgili baka kodlar###

kare_bul()

###programla ilgili baka kodlar###

kare_bul()

Grdnz gibi kare_bul() adl bu fonksiyon bizi pek ok zahmetten kurtaryor. Ancak
bu fonksiyonun bir sorunu var. Bu fonksiyon ekrana yalnzca 12 saysnn karesi 144
saysdr kts verebiliyor. Buradaki problem, fonksiyonun sadece 12 says zerinde ilem
yapabilmesi. yle bir dnnce, bu ktnn ne kadar anlamsz olduunu, aslnda yukardaki
fonksiyonun tamamen gereksiz bir i yaptn rahatlkla grebiliyoruz. Fonksiyonumuzun ad
kare_bul. Ama dediimiz gibi, fonksiyonumuz sadece 12 saysnn karesini syleyebiliyor.
Halbuki mantk olarak fonksiyonumuzun, btn saylarn karesini syleyebilmesini beklerdik.

Not: Bu arada, grdnz gibi, yukardaki fonksiyon parametresiz bir fonksiyondur.


Dolaysyla bu fonksiyonu arrken parantez iinde herhangi bir deer belirtmiyoruz.

Fonksiyonumuzun gerek anlamda ilevli bir hale gelebilmesi iin sadece tek bir sayy deil,
btn saylar inceleyebiliyor olmas gerek. te fonksiyonumuza bu yetenei parametreler
araclyla kazandrabiliriz.
Dikkatlice bakn:
def kare_bul(say):
kt = "{} saysnn karesi {} saysdr"
print(kt.format(say, say**2))

34.4. Fonksiyonlar Ne e Yarar? 525


Python 3 iin Trke Klavuz, Srm 3

Fonksiyona parametre olarak nasl bir isim verdiinizin nemi yoktur. Parantez iine
parametre olarak istediiniz kelimeyi yazabilirsiniz. nemli olan, parantez iinde fonksiyonun
ka parametre alacan gsteren bir iaret olmasdr. Mesela yukardaki fonksiyonu yle de
tanmlayabilirdik:
def kare_bul(i):
kt = "{} saysnn karesi {} saysdr"
print(kt.format(i, i**2))

...veya yle:
def kare_bul(osman):
kt = "{} saysnn karesi {} saysdr"
print(kt.format(osman, osman**2))

Elbette parametre ad olarak aklda kalc ve daha mantkl bir seim yapmak ilerinizi
kolaylatracaktr...
imdi de yukardaki fonksiyonu aralm:
kare_bul(9)

Bu fonksiyonu altrdmzda u kty alrz:


9 saysnn karesi 81 saysdr

Bu fonksiyona parametre olarak hangi sayy verirseniz o saynn karesi hesaplanacaktr.


rnein:
kare_bul(15)
kare_bul(25555)

Yine bu fonksiyonu programnz iinde gereken her yerde arabilirsiniz:


kare_bul(17)

####programla ilgili baka kodlar###

kare_bul(21)

###programla ilgili baka kodlar###

kare_bul(54354)

Fonksiyonu oluturan kodlarda herhangi bir deiiklik yapmak istediinizde sadece fonksiyon
tanmnn gvdesini deitirmeniz yeterli olacaktr. rnein:
def kare_bul(say):
kt = "{} saysnn karesi {}, karekk ise {} saysdr"
print(kt.format(say, say**2, say**0.5))

Bu sayede sadece fonksiyon gvdesinde deiiklik yaparak, programn baka ksmlarn hi


etkilemeden yolumuza devam edebiliyoruz.
Buraya kadar anlattklarmz, fonksiyonlarn ne ie yarad ve bir program yazarken neden
fonksiyonlara ihtiya duyacamz konusunda size bir kir vermi olmal. Eer hala aklnzda
fonksiyonlarn faydas konusunda bir phe kaldysa, fonksiyonlarn faydasn anlamanz
salayabilmek iin size yle bir soru sormama izin verin: Acaba istihza kelimesinin ka
karakterden olutuunu nasl buluruz?

526 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Elbette len() fonksiyonunu kullanarak! dediinizi duyar gibiyim. Gerekten de Pythonda bir
karakter dizisinin uzunluunu bulmann en iyi yolu len() fonksiyonunu kullanmaktr:
>>> len("istihza")

Peki ya Pythonda len() diye bir fonksiyon olmasayd ne yapacaktnz? Byle bir durumda,
karakter dizilerinin uzunluunu lmek iin sizin bir yntem icat etmeniz gerekecekti. Mesela
istihza kelimesinin ka karakterden olutuunu bulmak iin yle bir kod yazacaktnz:
c = 0
for s in "istihza":
c += 1
print(c)

Burada nce c adl bir deiken tanmlayp, bu deikenin deerini 0 yaptk. Bu deiken,
uzunluunu sorgulamak istediimiz kelimenin ka karakterden olutuu bilgisini saklayacak.
Ardndan bir for dngs tanmlyoruz. Bu dngde, istihza kelimesindeki her bir karakter
iin c deikeninin deerini 1 say artryoruz. Bylece dng sonunda c deikeni istihza
kelimesi iinde ka karakter olduu bilgisini tutmu oluyor.
Son olarak da c deikeninin nihai deerini ekrana yazdryoruz.
Bu kodlar altrdnzda 7 cevab alacaksnz. Demek ki istihza kelimesinde 7 karakter
varm. Peki istihza kelimesi yerine mesela Afyonkarahisar kelimesi iinde ka karakter
olduunu hesaplamak isterseniz ne yapacaksnz? Elbette yukardaki kodlar tekrar yazp,
istihza kelimesini Afyonkarahisar kelimesi ile deitireceksiniz. Bylece bu kelimenin ka
karakterden olutuunu bulmu olacaksnz. Sorgulamak istediiniz her kelime iin ayn
eyleri yapabilirsiniz...
Ne kadar verimsiz bir yntem, deil mi?
Halbuki hi bu tr eylerle uramaya gerek yok. Eer Python bize len() fonksiyonu gibi bir
fonksiyon vermemi olsayd, kendi len() fonksiyonumuzu icat edebilirdik. Dikkatlice bakn:
def uzunluk(e):
c = 0
for s in e:
c += 1
print(c)

Bylece ad uzunluk olan bir fonksiyon tanmlam olduk. Artk bir enin uzunluunu
hesaplamak istediimizde, btn o kodlar her defasnda tekrar tekrar yazmak yerine sadece
uzunluk() fonksiyonunu kullanabiliriz:
uzunluk("istihza")
uzunluk("Afyonkarahisar")
uzunluk("Tarm ve Kyileri Bakanl")

stelik bu fonksiyon yalnzca karakter dizilerinin deil teki veri tiplerinin de uzunluunu
hesaplayabilir:
liste = ["ahmet", "mehmet", "veli"]
uzunluk(liste)

Verdiimiz bu rnek bize hem gml fonksiyonlarn faydasn, hem de genel olarak
fonksiyonlarn ne ie yaradn aka gsteriyor. Buna gre, len() benzeri gml

34.4. Fonksiyonlar Ne e Yarar? 527


Python 3 iin Trke Klavuz, Srm 3

fonksiyonlar tekerlei yeniden icat etme derdinden kurtaryor bizi. rnein Python
gelitiricilerinin len() gibi bir fonksiyon tanmlam olmalar sayesinde, bir karakter dizisinin
uzunluunu hesaplamak iin kendi kendimize yntem icat etmek zorunda kalmyoruz. Ama
eer kendi yntemimizi icat etmemiz gerekirse, istediimiz ilevi yerine getiren bir fonksiyon
tanmlamamz da mmkn.
Bylece temel olarak fonksiyonlarn ne ie yaradn, neye benzediini, nasl tanmlandn
ve nasl arldn incelemi olduk. imdi fonksiyonlarn biraz daha derinine dalmaya
balayabiliriz.

34.5 Parametreler ve Argmanlar

imdiye kadar yaptmz rnekler sayesinde aslnda parametrelerin neye benzediini ve ne


ie yaradn renmitik. Bu blmde ise sizi argman adl bir kavramla tantrp, argman
ile parametre arasndaki benzerlik ve farkllklar inceleyeceiz. Bunun yansra, parametre
kavramn da bu blmde daha derinlikli bir ekilde ele alacaz.
O halde hemen yola koyulalm.
Parametrenin ne olduunu biliyorsunuz. Bunlar fonksiyon tanmlarken parantez iinde
belirttiimiz, fonksiyon gvdesinde yaplan iin deiken elerini gsteren paralardr.
Mesela:
def kopyala(kaynak_dosya, hedef_dizin):
kt = "{} adl dosya {} adl dizin iine kopyaland!"
print(kt.format(kaynak_dosya, hedef_dizin))

Burada kopyala() adl bir fonksiyon tanmladk. Bu fonksiyon toplam iki adet parametre
alyor: kaynak_dosya ve hedef_dizin. Grdnz gibi, bu iki parametre gerekten
de fonksiyon gvdesinde yaplan iin deiken elerini gsteriyor. Bu fonksiyonun
retecei kt, fonksiyonu aran kiinin bu iki parametreye verecei deerlere bal olarak
ekillenecek.
Bildiiniz gibi, parametrelere ne ad verdiinizin hibir nemi yok. Elbette parametrenin
grevine uygun bir isim vermeniz fonksiyonunuzun okunaklln artracaktr. Ama tabii ki
bu fonksiyonu pekala u parametrelerle de tanmlayabilirdik:
def kopyala(a, b):
kt = "{} adl dosya {} adl dizin iine kopyaland!"
print(kt.format(a, b))

Burada nemli olan, parametre grevi grecek iki adet kelime bulmak. Bu kelimelerin ne
olduunun nemi yok. Ama tabii ki kaynak_dosya ve hedef_dizin adlar, a ve b adlarna
kyasla, fonksiyondaki parametrelerin yapt ii ok daha iyi tarif ediyor.
Parametre ad belirleme kurallar deiken ad belirleme kurallaryla ayndr. Dolaysyla bir
deiken ad belirlerken neye dikkat ediyorsak, parametre ad belirlerken de ayn eye dikkat
etmeliyiz.
Gelin imdi isterseniz tanmladnz bu fonksiyonu aralm:
kopyala("deneme.txt", "/home/istihza/Desktop")

Kodlarmz dosya iinde tam olarak yle grnyor:

528 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

def kopyala(kaynak_dosya, hedef_dizin):


kt = "{} adl dosya {} adl dizin iine kopyaland!"
print(kt.format(kaynak_dosya, hedef_dizin))

kopyala("deneme.txt", "/home/istihza/Desktop")

Bu kodlar bir dosyaya kaydedip altrdmzda yle bir kt alrz:


deneme.txt adl dosya /home/istihza/Desktop adl dizin iine kopyaland!

Grdnz gibi, deneme.txt ve /home/istihza/Desktop deerleri, kt adl karakter


dizisinde uygun yerlere yerletirildi ve ekrana kt olarak verildi. te burada grdnz
bu deneme.txt ve /home/istihza/Desktop deerlerine argman ad verilir. Yani bir
fonksiyonu tanmlarken belirlediimiz adlara parametre, ayn fonksiyonu arrken
belirlediimiz adlara ise argman deniyor. Dolaysyla fonksiyon tanmnda belirlediimiz
kaynak_dosya ve hedef_dizin adl deikenler birer parametre, fonksiyon arsnda bu
parametrelere karlk gelen deneme.txt ve /home/istihza/Desktop deerleri ise birer
argman oluyor.
Bylece parametre ve argman arasndaki fark renmi olduk. Ancak unu belirtmekte
yarar var: Bu iki kavram genellikle birbirinin yerine kullanlr. Yani bu iki kavram arasndaki,
yukarda akladmz farka pek kimse dikkat etmez. Dolaysyla pek ok yerde hem
parametre hem de argman iin ayn ifadenin kullanldn grebilirsiniz. zellikle Trkede
parametre kelimesi argman kelimesine kyasla daha bilinir ve yaygn olduu iin, ayrm
yaplmakszn hem fonksiyon arsndaki deerlere, hem de fonksiyon tanmndaki deerlere
parametre ad verilir.
Gelelim parametrelerin eitlerine...
Pythonda parametreler ilevlerine gre farkl kategorilere ayrlr. Gelin imdi bu kategorileri
tek tek inceleyelim.

34.5.1 Sral (veya simsiz) Parametreler

Pythonda yle bir fonksiyon tanmlayabileceimizi biliyoruz:


def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

print("-"*30)

Yukarda tanmladmz bu fonksiyonu u ekilde arabiliriz:

kayt_olutur("Ahmet", "z", "Debian", "Ankara")

Bu fonksiyonda, yazdmz parametrelerin sras byk nem tar. Mesela yukardaki


fonksiyonu yle ardmz dnn:

kayt_olutur("Debian", "Ankara", "z", "Ahmet")

34.5. Parametreler ve Argmanlar 529


Python 3 iin Trke Klavuz, Srm 3

Eer fonksiyon parametrelerini bu srayla kullanrsak aldmz kt hatal olacaktr:


------------------------------
isim : Debian
soyisim : Ankara
iletim sistemi: z
ehir : Ahmet
------------------------------

Grdnz gibi, isim, soyisim ve teki bilgiler birbirine karm. te Pythonda, verili sras
nem tayan bu tr parametrelere sral parametreler (veya isimsiz parametreler) ad verilir.

34.5.2 simli Parametreler

Bir nceki blmde verdiimiz u rnei yeniden ele alalm:


def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

print("-"*30)

Bu fonksiyonu arrken parametrelerin srasn doru vermenin, alacamz ktnn dzgn


olmas bakmndan byk nem tadn biliyoruz. Ancak zellikle parametre saysnn
ok olduu fonksiyonlarda parametre srasn aklda tutmak zor olabilir. Byle durumlarda
parametreleri isimleri ile birlikte kullanmay tercih edebiliriz:

kayt_olutur(soyisim="z", isim="Ahmet", isis="Debian", ehir= "Ankara")

Bylece fonksiyon parametrelerini istediimiz sra ile kullanabiliriz. Ancak burada dikkat
etmemiz gereken baz noktalar var. Pythonda isimli bir parametrenin ardndan sral bir
parametre gelemez. Yani u kullanm yanltr:

kayt_olutur(soyisim="z", isim="Ahmet", "Debian", "Ankara")

Bu kodlar bize u hatay verir:


File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg

Bu yzden, eer isimli parametreler kullanacaksak, isimli parametrelerden sonra sral


parametre kullanmamaya dikkat ediyoruz.

34.5.3 Varsaylan Deerli Parametreler

imdiye kadar karlatmz fonksiyonlarda bir ey dikkatinizi ekmi olmal. Mesela print()
fonksiyonunu ele alalm. Bildiiniz gibi, bu fonksiyonu en basit ekilde yle kullanyoruz:

print("Frat", "zgl")

530 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Evet, print() fonksiyonunu bu ekilde kullanabiliyoruz, ancak bildiiniz gibi, aslnda bu


fonksiyonun baz zel parametreleri de var. Daha nceki derslerimizden hatrlayacanz gibi,
biz yukardaki komutu verdiimizde aslnda Python bunu u ekilde alglyor:
print("Frat", "zgl", sep=" ", end="\n", file=sys.stdout, flush=False)

Yani biz grmesek de aslnda her print() ars sep, end, le ve ush parametrelerini
de ieriyor. Biz bu zel parametreleri kullanmasak da, yazdmz kod dzgn bir ekilde
alr. Bunun nedeni, sep, end, le ve ush parametrelerinin ntanml olarak birtakm
deerlere sahip olmasdr. Yani biz bu parametrelere kendimiz bir deer atamazsak Python
bu parametrelere kendi belirledii baz ntanml deerleri atayacaktr. Dolaysyla, eer biz
baka bir deer yazmazsak, sep parametresi deerine, end parametresi n deerine, le
parametresi sys.stdout deerine, ush parametresi ise False deerine sahip olacaktr. te
bu tr parametrelere Pythonda varsaylan deerli parametreler ad verilir. Peki biz kendimiz
varsaylan deerli parametreler ieren fonksiyonlar nasl tanmlayabiliriz?
u rnee dikkatlice bakn:
def kur(kurulum_dizini="/usr/bin/"):
print("Program {} dizinine kuruldu!".format(kurulum_dizini))

Burada kur() adl bir fonksiyon tanmladk. Bu fonksiyonun grevi, yazdmz bir
program, kullancnn bilgisayarndaki bir dizine kurmak ve programn hangi dizine kurulduu
konusunda kullancy bilgilendirmek. Bu fonksiyonu u ekilde arabiliriz:
kur()

Eer kur() fonksiyonunu byle arrsak bize u kty verecektir:


Program /usr/bin/ dizinine kuruldu!

Grdnz gibi, kur() fonksiyonunun kurulum_dizini adl bir parametresi var. Biz
fonksiyonu tanmlarken, bu parametreye bir varsaylan deer atadk (/usr/bin/ ). Bylece
kur() fonksiyonu parametresiz olarak arldnda bu varsaylan deer devreye girdi.
Eer biz bu deeri deitirmek istersek, mesela programmzn C:\Users\rat dizinine
kurulmasn istersek, kur() fonksiyonunu yle armalyz:
kur("C:\\Users\\firat")

kur() fonksiyonunu yukardaki gibi ardmzda Python bize yle bir kt verir:
Program C:\Users\firat dizinine kuruldu!

Bu rnek size, varsaylan deerli parametreler belirlemenin ne kadar faydal olabileceini


gstermi olmal. Mesela bir program yazdnz dnn. Programnz indiren
kullanclar, yukardaki gibi bir varsaylan deerli parametre belirlemi olmanz sayesinde
programnz nereye kuracaklarn belirlemek zorunda kalmadan bir sonraki kurulum admna
geebiliyorlar...
Elbette eer isterseniz kullanclarnz bir kurulum dizini belirlemeye zorlamak da
isteyebilirsiniz. Bunun iin yine varsaylan deerli parametrelerden yararlanabilirsiniz:
def kur(kurulum_dizini=''):
if not kurulum_dizini:
print("Ltfen program hangi dizine kurmak istediinizi belirtin!")
else:
print("Program {} dizinine kuruldu!".format(kurulum_dizini))

34.5. Parametreler ve Argmanlar 531


Python 3 iin Trke Klavuz, Srm 3

Bu defa kurulum_dizini parametresinin varsaylan deerini bo bir karakter dizisi olarak


belirledik. Eer bu parametrenin deeri bo bir karakter dizisi olursa, kullanc herhangi bir
kurulum dizini belirtmemi demektir. Eer kullanc herhangi bir kurulum dizini belirtmezse
kurulum_dizini parametresinin bool deeri False olacaktr. Bu zellii dikkate alarak
fonksiyon gvdesinde u kodlar kullanabiliyoruz:
if not kurulum_dizini:
print("Ltfen program hangi dizine kurmak istediinizi belirtin!")

Bylece, kurulum_dizini parametresinin bool deeri False olursa kullanclarmza yle bir
uyar gsteriyoruz:
"Ltfen program hangi dizine kurmak istediinizi belirtin!"

Dolaysyla kuruluma balayabilmek iin kur() fonksiyonunun yle altrlmasn zorunlu


tutuyoruz:
kur("C:\\Users\\istihza")

Buna benzer durumlarla pek ok kez karlam olmalsnz. zellikle programlarn


kurulmasn salayan setup betiklerinde her aama iin bir varsaylan deer belirlenip,
kullancnn sadece Next tularna basarak salkl bir kurulum yapmas salanabiliyor. Eer
kullanc varsaylan deerlerin dnda birtakm deerler belirlemek isterse, yukarda rneini
verdiimiz yap kullancya byle bir zgrlk de salyor.

34.5.4 Rastgele Sayda simsiz Parametre Belirleme

imdiye kadar rendiimiz pek ok fonksiyonun toplam ka parametre alabilecei bellidir.


rnein input() fonksiyonu yalnzca tek bir parametre alabilir. Eer bu fonksiyona birden
fazla parametre verirsek Python bize bir hata mesaj gsterecektir. Ayn ekilde mesela pow()
fonksiyonunun da ka parametre alabilecei bellidir. Ama rnein print() fonksiyonuna
verebileceimiz parametre says (teknik olarak 256 ile snrl olsa da) pratik olarak neredeyse
snrszdr.
Peki acaba biz kendimiz, snrsz parametre alabilen fonksiyonlar retebilir miyiz?
Bu sorunun cevab evet olacaktr. imdi u rnee dikkatlice bakn:
def fonksiyon(*parametreler):
print(parametreler)

fonksiyon(1, 2, 3, 4, 5)

Bu kodlar altrdmzda u kty alacaz:


(1, 2, 3, 4, 5)

Grdnz gibi, fonksiyon tanm iinde kullandmz * iareti sayesinde fonksiyonumuzun


pratik olarak snrsz sayda parametre kabul etmesini salayabiliyoruz. Bu arada, bu tr
fonksiyonlarn alabilecei parametre says, dediimiz gibi, pratikte snrszdr, ama teknik
olarak bu say 256 adedi geemez.
Yukardaki kodlarn verdii ktnn bir demet olduuna dikkatinizi ekmek isterim. Bu bilgiye
sahip olduktan sonra, bu tr fonksiyonlar demet ileme kurallarna gre istediiniz ekilde
maniple edebilirsiniz.

532 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Peki byle bir fonksiyon tanmlamak ne iimize yarar?


Mesela bu yapy kullanarak yle bir fonksiyon yazabilirsiniz:
def arp(*saylar):
sonu = 1
for i in saylar:
sonu *= i
print(sonu)

Bu fonksiyon kendisine verilen btn parametreleri birbiriyle arpar. rnein:


arp(1, 2, 3, 4)

Bu kodun kts 24 olacaktr. Grdnz gibi, fonksiyonumuza istediimiz sayda parametre


vererek bu saylarn birbiriyle arplmasn salayabiliyoruz.
Aslnda burada kullandmz * iareti size hi yabanc deil. Hatrlarsanz print()
fonksiyonundan bahsederken una benzer bir kullanm rnei vermitik:
>>> print(*'TBMM', sep='.')

T.B.M.M

Burada * iareti, eklendii parametreyi elerine ayryor. sep parametresi ise * iaretinin
birbirinden ayrd elerin arasna birer . karakteri ekliyor.
Bu iaretin etkilerini u rneklerde daha net grebilirsiniz:
>>> liste = ["Ahmet", "Mehmet", "Veli"]
>>> print(*liste)

Ahmet Mehmet Veli

>>> szlk = {"a": 1, "b": 2}


>>> print(*szlk)

a b

Grdnz gibi, * iareti herhangi bir eyi alp, bunu paralarna ayryor. te bu *
iaretini fonksiyon tanmlarken kullandmzda ise bu ilemin tam tersi gerekleiyor. Yani
fonksiyon tanmnda parametrenin soluna * getirdiimizde, bu fonksiyon arlrken verilen
argmanlar tek bir deiken iinde bir demet olarak toplanyor. Zaten bu konunun banda
verdiimiz u rnekte de bu durum aka grnyor:
def fonksiyon(*parametreler):
print(parametreler)

fonksiyon(1, 2, 3, 4, 5)

Bu fonksiyonu ardmzda u kt veriliyor:


(1, 2, 3, 4, 5)

Aynen sylediimiz gibi, fonksiyon() adl fonksiyona argman olarak verdiimiz her bir
enin (1, 2, 3, 4, 5 ) tek bir demet iinde toplandn gryorsunuz.
Yldzl parametreler, tanmladnz fonksiyonun parametre saysn herhangi bir ekilde
snrlamak istemediiniz durumlarda ok iinize yarar.

34.5. Parametreler ve Argmanlar 533


Python 3 iin Trke Klavuz, Srm 3

Elbette * iaretiyle birlikte kullanacanz parametrenin ad olarak, Pythonn deiken


adlandrma kurallarna uygun btn kelimeleri belirleyebilirsiniz. Mesela biz yukarda
parametreler adn tercih ettik. Ama Python dnyasnda * iaretiyle birlikte kullanlacak
parametrenin ad geleneksel olarak, argmanlar anlamnda argstr. Yani Python
programclar genellikle yukardaki gibi bir fonksiyonu yle tanmlar:
def fonksiyon(*args):
...

* iareti ile birlikte kullanlacak parametrenin adn args yapmak bir zorunluluk olmamakla
birlikte, baka Python programclarnn kodlarnz daha kolay anlayabilmesi asndan bu
gelenei devam ettirmenizi tavsiye ederim. Yazdmz kodlarda Python programlama dilinin
geleneklerine bal kalmak ounlukla iyi bir alkanlktr.

34.5.5 Rastgele Sayda simli Parametre Belirleme

Bir nceki balk altnda, fonksiyon tanmlarken rastgele sayda isimsiz parametrelerin nasl
belirleneceini tarttk. Ayn bu ekilde, rastgele sayda isimli parametre belirlemek de
mmkndr.
rnein:
def fonksiyon(**parametreler):
print(parametreler)

fonksiyon(isim="Ahmet", soyisim="z", meslek="Mhendis", ehir="Ankara")

Bu kodlar altrdmzda yle bir kt alyoruz:

{'ehir': 'Ankara', 'isim': 'Ahmet', 'soyisim': 'z', 'meslek': 'Mhendis'}

Grdnz gibi, fonksiyonu tanmlarken parametremizin sol tarafna yerletirdiimiz **


iareti, bu fonksiyonu arrken yazdmz isimli parametrelerin bize bir szlk olarak
verilmesini salyor. Bu yapnn bize bir szlk verdiini bildikten sonra, bunu szlk veri
tipinin kurallar erevesinde istediimiz ekilde evirip evirebiliriz.
Peki bu ara ne iimize yarar?
Hatrlarsanz bu blmn en banda kayt_olutur() adl yle bir fonksiyon tanmlamtk:
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

print("-"*30)

Bu fonksiyon bize toplam drt adet parametre kullanarak, isim, soyisim, iletim sistemi
ve ehir bilgilerinden meydana gelen bir kayt oluturma imkan salyor. Bu fonksiyonda
kullancnn girebilecei bilgiler snrl. Ama bir de yle bir fonksiyon yazdmz dnn:
def kayt_olutur(**bilgiler):
print("-"*30)

534 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

for anahtar, deer in bilgiler.items():


print("{:<10}: {}".format(anahtar, deer))

print("-"*30)

kayt_olutur(ad="Frat", soyad="zgl", ehir="stanbul", tel="05333213232")

Bu fonksiyonu altrdmzda u kty alacaz:


tel : 05333213232
ad : Frat
ehir : stanbul
soyad : zgl

Grdnz gibi, ** iaretlerini kullanmamz sayesinde hem adlarn hem de deerlerini


kendimiz belirlediimiz bir kii veritaban oluturma imkan elde ediyoruz. stelik bu
veritabannn, kiiye ait ka farkl bilgi iereceini de tamamen kendimiz belirleyebiliyoruz.
Tpk * iaretlerinin betimledii parametrenin geleneksel olarak args eklinde adlandrlmas
gibi, ** iaretlerinin betimledii parametre de geleneksel olarak kwargs eklinde adlandrlr.
Dolaysyla yukardaki gibi bir fonksiyonu Python programclar yle tanmlar:
def kayt_olutur(**kwargs):
...

** iaretli parametreler pek ok farkl durumda iinize yarayabilir veya iinizi kolaylatrabilir.
Mesela * ve ** iaretlerini kullanarak yle bir program yazabilirsiniz:
def karlk_bul(*args, **kwargs):
for szck in args:
if szck in kwargs:
print("{} = {}".format(szck, kwargs[szck]))
else:
print("{} kelimesi szlkte yok!".format(szck))

szlk = {"kitap" : "book",


"bilgisayar" : "computer",
"programlama": "programming"}

karlk_bul("kitap", "bilgisayar", "programlama", "fonksiyon", **szlk)

Burada tanmladmz karlk_bul() adl fonksiyon, kendisine verilen parametreleri


(*args ), bir szlk iinde arayarak (**szlk ) karlklarn bize kt olarak veriyor. Eer
verilen parametre szlkte yoksa, ilgili kelimenin szlkte bulunmad konusunda da bizi
bilgilendiriyor.
karlk_bul() adl fonksiyonu nasl tanmladmza ok dikkat edin. Parametre listesi
iinde belirttiimiz *args ifadesi sayesinde, fonksiyonu kullanacak kiiye, istedii sayda
isimsiz parametre girme imkan tanyoruz. **kwargs parametresi ise kullancya istedii
sayda isimli parametre girme olana veriyor.
Esasnda yukardaki kod *args ve **kwargs yaplar asndan ucuz bir rnektir. Bu yaplar
iin daha nitelikli bir rnek verelim...
Bildiiniz gibi print() fonksiyonu snrsz sayda isimsiz parametre ve buna ek olarak birka
tane de isimli parametre alyor. Bu fonksiyonun alabildii isimli parametrelerin sep, end,

34.5. Parametreler ve Argmanlar 535


Python 3 iin Trke Klavuz, Srm 3

le ve ush adl parametreler olduunu biliyorsunuz. Yine bildiiniz gibi, sep parametresi
print() fonksiyonuna verilen isimsiz parametrelerin her birinin arasna hangi karakterin
geleceini; end parametresi ise bu parametrelerin en sonuna hangi karakterin geleceini
belirliyor. Bizim amacmz bu fonksiyona bir de start adnda isimli bir parametre ekleyerek
print() fonksiyonunun ilevini genileten baka bir fonksiyon yazmak. Bu yeni parametre,
karakter dizilerinin en bana hangi karakterin geleceini belirleyecek.
imdi bu amacmz gerekletirecek kodlarmz yazalm:
def bas(*args, start='', **kwargs):
for e in args:
print(start+e, **kwargs)

bas('e1', 'e2', 'e3', start="#.")

print() fonksiyonunun ilevini genileten yeni fonksiyonumuzun ad bas(). Bu fonksiyon


her bakmdan print() fonksiyonu ile ayn ilevi grecek. Ancak bas() fonksiyonu, print()
fonksiyonuna ek olarak, sahip olduu start adl bir isimli parametre sayesinde, kendisine
verilen parametrelerin en bana istediimiz herhangi bir karakteri eklemek olana da
verecek bize.
bas() fonksiyonunun ilk parametresi olan *args sayesinde kullancya istedii kadar
parametre verme imkan tanyoruz. Daha sonra da ilave start parametresini tanmlyoruz.
Bu parametrenin ntanml deeri bo bir karakter dizisi. Yani eer kullanc bu parametrenin
deerine herhangi bir ey yazmazsa, *args kapsamnda verilen parametreler zerinde
hibir deiiklik yapmyoruz. Bunun ardndan gelen **kwargs parametresi ise print()
fonksiyonunun halihazrda sahip olduu sep, end, le ve ush parametrelerinin bas()
fonksiyonunda da ayn ekilde kullanlmasn salyor. **kwargs eklinde bir tanmlama
sayesinde, print() fonksiyonunun isimli parametrelerini tek tek belirtip tanmlamak zorunda
kalmyoruz:
def bas(*args, start='', **kwargs):
for e in args:
print(start+e, **kwargs)

f = open("te.txt", "w")

bas('e1', 'e2', 'e3', start="#.", end="", file=f)

Eer elimizde **kwargs gibi bir imkan olmasayd yukardaki fonksiyonu u ekilde
tanmlamamz gerekirdi:
import sys

def bas(*args, start='', sep=' ', end='\n', file=sys.stdout, flush=False):


for e in args:
print(start+e, sep=sep, end=end, file=file, flush=flush)

Grdnz gibi, print() fonksiyonunun btn isimli parametrelerini ve bunlarn ntanml


deerlerini tanmlamak zorunda kaldk. Eer gnn birinde Python gelitiricileri print()
fonksiyonuna bir baka isimli parametre daha eklerse, yukardaki fonksiyonu ilgili yenilie
gre elden geirmemiz gerekir. Ama **kwargs yapsn kullandmzda, print()
fonksiyonuna Python gelitiricilerince eklenecek btn parametreler bizim fonksiyonumuza
da otomatik olarak yansyacaktr...

536 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

34.6 return Deyimi

Bu blmde return adl bir deyimden sz edeceiz. zellikle Python programlama dilini
renmeye yeni balayanlar bu deyimin ne ie yaradn anlamakta zorlanabiliyor. Biz
burada bu deyimi anlalr hale getirebilmek iin elimizden geleni yapacaz. ncelikle ok
basit bir rnek verelim:
def ismin_ne():
isim = input("ismin ne? ")
print(isim)

Bu ok basit bir fonksiyon. Bu fonksiyonu nasl aracamz biliyoruz:


ismin_ne()

Fonksiyonu bu ekilde ardktan sonra, fonksiyon tanmnda yer alan input() fonksiyonu
sayesinde kullancya ismi sorulacak ve verdii cevap ekrana baslacaktr.
Yukardaki fonksiyonun tek ilevi kullancdan ald isim bilgisini ekrana basmaktr. Aldnz
bu veriyi baka yerlerde kullanamazsnz. Bu fonksiyonu ardnz anda kullancya ismi
sorulacak ve alnan cevap ekrana baslacaktr. Ancak siz, tanmladnz fonksiyonlarn tek
grevinin bir veriyi ekrana basmak olmasn istemeyebilirsiniz.
rnein yukardaki fonksiyon yardmyla kullancdan ismini aldktan sonra, bu isim bilgisini
baka bir karakter dizisi iinde kullanmak isteyebilirsiniz. Diyelim ki amacnz ismin_ne()
fonksiyonuyla aldnz ismi u karakter dizisi iine aadaki ekilde yerletirmek:
Merhaba Frat. Naslsn?

Bildiimiz yntemi kullanarak bu amacmz gerekletirmeye alalm:


print("Merhaba {}. Naslsn?".format(ismin_ne()))

Buradan yle bir kt alyoruz:


ismin ne? Frat
Frat
Merhaba None. Naslsn?

Grdnz gibi, istediimiz eyi elde edemiyoruz. nk dediimiz gibi, yukardaki


fonksiyonun tek grevi kullancdan ald kty ekrana basmaktr. Bu fonksiyondan
gelen kty baka yerde kullanamayz. Eer kullanmaya alrsak yukardaki gibi hi
beklemediimiz bir sonu alrz.
Bu arada, ktda None diye bir ey grdnze dikkat edin. Yukardaki fonksiyonu u ekilde
ararak bunu daha net grebilirsiniz:
print(ismin_ne())

Buradan u kty alyoruz:


ismin ne? Frat
Frat
None

Bu ktnn ne anlama geldiini birazdan aklayacaz. Ama ncelikle baka bir konudan sz
edelim.

34.6. return Deyimi 537


Python 3 iin Trke Klavuz, Srm 3

Biraz nce sylediimiz gibi, yukarda tanmladmz ismin_ne() adl fonksiyonun tek grevi
kullancdan ald isim bilgisini ekrana basmaktr. imdi bu fonksiyonu bir de yle
tanmlayalm:
def ismin_ne():
isim = input("ismin ne? ")
return isim

imdi de bu fonksiyonu aralm:


ismin_ne()

Grdnz gibi, fonksiyonu ardmzda yalnzca fonksiyon gvdesindeki input()


fonksiyonu alt, ama bu fonksiyondan gelen veri ekrana kt olarak verilmedi. nk
biz burada herhangi bir ekrana basma (print) ilemi yapmadk. Yaptmz tek ey isim adl
deikeni dndrmek.
Peki bu ne anlama geliyor?
return kelimesi ngilizcede iade etmek, geri vermek, dndrmek gibi anlamlar tar. te
yukardaki rnekte de return deyiminin yapt i budur. Yani bu deyim bize fonksiyondan
bir deer dndrr.
Eer tanmladmz bir fonksiyonda return deyimini kullanarak herhangi bir deer
dndrmezsek, Python fonksiyondan hususi bir deerin dndrlmediini gstermek iin
None adl bir deer dndrr... te yukarda tanmladmz ilk ismin_ne() fonksiyonunu
print(ismin_ne()) eklinde ardmzda ekranda None deerinin grnmesinin nedeni
budur.
Peki bir fonksiyon iinde herhangi bir veriyi ekrana basmayp return deyimi yardmyla
dndrmemizin bize ne faydas var?
Aslnda bunun cevab ok ak. Bir fonksiyon iinde bir deeri dndrmek yerine ekrana
bastnzda o fonksiyonun ilevini alabildiine kstlam oluyorsunuz. Fonksiyonunuzun tek
ilevi bir deeri ekrana basmak oluyor. u rnekte de gsterdiimiz gibi, bu deeri daha sonra
baka ortamlarda kullanamyoruz:
def ismin_ne():
isim = input("ismin ne? ")
print(isim)

print("Merhaba {}. Naslsn?".format(ismin_ne()))

Ama eer, mesela yukardaki fonksiyonda isim deikenini basmak yerine dndrrsek iler
deiir:
def ismin_ne():
isim = input("ismin ne? ")
return isim

print("Merhaba {}. Naslsn?".format(ismin_ne()))

Bu kodlar altrdmzda u kty alyoruz:


ismin ne? Frat
Merhaba Frat. Naslsn?

Grdnz gibi, istediimiz kty rahatlkla elde ettik. ismin_ne() adl fonksiyondan isim
deerini dndrm olmamz sayesinde bu deerle istediimiz ilemi gerekletirebiliyoruz.

538 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Yani bu deeri sadece ekrana basmakla snrlamyoruz kendimizi. Hatta fonksiyondan


dndrdmz deeri baka bir deikene atama imkanna dahi sahibiz bu ekilde:
ad = ismin_ne()
print(ad)

Eer fonksiyondan deer dndrmek yerine bu deeri ekrana basmay tercih etseydik
yukardaki ilemi yapamazdk.
return deyimiyle ilgili son bir ey daha syleyelim...
Bu deyim, iinde bulunduu fonksiyonun alma srecini kesintiye uratr. Yani return
deyimini kullandnz satrdan sonra gelen hibir kod almaz. Basit bir rnek verelim:
def fonk():
print(3)
return
print(5)

fonk()

Bu kodlar altrdnzda yalnzca print(3) satrnn altn, print(5) satrna ise hi


ulalmadn greceksiniz. te bu durumun sebebi, Pythonn kodlar return satrndan
itibaren okumay brakmasdr. Bu zellikten eitli ekillerde yararlanabilirsiniz. rnein:
def fonk(n):
if n < 0:
return 'eksi deerli say olmaz!'
else:
return n

f = fonk(-5)
print(f)

Burada eer fonksiyona parametre olarak eksi deerli bir say verilirse Python bize bir uyar
verecek ve fonksiyonun almasn durduracaktr.

34.7 rnek bir Uygulama

Gelin isterseniz buraya kadar rendiklerimizi kullanarak rnek bir uygulama yazalm. Bir
yandan da yeni eyler renerek bilgimize bilgi katalm.
Amacmz belli miktarda ve belli aralkta rastgele saylar reten bir program yazmak. rnein
programmz u ekilde alt adet rastgele say retebilecek:
103, 298, 152, 24, 91, 285

Ancak programmz bu saylar retirken her saydan yalnzca bir adet retecek. Yani ayn
seride bir saydan birden fazla bulunamayacak.
Dilerseniz ncelikle kodlarmz grelim:
import random

def say_ret(balang=0, biti=500, adet=6):


saylar = set()

34.7. rnek bir Uygulama 539


Python 3 iin Trke Klavuz, Srm 3

while len(saylar) < adet:


saylar.add(random.randrange(balang, biti))

return saylar

Esasnda bu kodlarn (neredeyse) tamamn anlayabilecek kadar Python bilgisine sahipsiniz.


Burada anlamam olabileceiniz tek ey random modldr. O yzden gelin isterseniz bu
modlden biraz sz edelim.
Biz henz modl kavramn bilmiyoruz. Ama buraya gelene kadar birka konu altnda
modllerle ilgili baz rnekler de yapmadk deil. rnein imdiye kadar yazdmz
programlardan rendiimiz kadaryla Pythonda os ve sys adl iki modln bulunduunu,
bu modllerin iinde, program yazarken iimize yarayacak pek ok deiken ve fonksiyon
bulunduunu ve bu fonksiyonlar programlarmzda kullanabilmek iin ilkin bu modlleri ie
aktarmamz gerektiini biliyoruz. te tpk os ve sys gibi, random da Python programlama
dili bnyesinde bulunan modllerden biridir. Bu modln iinde, rastgele saylar retmemizi
salayacak baz fonksiyonlar bulunur. te randrange() de bu fonksiyonlardan biridir.
Dilerseniz bu fonksiyonun nasl kullanldn anlamak iin etkileimli kabukta birka deneme
almas yapalm.
random modlnn iindeki aralar kullanabilmek iin ncelikle bu modl ie aktarmalyz:
>>> import random

Acaba bu modln iinde neler varm?


>>> dir(random)

['BPF', 'LOG4', 'NV_MAGICCONST', 'RECIP_BPF', 'Random',


'SG_MAGICCONST', 'SystemRandom', 'TWOPI', '_BuiltinMethodType',
'_MethodType', '_Sequence', '_Set', '__all__', '__builtins__',
'__cached__', '__doc__', '__file__', '__initializing__',
'__loader__', '__name__', '__package__', '_acos', '_ceil',
'_cos', '_e', '_exp', '_inst', '_log', '_pi', '_random', '_sha512',
'_sin', '_sqrt', '_test', '_test_generator', '_urandom', '_warn',
'betavariate', 'choice', 'expovariate', 'gammavariate', 'gauss',
'getrandbits', 'getstate', 'lognormvariate', 'normalvariate',
'paretovariate', 'randint', 'random', 'randrange', 'sample',
'seed', 'setstate', 'shuffle', 'triangular', 'uniform',
'vonmisesvariate', 'weibullvariate']

Grdnz gibi bu modln iinde epey ara var. Gelin isterseniz bu aralardan en sk
kullanlanlarn tanyalm.
rnein random modl iinde bulunan sample() adl fonksiyon herhangi bir dizi iinden
istediimiz sayda rastgele numune almamz salar:
>>> liste = ["ahmet", "mehmet", "sevgi", "sevim", "selin", "zeynep", "selim"]
>>> random.sample(liste, 2)

['sevim', 'ahmet']

Grdnz gibi, yedi kiilik bir isim listesinden 2 adet rastgele numune aldk. Ayn ilemi
tekrarlayalm:
>>> random.sample(liste, 2)

540 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

['sevgi', 'zeynep']

>>> random.sample(liste, 5)

['selin', 'zeynep', 'ahmet', 'selim', 'mehmet']

Numune alma ilemi tamamen rastgeledir. Ayrca grdnz gibi, listeden istediimiz
sayda numune alabiliyoruz.
random modl iinde bulunan shuffle() adl baka bir fonksiyon, bir dizi iindeki elerin
srasn rastgele bir ekilde kartrmamz salar:
>>> liste = ["ahmet", "mehmet", "sevgi", "sevim",
... "selin", "zeynep", "selim"]
>>> random.shuffle(liste)

shuffle() fonksiyonu liste elerini yine ayn liste iinde deitirdi. Deiiklii grmek iin
listeyi ekrana basabilirsiniz:
>>> liste

['selim', 'selin', 'ahmet', 'mehmet',


'sevim', 'sevgi', 'zeynep']

random modl iinde bulunan bir baka fonksiyon ise randrange() fonksiyonudur. Bu
fonksiyon, belli bir aralkta rastgele saylar retmemizi salar:
>>> random.randrange(0, 500)

156

Burada 0 ile 500 arasnda rastgele bir say rettik.


Grdnz gibi random son derece faydal olabilecek bir modldr. Dilerseniz imdi
random fonksiyonunu bir kenara brakp kodlarmza geri dnelim:
import random

def say_ret(balang=0, biti=500, adet=6):


saylar = set()

while len(saylar) < adet:


saylar.add(random.randrange(balang, biti))

return saylar

Burada ilk satrn ne i yaptn rendik. Bu satr yardmyla random modln ie


aktaryoruz.
Sonraki satrda fonksiyonumuzu tanmlamaya balyoruz:
def say_ret(balang=0, biti=500, adet=6):
...

Fonksiyonumuzun ad say_ret. Bu fonksiyon toplam farkl parametre alyor. Bunlar


balang, biti ve adet. Dikkat ederseniz bu parametrelerin her birinin bir varsaylan deeri
var. Dolaysyla say_ret() fonksiyonu parametresiz olarak arldnda bu parametre
ntanml deerlerine sahip olacaktr.

34.7. rnek bir Uygulama 541


Python 3 iin Trke Klavuz, Srm 3

Gelelim fonksiyon gvdesine...


lk olarak saylar adl bir kme tanmlyoruz.
Bildiiniz gibi, kmeler iinde eler her zaman tektir. Yani bir kme iinde ayn eden
yalnzca bir adet bulunabilir. Kmelerin bu zellii bizim yazdmz program iin olduka
uygun. nk biz de rettiimiz rastgele saylarn benzersiz olmasn istiyoruz. Bu
benzersizlii salayabilecek en uygun veri tipi kmelerdir.
Bir sonraki satrda bir while dngs gryoruz:
while len(saylar) < adet:
saylar.add(random.randrange(balang, biti))

Bu dngye gre, saylar deikeninin uzunluu adet parametresinin deerinden az olduu


mddete, saylar adl deikene balang ve biti parametrelerinin gsterdii deerler
arasndan rastgele saylar eklemeye devam edeceiz. rnein kullanc fonksiyonumuzu
parametresiz olarak ardysa, yukardaki dng u ekilde ileyecektir:
while len(saylar) < 6:
saylar.add(random.randrange(0, 500))

Buna gre, saylar deikeninin uzunluu 6 dan az olduu mddete bu deikene 0 ile
500 arasnda rastgele saylar eklemeye devam edeceiz. Bylelikle saylar deikeni iinde
birbirinden farkl toplam 6 say olmu olacak.
Fonksiyonun son satrnda ise u kodu gryoruz:
return saylar

Bu kod yardmyla, belirtilen miktardaki saylar tutan saylar adl deikeni fonksiyondan
dndryoruz. Yani fonksiyonumuz d dnyaya saylar adl bir deiken veriyor... Bu
deikeni bu ekilde dndrdkten sonra istediimiz gibi kullanabiliriz. Mesela:
for i in range(100):
print(say_ret())

Buradan una benzer bir kt alacaksnz:


{34, 144, 211, 468, 58, 286}
{41, 170, 395, 113, 178, 29}
{161, 195, 452, 271, 212, 324}
{1, 328, 461, 398, 464, 220}
{356, 489, 12, 114, 329, 472}
{320, 34, 238, 176, 243, 149}
{364, 304, 434, 403, 217, 63}
{452, 392, 175, 464, 81, 467}
{36, 230, 21, 440, 287, 415}
{292, 391, 145, 182, 440, 223}
{386, 38, 309, 377, 59, 277}
{0, 2, 42, 400, 404, 60}
{48, 482, 393, 80, 116, 407}
{483, 136, 431, 35, 344, 381}
...

Grdnz gibi, say_ret() fonksiyonunu kullanarak, her biri 6 eden oluan 100 adet
say listesi elde ettik. Biz yukarda bu fonksiyonu parametresiz olarak altrdmz iin,
Python balang, biti ve adet parametrelerinin ntanml deerlerini kulland (srasyla 0,
500 ve 6 ).

542 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

stersek biz fonksiyonumuzu farkl parametrelerle arabiliriz:


print(say_ret(0, 100, 10))

Bu kodlar bize 0 ile 100 arasndan 10 adet rastgele say seer:


{3, 4, 9, 11, 13, 47, 50, 53, 54, 61}

Eer ktnn kme parantezleri arasnda grnmesini istemiyorsanz elbette kty keynize
gre biimlendirebilirsiniz:
print(*say_ret(100, 1500, 20), sep='-')

Bu ekilde, 100 ile 1500 aras saylardan rastgele 20 adet seip her bir saynn arasna bir
tane - iareti yerletirdik:
352-1251-1366-1381-1350-330-203-842-269-285-816
-658-643-308-1174-152-594-522-1214-959

34.8 Fonksiyonlarn Kapsam ve global Deyimi

Elimizde yle bir kod olduunu dnelim:


x = 0

def fonk():
x = 1
return x

Bu kodlarda, fonksiyonun dnda x adl bir deiken var. Fonksiyonun iinde de yine x adn
tayan baka bir deiken var. Fonksiyonumuzun grevi bu x deikenini dndrmek.
Bu noktada size yle bir soru sormama izin verin: Acaba fonksiyon iinde tanmladmz x
deikeni, fonksiyon dndaki x deikeninin deerini deitiriyor mu? Bu sorunun cevabn
u kodlarla verelim:
x = 0

def fonk():
x = 1
return x

print('fonksiyon iindeki x: ', fonk())


print('fonksiyon dndaki x: ', x)

Bu kodlar altrdmzda u kty alacaz:


fonksiyon iindeki x: 1
fonksiyon dndaki x: 0

Grdnz gibi fonksiyon iindeki ve fonksiyon dndaki ayn adl deikenler birbirine
karmyor. Bunun sebebi, Pythondaki isim alan (namespace ) adl bir kavramdr.
Peki isim alan ne demek?
Pythonda deikenlerin, fonksiyonlarn ve daha sonra greceiniz gibi snarn bir kapsam
vardr. Bu kapsama Pythonda isim alan ad verilir. Dolaysyla Pythonda her nesnenin,

34.8. Fonksiyonlarn Kapsam ve global Deyimi 543


Python 3 iin Trke Klavuz, Srm 3

geerli ve etkin olduu bir isim alan bulunur. rnein yukardaki kodlarda fonksiyon
dndaki x deikeni ana isim alannda yer alan global bir deikendir. Fonksiyon iindeki
x deikeni ise fonk() deikeninin isim alan iinde yer alan lokal bir deikendir. Bu iki
deiken, adlar ayn da olsa, birbirlerinden farkl iki nesnedir.
Bir de u rneklere bakalm:
x = []
print('x\'in ilk hali:', x)

def deitir():
print('x\'i deitiriyoruz...')
x.append(1)
return x

deitir()
print('x\'in son hali: ', x)

Burada ise daha farkl bir durum sz konusu. Fonksiyon iinde append() metodunu
kullanarak yaptmz ekleme ilemi fonksiyon dndaki listeyi de etkiledi. Peki ama bu nasl
oluyor?
Python herhangi bir nesneye gndermede bulunduumuzda, yani o nesnenin deerini talep
ettiimizde aradmz nesneyi ilk nce mevcut isim alan iinde arar. Eer aranan nesneyi
mevcut isim alan iinde bulamazsa yukarya doru btn isim alanlarn tek tek kontrol eder.
Birka rnek verelim:
def fonk():
print(x)

fonk()

Tahmin edebileceiniz gibi, bu kodlar u hatay verecektir:


Traceback (most recent call last):
File "deneme.py", line 4, in <module>
fonk()
File "deneme.py", line 2, in fonk
print(x)
NameError: global name 'x' is not defined

Bu hatann sebebi, x adl bir deikenin tanmlanmam olmasdr. Bu hatay gidermek iin
yle bir kod yazabiliriz:
x = 0

def fonk():
print(x)

fonk()

Bu kod global alandaki x deikeninin deerini verecektir.


Yukardaki rnekte, biz print() ile x in deerini sorguladmzda Python ncelikle fonk()
adl fonksiyonun isim alanna bakt. Orada x i bulamaynca bu kez global alana ynelip, orada
bulduu x in deerini yazdrd.
Bu durumu daha net anlayabilmek iin u kodlar inceleyelim:

544 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

x = 0

def fonk():
x = 10
print(x)

fonk()
print(x)

Bu kodlar altrdmzda 10 ktsn alrz. nk Python, dediimiz gibi, ncelikle mevcut


isim alann kontrol ediyor. x deikenini mevcut isim alannda bulduu iin de global alana
bakmasna gerek kalmyor.
Yalnz burada dikkat etmemiz gereken baz eyler var.
Dediimiz gibi, global isim alanndaki nesnelerin deerini lokal isim alanlarndan
sorgulayabiliyoruz. Ancak istediimiz ey global isim alanndaki nesnelerin deerini
deitirmekse baz kavramlar arasndaki farklar iyi anlamamz gerekiyor.
Pythonda bir nesnenin deerini deitirmekle, o nesneyi yeniden tanmlamak farkl
kavramlardr.
Eer bir nesne deitirilebilir bir nesne ise, o nesnenin deerini, lokal isim alanlarndan
deitirebilirsiniz:
x = set()

def fonk():
x.add(10)
return x

print(fonk())

Ama eer bir nesne deitirilemez bir nesne ise, o nesnenin deerini zaten normalde
de deitiremezsiniz. Deitirmi gibi yapmak iin ise o nesneyi yeniden tanmlamanz
gerektiini biliyorsunuz:
>>> isim = 'Frat'
>>> isim += ' zgl'
>>> print(isim)

Frat zgl

Burada yaptmz ey, karakter dizisinin deerini deitirmekten ziyade bu karakter dizisini
yeniden tanmlamaktr. nk bildiiniz gibi karakter dizileri deitirilemeyen veri tipleridir.
te karakter dizileri gibi deitirilemeyen nesneleri, lokal isim alanlarnda
deitiremeyeceiniz gibi, yeniden tanmlayamazsnz da...
isim = 'Frat'

def fonk():
isim += ' zgl'
return isim

print(fonk())

Bu kodlar altrdnzda Python size bir hata mesaj gsterecektir.

34.8. Fonksiyonlarn Kapsam ve global Deyimi 545


Python 3 iin Trke Klavuz, Srm 3

Ayn durum deitirilebilir nesneler iin de geerlidir:


isim_listesi = []

def fonk():
isim_listesi += ['Frat zgl', 'Orun Kunek']
return isim_listesi

print(fonk())

Deitirilebilen bir veri tipi olan listeleri, fonksiyon iinde yeniden tanmlayamazsnz. Ancak
tabii isterseniz listeleri deiiklie uratabilirsiniz:
isim_listesi = []

def fonk():
isim_listesi.extend(['Frat zgl', 'Orun Kunek'])
return isim_listesi

print(fonk())

Bu kodlar dzgn bir ekilde alp, fonksiyon dndaki isim_listesi adl listeyi deiiklie
uratacaktr. Ancak u kodlar hata verecektir:
isim_listesi = []

def fonk():
isim_listesi += ['Frat zgl', 'Orun Kunek']
return isim_listesi

print(fonk())

te Python programlama dili bu tr durumlar iin zm olacak bir ara sunar bize. Bu aracn
ad global.
Gelin isterseniz bu global adl deyimin nasl kullanlacana bakalm nce...
u kodlarn hata vereceini biliyorsunuz:
isim = 'Frat'

def fonk():
isim += ' zgl'
return isim

print(fonk())

Ama bu kodlara yle bir ekleme yaparsanz iler deiir:


isim = 'Frat'

def fonk():
global isim
isim += ' zgl'
return isim

print(fonk())

Burada fonk() adl fonksiyonun ilk satrnda yle bir kod gryoruz:

546 Blm 34. Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

global isim

te bu satr, isim adl deikenin global alana tanmasn salyor. Bylece global alanda
bulunan isim adl deikeni deiiklie uratabiliyoruz.
global deyimi her ne kadar ilk bakta ok faydal bir aram gibi grnse de aslnda
programlarmzda genellikle bu deyimi kullanmaktan kanmamz iyi bir kir olacaktr. nk
bu deyim aslnda global alan kirletmemize neden oluyor. Global deikenlerin lokal
isim alanlarnda deiiklie uratlmas, eer dikkatsiz davranrsanz programlarnzn hatal
almasna yol aabilir.

34.8. Fonksiyonlarn Kapsam ve global Deyimi 547


BLM 35

Gml Fonksiyonlar

Bu blmde, daha nce de birka kez bahsettiimiz ve oka rneini grdmz bir
kavramdan sz edeceiz. Bu kavramn ad gml fonksiyonlar.
Esasnda biz buraya gelene kadar Pythonda pek ok gml fonksiyon grdk. Dolaysyla
aslnda grn olarak bunlarn neye benzediini biliyoruz. rnein daha nceki
derslerimizde grdmz print() gml bir fonksiyondur. Ayn ekilde open(), type(),
len(), pow(), bin() ve imdiye kadar tantmz teki btn fonksiyonlar birer gml
fonksiyondur.
Gml fonksiyonlar ngilizcede builtin functions olarak adlandrlr. Bu fonksiyonlar
gerekten de dile gml vaziyettedirler. Bildiiniz gibi, bir fonksiyonu kullanabilmemiz iin
o fonksiyonu tanmlamamz gerekir. te gml fonksiyonlar, bizim tanmlamamza gerek
kalmadan, Python gelitiricileri tarafndan nceden tanmlanp dile gmlm ve hizmetimize
sunulmu faydal birtakm aralardr.
te bu blmde biz de bu gml fonksiyonlar tek tek ve ayrntl olarak inceleyeceiz.
Dediimiz gibi, bunlardan bir ksmn halihazrda grmtnz. Ama biz btnlk asndan,
nceden ele alm olduumuz bu fonksiyonlara da ksaca deinmeden gemeyeceiz.
Bylelikle hem yeni fonksiyonlar renmi olacaz hem de nceden rendiimiz
fonksiyonlarla birlikte yeni fonksiyonlar da derli toplu bir ekilde grme imkanmz olacak.
Bu blmde elbette birtakm fonksiyonlar salt art arda sralamakla yetinmeyeceiz.
Pythondaki gml fonksiyonlar incelerken bir yandan da Python programlama dilindeki
ok nemli baz kavramlar ele alacaz.
lk olarak abs() adl bir fonksiyonla balyoruz gml fonksiyonlar incelemeye...

35.1 abs()

ngilizcede mutlak anlamna gelen absolute adl bir kelime bulunur. te bu fonksiyonun
ad da bu kelimeden gelir. Fonksiyonumuzun grevi de isminin anlamna yakndr. abs()
fonksiyonunu bir saynn mutlak deerini elde etmek iin kullanyoruz.
Peki mutlak deer ne anlama geliyor. Esasnda siz bu kavrama matematik derslerinden
ainasnz. Ama bilmeyenler veya unutmu olanlar iin tekrar edelim. Mutlak deer bir
saynn 0 a olan uzakldr. rnein 20 saysnn 0 saysna olan uzakl 20dir. Dolaysyla
20 saysnn mutlak deeri 20dir. Ayn ekilde -20 saysnn da 0 saysna uzakl 20dir. Yani,
-20 saysnn da mutlak deeri 20dir.
te abs() fonksiyonu bize bir saynn mutlak deerinin ne olduunu syler:

548
Python 3 iin Trke Klavuz, Srm 3

>>> abs(-20)

20

>>> abs(20)

20

>>> abs(20.0)

20.0

Mutlak deer kavram yalnzca tamsaylar ve kayan noktal saylar iin deil, ayn zamanda
karmak saylar iin de geerlidir. Dolaysyla abs() fonksiyonunu kullanarak karmak
saylarn da mutlak deerini hesaplayabiliriz:
>>> abs(20+3j)

20.223748416156685

Grdnz gibi bu fonksiyon yalnzca tek bir parametre alyor ve bu parametrenin mutlak
deerini dndryor.

35.2 round()

round() fonksiyonu bir sayy belli ltlere gre yukar veya aa doru yuvarlamamz
salar. Basit birka rnek verelim:
>>> round(12.4)

12

>>> round(12.7)

13

Grdnz gibi bu fonksiyon, kayan noktal saylar en yakn tam sayya doru yuvarlyor.
Ancak burada dikkat etmemiz gereken bir nokta var.
u rnekleri bir inceleyelim:
>>> round(1.5)

>>> round(12.5)

12

Grdnz gibi, fonksiyonumuz 1.5 saysn yukar doru, 12.5 saysn ise aa doru
yuvarlad. Bunun sebebi, kayan noktal bir saynn st ve alt tam saylara olan uzaklnn
birbirine eit olduu durumlarda Pythonn ift sayya doru yuvarlama yapmay tercih
etmesidir. Mesela yukardaki rneklerde 1.5 says hem 1 saysna, hem de 2 saysna eit
uzaklkta bulunuyor. te Python bu durumda, bir ift say olan 2 saysna doru yuvarlamay
tercih edecektir.

35.2. round() 549


Python 3 iin Trke Klavuz, Srm 3

round() fonksiyonu toplam iki parametre alr. lk parametre, yuvarlanacak saynn kendisidir.
Yuvarlama hassasiyetini belirlemek iin ise ikinci bir parametreden yararlanabiliriz.
rnein 22 saysn 7 ye bldmzde normalde yle bir kt elde ederiz:
>>> 22/7

3.142857142857143

round() fonksiyonunu tek parametre ile kullandmzda bu fonksiyon yukardaki sayy u


ekilde yuvarlayacaktr:
>>> round(22/7)

te biz round() fonksiyonuna ikinci bir parametre daha vererek, yuvarlama hassasiyetini
kontrol edebiliriz.
Aadaki rnekleri dikkatlice inceleyin:
>>> round(22/7)

>>> round(22/7, 0)

3.0

>>> round(22/7, 1)

3.1

>>> round(22/7, 2)

3.14

>>> round(22/7, 3)

3.143

>>> round(22/7, 4)

3.1429

Grdnz gibi, round() fonksiyonuna verdiimiz ikinci parametre, yuvarlama ileminin ne


kadar hassas olacan belirliyor.

35.3 all()

All kelimesi Trkede hepsi anlamna gelir. Bu fonksiyonun grevi de bu anlam artrr.
all() fonksiyonunun grevi, bir dizi iinde bulunan btn deerler True ise True deeri, eer
bu deerlerden herhangi biri False ise de False deeri dndrmektir.
rnein elimizde yle bir liste olduunu varsayalm:

550 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

>>> liste = [1, 2, 3, 4]

imdi all() fonksiyonunu bu liste zerine uygulayalm:


>>> all(liste)

True

Bildiiniz gibi, 0 hari btn saylarn bool deeri True dur. Yukardaki listede False deeri
verebilecek herhangi bir deer bulunmadndan, all() fonksiyonu bu liste iin True deerini
veriyor. Bir de una bakalm:
>>> liste = [0, 1, 2, 3, 4]
>>> all(liste)

False

Dediimiz gibi, all() fonksiyonu ancak dizi iindeki btn deerlerin bool deeri True ise
True kts verecektir.
Son bir rnek daha verelim:
>>> liste = ['ahmet', 'mehmet', '']
>>> all(liste)

False

Listede False deerine sahip bir bo karakter dizisi bulunduu iin all() fonksiyonu False
kts veriyor.
Bu fonksiyonu her trl kodun bool deerlerini test etmek iin kullanabilirsiniz. Mesela
bu fonksiyonu kullanarak, bir nesnenin listelenen zelliklerin hepsine sahip olup olmadn
denetleyebilirsiniz:
>>> a = 3
>>> t1 = a == 3 #say 3 m?
>>> t2 = a < 4 #say 4'ten kk m?
>>> t3 = a % 2 == 1 #say bir tek say m?
>>> all([t1, t2, t3]) #say bu zelliklerin hepsine sahip mi?

True

Eer saymz bu zelliklerin birine bile sahip deilse, all() fonksiyonu False kts verecektir.

35.4 any()

Any kelimesi ngilizcede herhangi bir anlamna gelir. te any() fonksiyonunun grevi de,
bir dizi iindeki btn deerlerden en az biri True ise True kts vermektir.
rnein:
>>> liste = ['ahmet', 'mehmet', '']
>>> any(liste)

True

35.4. any() 551


Python 3 iin Trke Klavuz, Srm 3

any() fonksiyonunun True kts verebilmesi iin listede yalnzca bir adet True deerli e
olmas yeterlidir. Bu fonksiyonun False kts verebilmesi iin dizi iindeki btn elerin
bool deerinin False olmas gerekir:
>>> l = ['', 0, [], (), set(), dict()]
>>> any(l)

False

i bo veri tiplerinin bool deerinin False olduunu biliyorsunuz.


Tpk all() fonksiyonunda olduu gibi, any() fonksiyonunu da, bir grup nesnenin bool
deerlerini denetlemek amacyla kullanabilirsiniz.

35.5 ascii()

Bu fonksiyon, bir nesnenin ekrana baslabilir halini verir bize. Dilerseniz bu fonksiyonun
yapt ii tanmlamak yerine bunu bir rnek zerinden anlatmaya alalm:
>>> a = 'istihza'
>>> print(ascii(a))

'istihza'

Bu fonksiyonun, print() fonksiyonundan farkl olarak, ktya trnak iaretlerini de eklediine


dikkat edin.
ascii() fonksiyonunun tam olarak ne yaptn daha iyi anlamak iin herhalde u rnek daha
faydal olacaktr.
Dikkatlice bakn:
>>> print('\n')

Bu komutu verdiimizde, n ka dizisinin etkisiyle yeni satra geileceini biliyorsunuz.


Bir de una bakn:
>>> print(ascii('\n!'))

'\n'

Grdnz gibi, ascii() fonksiyonu, satr ba ka dizisinin grevini yapmasn salamak


yerine bu ka dizisinin ekrana baslabilir halini veriyor bize.
Ayrca bu fonksiyon, karakter dizileri iindeki Trke karakterlerin de UNICODE temsillerini
dndrr. rnein:
>>> a = 'k'
>>> print(ascii(a))
'\u0131\u015f\u0131k'

Bunu daha net u ekilde grebiliriz:


>>> for i in a:
... print(ascii(i))
...
'\u0131'

552 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

'\u015f'
'\u0131'
'k'

Grdnz gibi, ascii() fonksiyonu ASCII olmayan karakterlerle karlatnda bunlarn


karakter temsilleri yerine UNICODE temsillerini (veya onaltlk sayma dzenindeki
karlklarn) veriyor.
Son olarak u rnee bakalm:
>>> liste = ['elma', 'armut', 'erik']
>>> temsil = ascii(liste)
>>> print(temsil)

['elma', 'armut', 'erik']

Burada listemiz ascii() fonksiyonuna parametre olarak verildikten sonra artk liste olma
zelliini yitirip bir karakter dizisi haline gelir. Bunu denetleyelim:
>>> print(type(temsil))
<class 'str'>

>>> temsil[0]

'['

Grdnz gibi, ascii() fonksiyonu listeyi alp, bunu ekrana baslabilir bir btn haline
getiriyor. Elbette bunun iin de, kendisine verilen parametreyi bir karakter dizisine
dntryor.

35.6 repr()

repr() fonksiyonunun yapt i, biraz nce grdmz ascii() fonksiyonunun yapt ie


ok benzer. Bu iki fonksiyon, ASCII olmayan karakterlere muameleleri asndan birbirinden
ayrlr.
Hatrlarsanz ascii() fonksiyonu ASCII olmayan karakterlerle karlatnda bunlarn
UNICODE (veya onaltlk) temsillerini gsteriyordu:
>>> ascii('eker')

"'\\u015feker'"

repr() fonksiyonu ise ASCII olmayan karakterlerle karlasa bile, bize kt olarak bunlarn
da karakter karlklarn gsterir:
>>> repr('eker')

"'eker'"

Geri kalan zellikleri bakmndan repr() ve ascii() fonksiyonlar birbiriyle ayndr.

35.6. repr() 553


Python 3 iin Trke Klavuz, Srm 3

35.7 bool()

Bu fonksiyon bir nesnenin bool deerini verir:


>>> bool(0)

False

>>> bool(1)

True

>>> bool([])

False

35.8 bin()

Bu fonksiyon, bir saynn ikili dzendeki karln verir:


>>> bin(12)

'0b1100'

Bu fonksiyonun verdii ktnn bir say deil, karakter dizisi olduuna dikkat etmelisiniz.

35.9 bytes()

Bu fonksiyon bytes trnde nesneler oluturmak iin kullanlr. Bu fonksiyonu bayt adl veri
tipini incelerken ayrntl olarak ele almtk. Gelin isterseniz burada da bu fonksiyona yle
bir deinelim.
Dediimiz gibi, bytes() adl fonksiyon, bytes trnde veriler oluturmaya yarar. Bu fonksiyon
ilev olarak, daha nce rendiimiz list(), str(), int(), set(), dict() gibi fonksiyonlara
ok benzer. Tpk bu fonksiyonlar gibi, bytes() fonksiyonunun grevi de farkl veri tiplerini
bayt adl veri tipine dntrmektir.
Bu fonksiyon, kendisine verilen parametrelerin trne bal olarak birbirinden farkl sonular
ortaya karr. rnein eer bu fonksiyona parametre olarak bir tam say verecek olursanz,
bu fonksiyon size o tam say miktarnca bir bayt nesnesi verecektir. Gelin isterseniz bu
durumu rnekler zerinde gstermeye alalm:
>>> bytes(10)

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

Yukardaki komut bize, her bir esinin deeri 0 olan 10 baytlk bir veri dndrd:
>>> a = bytes(10)

>>> a

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

554 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

>>> a[0]

>>> a[1]

>>> a[2]

Grdnz gibi, bytes(10) komutuyla oluturduumuz a deikeni iinde toplam 10 adet


bayt var ve bu baytlarn her birinin deeri 0.
Yukarda, bytes() fonksiyonuna bir tam say deerli parametre verdiimizde nasl bir sonu
alacamz rendik. Peki biz bu fonksiyona parametre olarak bir karakter dizisi verirsek ne
olur?
Hemen grelim:
>>> bytes('istihza')

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: string argument without an encoding

Bu fonksiyona karakter dizilerini dorudan parametre olarak veremeyiz. Eer verirsek


yukardaki gibi bir hata alrz. Peki acaba bu hatay almamzn nedeni ne olabilir?
Dediimiz gibi, bytes() fonksiyonu, eitli veri tiplerini bayta dntrmeye yarar. Ancak
bildiiniz gibi, bayta dntrme ilemi her kod zc tarafndan farkl biimde yaplr.
rnein:
>>> 'k'.encode('utf-8')

b'\xc4\xb1\xc5\x9f\xc4\xb1k'

>>> 'k'.encode('cp857')

b'\x8d\x9f\x8dk'

>>> 'k'.encode('cp1254')

b'\xfd\xfe\xfdk'

Dolaysyla, bytes() fonksiyonunun bir karakter dizisini bayta evirirken nasl davranmas
gerektiini anlayabilmesi iin, bayta dntrme ilemini hangi kod zc ile yapmak
istediimizi aka belirtmemiz gerekir:
>>> bytes('k', 'utf-8')

b'\xc4\xb1\xc5\x9f\xc4\xb1k'

>>> bytes('k', 'cp1254')

b'\xfd\xfe\xfdk'

35.9. bytes() 555


Python 3 iin Trke Klavuz, Srm 3

>>> bytes('k', 'cp857')

b'\x8d\x9f\x8dk'

Grdnz gibi, bytes() fonksiyonuna parametre olarak bir karakter dizisi verebilmek iin,
bu karakter dizisi ile birlikte bir kod zc de belirtmemiz gerekiyor. Bylece bytes()
fonksiyonu kendisine verdiimiz karakter dizisini, belirttiimiz kod zcnn kurallarna
gre bayta dntryor.
Bu arada, ktda grnen b harerinin, elimizdeki verinin bir bayt olduunu gsteren bir
iaret olduunu biliyorsunuz.
Ayrca, bytes() fonksiyonuna verdiimiz ikinci parametrenin isminin encoding olduunu ve
bu parametreyi isimli bir parametre olarak da kullanabileceimizi belirtelim:
>>> bytes('istihza', encoding='ascii')

Bu noktada size yle bir soru soraym: Acaba bytes() fonksiyonuna ilk parametre olarak
verdiimiz karakter dizisi, ikinci parametrede belirttiimiz kod zc tarafndan tannmazsa
ne olur?
Cevab tahmin edebilirsiniz: Byle bir durumda elbette Python bize bir hata mesaj gsterir:
>>> bytes('eker', 'ascii')

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character '\u015f' in position 0:
ordinal not in range(128)

... veya:
>>> bytes('', 'cp857')

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
File "C:\Python33\lib\encodings\cp857.py", line 12, in encode
return codecs.charmap_encode(input,errors,encoding_map)
UnicodeEncodeError: 'charmap' codec can't encode character '\u20ac' in position
0: character maps to <undefined>

har ASCII karakter kmesinde; iareti ise CP857 adl karakter kmesinde
tanmlanmam birer karakter olduu iin, ilgili kod zcler bu karakterleri zp bayta
dntremiyor. Yazdmz kodlarn bu tr durumlarda tamamen kmesini engellemek
iin, nceki derslerimizde de eitli vesilelerle renmi olduumuz errors adl bir
parametreden yararlanabiliriz:
>>> bytes('k', encoding='ascii', errors='replace')

b'???k'

>>> bytes('eker', encoding='ascii', errors='replace')

b'?eker'

>>> bytes('', encoding='cp857', errors='replace')

556 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

b'?'

>>> bytes('', encoding='cp857', errors='ignore')

b''

>>> bytes('', encoding='cp857', errors='xmlcharrefreplace')

b'&#8364;'

>>> bytes('eker', encoding='cp857', errors='xmlcharrefreplace')

b'\x9feker'

Grdnz gibi, errors parametresine verdiimiz eitli deerler yardmyla, bytes()


fonksiyonunun, encoding parametresinde belirtilen kod zc ile zlemeyen karakterlerle
karlatnda nasl davranacan belirleyebiliyoruz.
errors parametresine verdiimiz btn bu deerleri nceki derslerimizde renmitik.
Dolaysyla yukarda gsterdiimiz kodlar rahatlkla anlayabilecek kadar Python bilgisine
sahibiz.
Son olarak, bytes() fonksiyonuna parametre olarak 0-256 aras saylardan oluan diziler de
verebiliriz:
>>> bytes([65, 10, 12, 11, 15, 66])

b'A\n\x0c\x0b\x0fB'

Bu yap iinde Python, 0 ile 128 aras saylar iin standart ASCII tablosunu, 128 ile 256 aras
saylar iin ise Latin-1 karakter kmesini temel alarak saylar birer bayta dntrecektir.

35.10 bytearray()

Bildiiniz gibi baytlar deitirilemeyen bir veri tipidir. Dolaysyla bir bayt veri tipi zerinde
herhangi bir deiiklik yapamayz. rnein bir baytn herhangi bir esini baka bir deerle
deitiremeyiz:
>>> a = bytes('istihza', 'ascii')
>>> a[0]

105

>>> a[0] = 106

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: 'bytes' object does not support item assignment

Ama eer hem baytlarla almak, hem de bu baytlarn zerinde deiiklik yapabilmek
isterseniz baytlar yerine bayt dizileri ile alabilirsiniz. te bunun iin bytearray() adl bir
fonksiyondan yararlanyoruz.
Yaptklar i bakmndan bytearray() ve bytes() fonksiyonlar birbirlerine ok benzer. Bu
ikisi arasndaki tek fark, bytearray() ile oluturulan veri tipinin, bytes() ile oluturulan veri

35.10. bytearray() 557


Python 3 iin Trke Klavuz, Srm 3

tipinin aksine, deitirilebilir nitelikte olmasdr:


>>> a = bytearray('adana', 'ascii')

>>> a

bytearray(b'adana')

>>> a[0] = 65

>>> a

bytearray(b'Adana')

35.11 chr()

Bu fonksiyon, kendisine parametre olarak verilen bir tam saynn karakter karln
dndrr. rnein:
>>> chr(10)

'\n'

Bildiiniz gibi 10 saysnn karakter karl satr ba karakteridir. Bir de una bakalm:
>>> chr(65)

'A'

65 saysnn karakter karl ise A hardir.


Bu fonksiyon saylar karakterlere dntrrken ASCII sistemini deil, UNICODE sistemini
temel alr. Dolaysyla bu fonksiyon ile 128 (veya 255) st saylar da dntrebiliriz.
rnein:
>>> chr(305)

''

35.12 list()

Bu fonksiyon iki farkl ama iin kullanlabilir:


1. Liste tipinde bir veri oluturmak
2. Farkl veri tiplerini liste adl veri tipine dntrmek
Birinci ama iin bu fonksiyonu u ekilde kullanyoruz:
>>> l = list()

Bylece liste tipinde bir veri oluturmu olduk.


Dediimiz gibi list() fonksiyonunu, farkl tipteki verileri listeye dntrmek iin de
kullanabiliriz. rnein:

558 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

>>> list('istihza')

['i', 's', 't', 'i', 'h', 'z', 'a']

Burada istihza adl karakter dizisini bir listeye dntrdk.


Elbette bu fonksiyonu kullanarak baka veri tiplerini de listeye dntrebiliriz. rnein bir
szl, bu fonksiyon yardmyla kolayca listeye dntrebiliriz:
>>> s = {'elma': 44, 'armut': 10, 'erik': 100}
>>> list(s)

['armut', 'erik', 'elma']

Bir szlk listeye dntrlrken, elbette szln anahtarlar dikkate alnacaktr. Eer siz
szln anahtarlarndan deil de deerlerinde bir liste oluturmak isterseniz yle bir kod
yazabilirsiniz:
>>> list(s.values())

[10, 100, 44]

35.13 set()

set() fonksiyonu list() fonksiyonuna ok benzer. Bu fonksiyon da tpk list() fonksiyonu


gibi, veri tipleri arasnda dntrme ilemleri gerekletirmek iin kullanlabilir. set()
fonksiyonunun grevi farkl veri tiplerini kmeye dntrmektir:
>>> k = set()

Burada bo bir kme oluturduk. imdi de mesela bir karakter dizisini kmeye dntrelim:
>>> i = 'istihza'
>>> set(i)

{'t', 's', 'z', 'a', 'i', 'h'}

35.14 tuple()

tuple() fonksiyonu da, tpk list(), set() ve benzerleri gibi bir dntrc fonksiyondur.
Bu fonksiyon farkl veri tiplerini demete dntrr:
>>> tuple('a')

('a',)

35.15 frozenset()

Bu fonksiyonu kullanarak farkl veri tiplerini dondurulmu kmeye dntrebilirsiniz:

35.13. set() 559


Python 3 iin Trke Klavuz, Srm 3

>>> s = set('istihza')
>>> df = frozenset(s)
>>> df

frozenset({'t', 's', 'a', 'z', 'i', 'h'})

35.16 complex()

Saylardan sz ederken, eer matematikle ok fazla ili dl deilseniz pek


karlamayacanz, karmak say adl bir say trnden de bahsetmitik. Karmak
saylar, bir gerek, bir de sanal ksmdan oluan saylardr.
Karmak saylar Pythonda complex ifadesiyle gsteriliyor. Mesela u bir karmak saydr:
>>> 12+0j

te eer herhangi bir sayy karmak sayya dntrmeniz gerekirse complex() adl bir
fonksiyondan yararlanabilirsiniz. rnein:
>>> complex(15)

(15+0j)

Byle bir kod yazdmzda, verdiimiz parametre karmak saynn gerek ksmn
oluturacak, sanal ksm ise 0 olarak kabul edilecektir. Elbette isterseniz sanal ksm kendiniz
de belirleyebilirsiniz:
>>> complex(15, 2)

(15+2j)

35.17 oat()

Bu fonksiyonu, saylar veya karakter dizilerini kayan noktal sayya dntrmek iin
kullanyoruz:
>>> float('134')

134.0

>>> float(12)

12.0

35.18 int()

Bu fonksiyon birka farkl ama iin kullanlabilir. int() fonksiyonunun en temel grevi, bir
karakter dizisi veya kayan noktal sayy (eer mmknse) tam sayya dntrmektir:

560 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

>>> int('10')

10

>>> int(12.4)

12

Bunun dnda bu fonksiyonu, herhangi bir sayma sisteminde temsil edilen bir sayy onlu
sayma sistemine dntrmek iin de kullanabiliriz. rnein:
>>> int('12', 8)

10

Burada, sekizli sayma sistemine ait say deerli bir karakter dizisi olan 12yi onlu sayma
sistemine dntrdk ve bylece 10 saysn elde ettik.
int() fonksiyonunu sayma sistemleri arasnda dntrme ilemlerinde kullanabilmek iin
ilk parametrenin bir karakter dizisi olmas gerektiine dikkat ediyoruz.
Bu arada, int(12, 8) komutununun 12 saysn sekizli sayma sistemine dntrmediine
dikkat edin. Bu komutun yapt i sekizli sayma sistemindeki 12 saysn onlu sayma
sistemine dntrmektir.
int() fonksiyonunun bu kullanmyla ilgili bir rnek daha verelim:
>>> int('4cf', 16)

1231

Burada da, onaltl sayma sistemine ait bir say olan 4cf yi onlu sayma sistemine evirdik
ve 1231 saysn elde ettik. 4cf saysn int() fonksiyonuna parametre olarak verirken
bunu karakter dizisi eklinde yazmay unutmuyoruz. Aksi halde Python bize bir hata mesaj
gsterecektir.

35.19 str()

Bu fonksiyonun, farkl veri tiplerini karakter dizisine dntrmek iin kullanldn


biliyorsunuz. rnein:
>>> str(12)

'12'

Burada 12 saysn bir karakter dizisine dntrdk. imdi de bir bayt karakter dizisine
dntrelim:
>>> bayt = b'istihza'

Bayt nesnemizi tanmladk. imdi bunu bir karakter dizisine dntrelim:


>>> kardiz = str(bayt, encoding='utf-8')
>>> print(kardiz)

istihza

35.19. str() 561


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, bir bayt karakter dizisine dntrmek iin str() fonksiyonuna
encoding adl bir parametre veriyoruz. Fonksiyonumuz, bu parametrede hangi kodlama
biimi belirtildiyse, baytlar bu kodlama biiminin kurallarna gre bir karakter dizisine
dntryor.
Tahmin edebileceiniz gibi, belirttiiniz kodlama biiminin herhangi bir bayt karakter dizisine
dntremedii durumlara kar bir errors parametresi de verebiliriz str() fonksiyonuna.
rnein elimizde bayt tipinde yle bir veri olduunu varsayalm:
>>> bayt = bytes('kadn', encoding='utf-8')
>>> print(bayt)

b'kad\xc4\xb1n'

imdi bu bayt veri tipini bir karakter dizisine dntrmeye alalm:


>>> kardiz = str(bayt, encoding='ascii')

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc4 in position 3: ordinal
not in range(128)

ASCII adl kod zc, bkadn iindeki baytlardan birini tanyamad iin bize bir hata
mesaj gsterdi. Bildiiniz gibi ASCII 128den byk baytlar dntremez. te bu tr
durumlara kar errors parametresinden yararlanabilirsiniz:
>>> kardiz = str(bayt, encoding='ascii', errors='ignore')
>>> print(kardiz)

kadn

errors parametresine verdiimiz ignore deeri sayesinde Python bize hata mesaj gstermek
yerine, ASCII ile zlemeyen bayt grmezden geldi. errors parametresinin hangi deerleri
alabileceini nceki derslerimizden hatrlyor olmalsnz.

35.20 dict()

Bu fonksiyon, farkl veri tiplerinden szlkler retmemizi salar. rnein bu fonksiyonu


kullanarak bo bir szlk oluturabiliriz:
>>> s = dict()

Bu fonksiyon, deikenlerden szlkler oluturmamz da salar:


>>> s = dict(a=1, b=2, c=3)

{'a': 1, 'b': 2, 'c': 3}

dict() fonksiyonuna parametre olarak i ie gemi listeler veya demetler vererek de szlk
retebiliriz:
>>> eler = (['a', 1], ['b', 2], ['c', 3])
>>> dict(eler)

{'a': 1, 'b': 2, 'c': 3}

562 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

35.21 callable()

Bu fonksiyon, bir nesnenin arlabilir olup olmadn denetler. Peki hangi nesneler
arlabilir zelliktedir. Mesela fonksiyonlar arlabilir nesnelerdir. Deikenler ise
arlabilir nesneler deildir.
Birka rnek verelim bununla ilgili:
>>> callable(open)

True

Pythonn open() adl bir fonksiyonu olduu iin, doal olarak callable() fonksiyonu True
kts veriyor.
Bir de una bakalm:
>>> import sys
>>> callable(sys.version)

False

Burada da sys modl iindeki version adl nesnenin arlabilir zellikte olup olmadn
sorguladk. Daha nceki derslerimizde de grdnz gibi, sys modl iindeki version
adl ara bir fonksiyon deil, deikendir. Dolaysyla bu deiken callable(sys.version)
sorgusuna False yant verir.

35.22 ord()

Bu fonksiyon, bir karakterin karlk geldii ondalk sayy verir. rnein:


>>> ord('a')

97

>>> ord('')

305

35.23 oct()

Bu fonksiyon, bir sayy sekizli dzendeki karlna evirmemizi salar:


>>> oct(10)

'0o12'

35.24 hex()

Bu fonksiyon, bir sayy onaltl dzendeki karlna evirmemizi salar:

35.21. callable() 563


Python 3 iin Trke Klavuz, Srm 3

>>> hex(305)

'Ox131'

Yalnz hem oct() hem de hex() fonksiyonlarnda dikkat etmemiz gereken ey, bu
fonksiyonlarn parametre olarak bir say alp, kt olarak bir karakter dizisi veriyor olmasdr.

35.25 eval(), exec(), globals(), locals(), compile()

Bu blmde be farkl fonksiyonu bir arada inceleyeceiz. Bu fonksiyonlar birlikte ele


almamzn nedeni bunlarn birbiriyle yakndan balantl olmas.
Burada ileyeceimiz bu be fonksiyon unlardan oluuyor:
1. eval()
2. exec()
3. globals()
4. locals()
5. compile()
Ancak bu fonksiyonlardan sz etmeye balamadan nce Pythondaki iki nemli kavram
akla kavuturmamz gerekiyor: Bu kavramlar unlar:
1. ifade
2. deyim
ncelikle ifade kavramndan balayalm.
ngilizcede expression denen ifadeler, bir deer retmek iin kullanlan kod paralardr.
Karakter dizileri, saylar, ileler, teki veri tipleri, liste reteleri, szlk reteleri, kme
reteleri, fonksiyonlar hep birer ifadedir. rnein:
>>> 5

>>> 23 + 4

>>> [i for i in range(10)]

>>> len([1, 2, 3])

ngilizcede statement olarak adlandrlan deyimler ise ifadeleri de kapsayan daha geni bir
kavramdr. Buna gre btn ifadeler ayn zamanda birer deyimdir. Daha dorusu, ifadelerin
bir araya gelmesi ile deyimler oluturulabilir.
Deyimlere birka rnek verelim:
>>> a = 5

>>> if a:
... print(a)

>>> for i in range(10):


... print(i)

564 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Python programlama dilinde deyimlerle ifadeleri ayrt etmenin kolay bir yolu da eval()
fonksiyonundan yararlanmaktr. Eer deyim mi yoksa ifade mi olduundan emin
olamadnz bir eyi eval() fonksiyonuna parametre olarak verdiinizde hata almyorsanz
o parametre bir ifadedir. Eer hata alyorsanz o parametre bir deyimdir. nk eval()
fonksiyonuna parametre olarak yalnzca ifadeler verilebilir.
Birka rnek verelim:
>>> eval('a = 5')

File "<string>", line 1


a = 5
^
SyntaxError: invalid syntax

Grdnz gibi, eval() fonksiyonu bize bir hata mesaj verdi. nk a = 5 kodu bir
deyimdir. Unutmayn, Pythonda btn deer atama ilemleri birer deyimdir. Dolaysyla
eval() fonksiyonu bu deyimi parametre olarak alamaz.
Bir de una bakalm:
>>> eval('5 + 25')

30

Bu defa hata almadk. nk eval() fonksiyonuna, olmas gerektii gibi, parametre olarak
bir ifade verdik. Bildiiniz gibi, 5 + 25 kodu bir ifadedir.
Dediimiz gibi, eval() fonksiyonu deyimleri parametre olarak alamaz. Ama exec()
fonksiyonu alabilir:
>>> exec('a = 5')

Bu ekilde, deeri 5 olan a adl bir deiken oluturmu olduk. sterseniz kontrol edelim:
>>> print(a)

Grdnz gibi, exec() fonksiyonu, mevcut isim alan iinde a adl bir deiken oluturdu.
Yalnz elbette mevcut isim alan iinde yeni deikenler ve yeni deerler olutururken dikkatli
olmamz gerektiini biliyorsunuz. Zira mesela yukardaki komutu vermeden nce mevcut isim
alannda zaten a adl bir deiken varsa, o deikenin deeri deiecektir:
>>> a = 20

Elimizde, deeri 20 olan a adl bir deiken var. imdi exec() fonksiyonu yardmyla a
deikeninin de iinde yer ald mevcut isim alanna mdahale ediyoruz:
>>> exec('a = 10')

Bylece a deikeninin eski deerini silmi olduk. Kontrol edelim:


>>> print(a)

10

Bu tr durumlarda, exec() ile oluturduunuz deikenleri global isim alanna deil de, farkl
bir isim alanna gndermeyi tercih edebilirsiniz. Peki ama bunu nasl yapacaz?

35.25. eval(), exec(), globals(), locals(), compile() 565


Python 3 iin Trke Klavuz, Srm 3

Python programlama dilinde isim alanlar szlk tipinde bir veridir. rnein global isim alan
basit bir szlkten ibarettir.
Global isim alann gsteren szlkte hangi anahtar ve deerlerin olduunu grmek iin
globals() adl bir fonksiyonu kullanabilirsiniz:
>>> globals()

Bu fonksiyonu altrdmzda una benzer bir kt alrz:


{'__doc__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__name__': '__main__', '__package__': None, '__builtins__': <module 'builtins'>}

Grdnz gibi, elimizdeki ey gerekten de bir szlk. Dolaysyla bir szlk ile ne
yapabilirsek bu szlkle de ayn eyi yapabiliriz...
globals adl bu szln ierii, o anda global isim alannda bulunan nesnelere gre farkllk
gsterecektir. rnein:
>>> x = 10

eklinde 10 deerine sahip bir x nesnesi tanmladktan sonra globals() fonksiyonunu tekrar
altrrsanz global isim alanna bu nesnenin de eklenmi olduunu grrsnz.
Dediimiz gibi, globals() fonksiyonundan dnen nesne bir szlktr. Bu szle, herhangi
bir szle veri ekler gibi deer de ekleyebilirsiniz:
>>> globals()['z'] = 23

Bu ekilde global isim alanna z adl bir deiken eklemi oldunuz:


>>> z

23

Yalnz, Python programlama dili bize bu ekilde global isim alanna nesne ekleme imkan
verse de, biz mecbur deilsek bu yntemi kullanmaktan kanmalyz. nk bu ekilde
srad bir yntemle deiken tanmladmz iin aslnda global isim alann, nerden geldiini
kestirmenin g olduu deerlerle kirletmi oluyoruz.
Bildiiniz gibi, Pythonda global isim alan dnda bir de lokal isim alan bulunur. Lokal isim
alanlarnn, fonksiyonlara (ve ileride greceimiz gibi snara) ait bir isim alan olduunu
biliyorsunuz. te bu isim alanlarna ulamak iin de locals() adl bir fonksiyondan
yararlanacaz:
def fonksiyon(param1, param2):
x = 10
print(locals())

fonksiyon(10, 20)

Bu fonksiyonu altrdnzda u kty alacaksnz:


{'param2': 20, 'param1': 10, 'x': 10}

Grdnz gibi, locals() fonksiyonu gerekten de bize fonksiyon() adl fonksiyon iindeki
lokal deerleri veriyor.

566 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

globals() ve locals() fonksiyonlarnn ne ie yaradn incelediimize gre exec()


fonksiyonunu anlatrken kaldmz yere dnebiliriz.
Ne diyorduk?
Elimizde, deeri 20 olan a adl bir deiken vard:
>>> a = 20

exec() fonksiyonu yardmyla a deikeninin de iinde yer ald mevcut isim alanna
mdahale edelim:
>>> exec('a = 3')

Bu ekilde a deikeninin varolan deerini silmi olduk:


>>> print(a)

Dediimiz gibi, bu tr durumlarda, exec() ile oluturduunuz deikenleri global isim alan
yerine farkl bir isim alanna gndermeyi tercih etmemiz daha uygun olacaktr. Pythonda
isim alanlarnn basit bir szlk olduunu rendiimize gre, exec() ile oluturduumuz
deikenleri global isim alan yerine nasl farkl bir isim alanna gndereceimizi grebiliriz.
nce yeni bir isim alan oluturalm:
>>> ia = {}

imdi exec() ile oluturacamz deerleri bu isim alanna gnderebiliriz:


>>> exec('a = 3', ia)

Bylece global isim alanndaki a deikeninin deerine dokunmam olduk:


>>> a

20

Yeni oluturduumuz deer ise ia adl yeni isim alanna gitti:


>>> ia['a']

35.26 copyright()

Bu fonksiyon yardmyla Pythonn telif haklarna ilikin bilgilere eriebilirsiniz:


>>> copyright()

Copyright (c) 2001-2012 Python Software Foundation.


All Rights Reserved.

Copyright (c) 2000 BeOpen.com.


All Rights Reserved.

Copyright (c) 1995-2001 Corporation for National Research Initiatives.

35.26. copyright() 567


Python 3 iin Trke Klavuz, Srm 3

All Rights Reserved.

Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam.


All Rights Reserved.

35.27 credits()

Bu fonksiyon, Python programlama diline katkda bulunanlara teekkr ieren kk bir


metni ekrana kt olarak verir:
>>> credits()

Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands


for supporting Python development. See www.python.org for more information.

35.28 license()

Bu fonksiyon yardmyla Pythonn lisansna ilikin epey ayrntl metinlere ulaabilirsiniz.

35.29 dir()

Eer dir() fonksiyonunu parametresiz olarak kullanrsak, mevcut isim alanndaki eleri bir
liste halinde elde ederiz:
>>> dir()

['__builtins__', '__doc__', '__loader__', '__name__', '__package__']

Bu bakmdan dir() fonksiyonu globals() ve locals() fonksiyonlarna benzer. Ancak


onlardan fark, dir() fonksiyonunun kt olarak bir liste, globals() ve locals()
fonksiyonlarnn ise birer szlk vermesidir.
Ayrca dir() fonksiyonunu kullanarak nesnelerin metot ve niteliklerini ieren bir listeye
ulaabileceimizi de biliyorsunuz. rnein bu fonksiyonu kullanarak farkl veri tiplerinin
metot ve niteliklerini listeleyebiliriz:
>>> dir('')
>>> dir([])
>>> dir({})

35.30 divmod()

Bu fonksiyonun ilevini bir rnek zerinden gstermeye alalm:


>>> divmod(10, 2)

(5, 0)

568 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi divmod(10, 2) komutu bize iki eli bir demet veriyor. Bu demetin ilk esi,
divmod() fonksiyonuna verilen ilk parametrenin ikinci parametreye blnmesi ileminin
sonucudur. Demetimizin ikinci esi ise, ilk parametrenin ikinci parametreye blnmesi
ileminden kalan saydr. Yani demetin ilk parametresi blme ileminin blm ksmn, ikinci
esi ise kalan ksmn verir.
Bu fonksiyonun blme ilemininin sonucunu tamsay cinsinden verdiine dikkat ediyoruz:
>>> divmod(10, 3)

(3, 1)

10 says 3 saysna blndnde tamsay cinsinden sonu 3 tr. Bu blme ileminin kalan
ise 1 dir.

35.31 enumerate()

ngilizcede enumerate kelimesi numaralandrmak anlamna gelir. enumerate()


fonksiyonunun grevi de kelimenin bu anlamyla ayndr. Yani bu fonksiyonu kullanarak
nesneleri numaralandrabiliriz.
Bu fonksiyon bize bir enumerate nesnesi verir:
>>> enumerate('istihza')

<class 'enumerate'>

Bu nesnenin ieriine nasl eriebileceimizi biliyorsunuz:


Nesneyi bir listeye evirebiliriz:
>>> list(enumerate('istihza'))

[(0, 'i'), (1, 's'), (2, 't'), (3, 'i'), (4, 'h'), (5, 'z'), (6, 'a')]

veya:
>>> [i for i in enumerate('istihza')]

[(0, 'i'), (1, 's'), (2, 't'), (3, 'i'), (4, 'h'), (5, 'z'), (6, 'a')]

print() fonksiyonuna yldzl parametre olarak verebiliriz:


>>> print(*enumerate('istihza'))

(0, 'i') (1, 's') (2, 't') (3, 'i') (4, 'h') (5, 'z') (6, 'a')

veya nesne zerinde bir dng kurabiliriz:


>>> for i in enumerate('istihza'):
... print(i)
...
(0, 'i')
(1, 's')
(2, 't')
(3, 'i')
(4, 'h')

35.31. enumerate() 569


Python 3 iin Trke Klavuz, Srm 3

(5, 'z')
(6, 'a')

Grdnz gibi, enumerate nesnesi bize her koulda iki eli demetler veriyor. Bu
demetlerin herbir esine nasl ulaabileceimizi de biliyor olmalsnz:
>>> for sra, e in enumerate('istihza'):
... print("{}. {:>2}".format(sra, e))
...
0. i
1. s
2. t
3. i
4. h
5. z
6. a

rneklerden de grdnz gibi, enumerate() fonksiyonu bize bir dizi iindeki elerin
srasn ve enin kendisini ieren bir demet veriyor. Dikkat ettiyseniz, her zaman olduu
gibi, Python burada da saymaya 0dan balyor. Yani enumerate() fonksiyonunun rettii e
sralamasnda ilk enin sras 0 oluyor. Elbette eer isterseniz enumerate() fonksiyonunun
saymaya katan balayacan kendiniz de belirleyebilirsiniz:
>>> for sra, e in enumerate('istihza', 1):
... print("{}. {:>2}".format(sra, e))
...
1. i
2. s
3. t
4. i
5. h
6. z
7. a

enumerate() fonksiyonuna verdiimiz ikinci parametre saymaya katan balanacan


gsteriyor. Eer bu fonksiyonu ikinci parametre olmadan kullanrsak Python bizim saymaya
0dan balamak istediimizi varsayacaktr.

35.32 exit()

Bu fonksiyon, o anda alan programdan kmanz salar. Eer bu komutu etkileimli


kabukta verirseniz o anda ak olan oturum kapanacaktr.

35.33 help()

help() fonksiyonu gml fonksiyonlar iinde en faydal fonksiyonlarn banda gelir. Bu


fonksiyonu kullanarak Python programlama diline ait elere ilikin yardm belgelerine
ulaabiliriz. rnein:
>>> help(dir)

570 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Bu komutu verdiimizde dir() fonksiyonunun ne ie yaradn gsteren ngilizce bir belgeye


ularz. Grdnz gibi, hakknda bilgi edinmek istediimiz eyi help() fonksiyonuna
parametre olarak vererek ilgili yardm dosyasna eriebiliyoruz.
Eer bu fonksiyonu parametresiz olarak kullanrsak etkileimli yardm denen ekrana ularz:
>>> help()

Welcome to Python 3.3! This is the interactive help utility.

If this is your first time using Python, you should definitely check out
the tutorial on the Internet at http://docs.python.org/3.3/tutorial/.

Enter the name of any module, keyword, or topic to get help on writing
Python programs and using Python modules. To quit this help utility and
return to the interpreter, just type "quit".

To get a list of available modules, keywords, or topics, type "modules",


"keywords", or "topics". Each module also comes with a one-line summary
of what it does; to list the modules whose summaries contain a given word
such as "spam", type "modules spam".

help>

Bu ekranda, hakknda bilgi edinmek istediiniz eyi help> ibaresinden hemen sonra, boluk
brakmadan yazarak eye ilikin bilgilere ulaabilirsiniz:
help> dir

Etkileimli yardm ekranndan kmak iin q harne basabilirsiniz.

35.34 id()

Pythonda her nesnenin bir kimliinin olduunu biliyorsunuz. Kimlik ilelerini incelediimiz
konuda bundan bir miktar bahsetmi ve orada id() adl bir fonksiyondan sz etmitik.
Orada yle bir rnek vermitik:
>>> a = 50
>>> id(a)

505494576

>>> kardiz = "Elveda Zalim Dnya!"


>>> id(kardiz)

14461728

Orada sylediimiz ve yukardaki rneklerden de bir kez daha grdnz gibi, Pythondaki
her nesnenin kimlii eiz, tek ve benzersizdir.

35.34. id() 571


Python 3 iin Trke Klavuz, Srm 3

35.35 input()

Bu fonksiyonun ne ie yaradn gayet iyi biliyorsunuz. input() adl bu gml fonksiyonu


kullanarak kullanc ile veri alveriinde bulunabiliyoruz.

35.36 format()

Bu gml fonksiyonun grevi, daha nce karakter dizilerini ilerken, karakter dizilerinin
bir metodu olarak rendiimiz format() metodununa benzer bir ekilde, karakter dizilerini
biimlendirmektir. Ancak format() fonksiyonu, daha nce rendiimiz format() metoduna
gre daha dar kapsamldr. format() metodunu kullanarak olduka karmak karakter
dizisi biimlendirme ilemlerini gerekletirebiliriz, ama birazdan inceleyeceimiz format()
gml fonksiyonu yalnzca tek bir deeri biimlendirmek iin kullanlr.
Basit bir rnek verelim:
>>> format(12, '.2f')

12.00
Yukardaki ifadeyi daha nce grdmz format() metodu ile u ekilde yazabiliriz:
>>> '{:.2f}'.format(12)

'12.00'

35.37 lter()

Bu gml fonksiyon yardmyla dizi nitelii tayan nesneler iindeki eler zerinde belirli
bir lte gre bir szme ilemi uygulayabiliriz. Dilerseniz filter() fonksiyonunun grevini
bir rnek zerinden anlamaya alalm.
Diyelim ki elimizde yle bir liste var:
>>> [400, 176, 64, 175, 355, 13, 207, 298, 397, 386, 31, 120, 120, 236,
241, 123, 249, 364, 292, 153]

Amacmz bu liste iindeki tek saylar szmek.


Daha nce rendiimiz yntemleri kullanarak bu grevi u ekilde yerine getirebiliriz:
>>> for i in l:
... if i % 2 == 1:
... print(i)
...
175
355
13
207
397
31
241
123

572 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

249
153

Hatta eer istersek liste retelerini kullanarak ayn ilemi daha ksa bir yoldan da
halledebiliriz:
>>> [i for i in l if i % 2 == 1]

[175, 355, 13, 207, 397, 31, 241, 123, 249, 153]

te Python, yukardaki ilemi yapabilmemiz iin bize nc bir yol daha sunar. Bu nc
yolun ad filter() fonksiyonudur. Dikkatlice bakn:
def tek(say):
return say % 2 == 1

print(*filter(tek, l))

Dilerseniz bu kodlar daha iyi anlayabilmek iin filter() fonksiyonuna biraz daha yakndan
bakalm...
filter() fonksiyonu toplam iki parametre alr. Bu parametrelerden ilki lt belirleyen
fonksiyon, ikincisi ise bu ltn uygulanaca edir. Yukardaki rnee baktmzda, tek()
adl fonksiyonun, l adl e zerine uygulandn gryoruz.
Yukardaki rnekte ilk olarak tek() adl bir fonksiyon tanmladk:
def tek(say):
return say % 2 == 1

Bu fonksiyonun grevi, kendisine parametre olarak verilen bir saynn tek say olup olmadn
sorgulamak. Eer verilen parametre bir tek say ise fonksiyonumuz True deerini, tek say
deilse False deerini dndrecektir. sterseniz fonksiyonumuzu test edelim:
print(tek(12))

12 says bir tek say olmad iin fonksiyonumuz bize False kts verir.
Bir de una bakalm:
print(tek(117))

117 says ise bir tek saydr. Bu nedenle fonksiyonumuz bize True deerini verecektir.
te biz bu fonksiyonu, filter() fonksiyonu yardmyla u liste zerine uygulayacaz:
l = [400, 176, 64, 175, 355, 13, 207, 298, 397, 386, 31,
120, 120, 236, 241, 123, 249, 364, 292, 153]

Dediimiz gibi, filter() fonksiyonu, dizi zellii tayan nesneler zerinde belli bir lte
gre ltreleme ilemi yapmamz salar. Biz de biraz nce tanmladmz tek() adl
fonksiyonu l adl bu listeye uygulayarak liste iindeki tek saylar ltreleyeceiz.
filter() fonksiyonunu altralm:
>>> filter(tek, l)

Burada filter() fonksiyonuna ilk parametre olarak tek() fonksiyonunu verdik. kinci
parametremiz ise bu fonksiyonu uygulayacamz l adl liste. Amacmz, l adl liste zerine

35.37. lter() 573


Python 3 iin Trke Klavuz, Srm 3

tek() fonksiyonunu uygulayarak, bu liste iindeki elerden True kts verenleri (yani tek
saylar) ayklamak.
imdi de yukardaki koddan aldmz ktya bakalm:
<filter object at 0x00F74F30>

Grdnz gibi, bu fonksiyonu bu ekilde kullandmzda elde ettiimiz ey bir ltre


nesnesi. Bu nesne iindeki eleri grebilmek iin ne yapabileceimizi biliyorsunuz:
>>> list(filter(tek, l))

[175, 355, 13, 207, 397, 31, 241, 123, 249, 153]

veya:
>>> print(*filter(tek, l))

175 355 13 207 397 31 241 123 249 153

ya da:
>>> [i for i in filter(tek, l)]

[175, 355, 13, 207, 397, 31, 241, 123, 249, 153]

Grdnz gibi, gerekten de l adl liste iindeki btn tek saylar szld.
Gelin isterseniz filter() fonksiyonunu biraz daha iyi anlayabilmek iin basit bir alma
yapalm.
Elimizde bir snftaki rencilerin Matematik snavndan ald notlar ieren bir szlk var:
notlar = {'Ahmet' : 60,
'Sinan' : 50,
'Mehmet' : 45,
'Ceren' : 87,
'Selen' : 99,
'Cem' : 98,
'Can' : 51,
'Kezban' : 100,
'Hakan' : 66,
'Mahmut' : 80}

Okulda kullanlan not sistemine gre yukardaki notlar u ekilde snandrabiliyoruz:


def not_durumu(n):
if n in range(0, 50): return 'F'
if n in range(50, 70): return 'D'
if n in range(70, 80): return 'C'
if n in range(80, 90): return 'B'
if n in range(90, 101): return 'A'

Buna gre mesela print(not_durumu(54)) gibi bir kod yazdmzda bu notun karlk geldii
D saysn alabiliyoruz. Peki biz bu notlar belli bir lte gre szmek, ayklamak istersek
ne yapabiliriz? rnein notu 70ten yukar olan rencileri listelemek istersek nasl bir kod
yazabiliriz?
te byle bir durumda filter() adl gml fonksiyonu kullanabiliriz:

574 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

notlar = {'Ahmet' : 60,


'Sinan' : 50,
'Mehmet' : 45,
'Ceren' : 87,
'Selen' : 99,
'Cem' : 98,
'Can' : 51,
'Kezban' : 100,
'Hakan' : 66,
'Mahmut' : 80}

def sz(n):
return n >= 70

print(*filter(sz, notlar.values()))

Grdnz gibi, filter() fonksiyonu, sz() adl fonksiyon ile belirlediimiz lt notlar
adl szln deerleri zerine tek tek uygulamamz salyor.

35.38 hash()

Bu fonksiyon, belirli trdeki nesnelere bir karma deeri vermemizi salar. rnein:
>>> hash('istihza')

-840510580

>>> hash('python')

212829695

Ancak bu fonksiyonun rettii kt ayn nesne iin btn sistemlerde ayn olmayabilir.
Yani rnein yukardaki hash(istihza) komutu 32 bitlik ve 64 bitlik iletim sistemlerinde
birbirinden farkl sonular verebilir. Ayrca bu fonksiyonun rettii karma deerlerinin
birbiriyle akma ihtimali de yksektir. Dolaysyla bu fonksiyonu kullanarak, mesela parola
girileri iin karma deeri retmek doru olmaz.

35.39 isinstance()

Hatrlarsanz daha ilk derslerimizde rendiimiz type() adl bir fonksiyon vard. Bu
fonksiyonu bir nesnenin hangi veri tipinde olduunu tespit etmek iin kullanyorduk:
>>> type('istihza')

<class 'str'>

te buna benzer ekilde, tip denetimi iin kullanabileceimiz bir fonksiyon daha var. Bu
fonksiyonun ad isinstance().
Bu fonksiyonu yle kullanyoruz:

35.38. hash() 575


Python 3 iin Trke Klavuz, Srm 3

>>> isinstance('istihza', str)

True

Grdnz gibi istihza gerekten bir karakter dizisi (str) olduu iin komutumuz True
kts veriyor.
Bir de una bakalm:
>>> isinstance('istihza', list)

False

istihza bir liste (list) olmad iin komutumuz bu kez False kts verdi.

35.40 len()

Bu fonksiyon yardmyla nesnelerin uzunluklarn hesaplayabileceimizi biliyorsunuz:


>>> len('istihza')

>>> l = [1, 4, 5, 3, 2, 9, 10]


>>> len(l)

35.41 map()

Diyelim ki elimizde yle bir liste var:


>>> l = [1, 4, 5, 4, 2, 9, 10]

Amacmz bu liste iindeki her enin karesini hesaplamak. Bunun iin yle bir yol
izleyebiliriz:
>>> for i in l:
... i ** 2
...
1
16
25
16
4
81
100

Bylece, istediimiz gibi, btn elerin karesini bulmu olduk. Bu tr bir ilemi yapmann
bir baka yolu da map() adl bir gml fonksiyondan yararlanmaktr. Dikkatlice bakn:
>>> def karesi(n):
... return n ** 2
...

576 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Burada bir n saysnn karesini hesaplayan bir fonksiyon tanmladk. imdi bu fonksiyonu l
listesinin btn eleri zerine uygulayacaz:
>>> list(map(karesi, l))

[1, 16, 25, 16, 4, 81, 100]

35.42 max()

max() gml fonksiyonunun grevi, bir dizi iindeki en byk eyi vermektir. Bu fonksiyon
birka farkl parametre alr ve verdii kt, ald parametrelerin trne ve saysna bal
olarak deiiklik gsterebilir.
Bu fonksiyonu en basit u ekilde kullanabilirsiniz:
>>> max(1, 2, 3)

max() fonksiyonu yukardaki ekilde altrldnda, kendisine verilen parametreler arasnda


en byk olan bulacaktr. Yukardaki parametrelerden en by 3 olduu iin de yukardaki
komut 3 kts verecektir.
Yukardaki kodlarn salad etkiyi u ekilde de elde edebiliriz:
>>> liste = [1, 2, 3]
>>> max(liste)

max() fonksiyonu yukarda gsterildii gibi birtakm isimsiz parametrelerle birlikte key adl
isimli bir parametre de alr. Bu parametre yardmyla max() fonksiyonunun en byk
kavramn hangi lte gre seeceini belirleyebiliriz. rnein:
>>> isimler = ['ahmet', 'can', 'mehmet', 'selin', 'abdullah', 'kezban']
>>> max(isimler, key=len)

'abdullah'

max() fonksiyonu ntanml olarak, en byk kavramn saysal byklk zerinden


deerlendirir. Yani herhangi bir key parametresi kullanlmadnda, bu fonksiyon otomatik
olarak bir dizi iindeki en byk sayy bulur. Ancak eer biz istersek, yukardaki rnekte
olduu gibi, en byk kavramnn uzunluk cinsinden deerlendirilmesini de salayabiliriz.
Yukardaki rnekte elimizde yle bir liste var:
>>> isimler = ['ahmet', 'can', 'mehmet', 'selin', 'abdullah', 'kezban']

Amacmz bu liste iindeki isimler arasndan, en fazla harf ierenini bulmak. Bildiiniz gibi
Pythonda bir karakter dizisinin uzunluunu belirlemek iin len() adl bir fonksiyondan
yararlanyoruz. te aadaki kod yardmyla da max() fonksiyonunun en byk ltn
len() fonksiyonu zerinden deerlendirmesini salyoruz:
>>> max(isimler, key=len)

Bu arada key fonksiyonuna len() fonksiyonunu parantezsiz olarak verdiimize dikkat edin.

35.42. max() 577


Python 3 iin Trke Klavuz, Srm 3

Gelin isterseniz max() fonksiyonunu biraz daha iyi anlamak iin ufak bir alma yapalm.
Diyelim ki elimizde yle bir szlk var:
askerler = {'ahmet' : 'onba',
'mehmet' : 'temen',
'ali' : 'yzba',
'cevat' : 'albay',
'berkay' : 'stemen',
'mahmut' : 'binba'}

Amacmz bu szlk iindeki en yksek askeri rtbeyi bulmak. te bunun iin max()
fonksiyonundan yararlanabiliriz.
Bildiiniz gibi, max() fonksiyonu lt olarak saysal bykl gz nne alyor. Elbette
askeri rtbeleri byle bir lte gre sralamak pek mmkn deil. Ama eer yle bir
fonksiyon yazarsak iler deiir:
def en_yksek_rtbe(rtbe):
rtbeler = {'er' : 0,
'onba' : 1,
'avu' : 2,
'astemen' : 3,
'temen' : 4,
'stemen' : 5,
'yzba' : 6,
'binba' : 7,
'yarbay' : 8,
'albay' : 9}

return rtbeler[rtbe]

Burada, rtbelerin her birine bir say verdik. En kk rtbe en dk sayya, en yksek
rtbe ise en byk sayya sahip. Fonksiyonumuz bir adet parametre alyor. Bu parametrenin
ad rtbe. Yazdmz fonksiyon, kendisine parametre olarak verilecek rtbeyi rtbeler adl
szlkte arayp, bu rtbeye karlk gelen sayy dndrecek.
Bu bilgileri kullanarak kodlarmzn son halini dzenleyelim:
def en_yksek_rtbe(rtbe):
rtbeler = {'er' : 0,
'onba' : 1,
'avu' : 2,
'astemen' : 3,
'temen' : 4,
'stemen' : 5,
'yzba' : 6,
'binba' : 7,
'yarbay' : 8,
'albay' : 9}

return rtbeler[rtbe]

askerler = {'ahmet': 'onba',


'mehmet': 'temen',
'ali': 'yzba',
'cevat': 'albay',
'berkay': 'stemen',
'mahmut': 'binba'}

578 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Artk max() fonksiyonunu askerler adl szlk zerine uygulayabiliriz:


print(max(askerler.values(), key=en_yksek_rtbe))

Bylece askerler adl szln deerleri en_yksek_rtbe() fonksiyonunun sunduu lt


zerinden ele alnacak ve en byk say deerine sahip olan rtbe kt olarak verilecektir.
Yukardaki kodlar problemimizi zyor. Peki ama ya biz rtbe ile birlikte bu rtbeyi tayan
askerin adn da renmek istersek nasl bir kod yazacaz?
Bunun iin de yle bir kod yazabiliriz:
for k, v in askerler.items():
if askerler[k] in max(askerler.values(), key=en_yksek_rtbe):
print(v, k)

Eer isterseniz burada in ileci yerine == ilecini de kullanabilirsiniz:


for k, v in askerler.items():
if askerler[k] == max(askerler.values(), key=en_yksek_rtbe):
print(v, k)

35.43 min()

min() fonksiyonu max() fonksiyonunun tam tersini yapar. Bildiiniz gibi max() fonksiyonu bir
dizi iindeki en byk eyi buluyordu. te min() fonksiyonu da bir dizi iindeki en kk
eyi bulur. Bu fonksiyonun kullanm max() ile ayndr.

35.44 open()

Bu fonksiyon herhangi bir dosyay amak veya oluturmak iin kullanlr. Eer dosyann
almas veya oluturulmas esnasnda bir hata ortaya karsa IOError trnde bir hata mesaj
verilir.
Bu fonksiyonun forml udur:
>>> open(dosya_adi, mode='r', buffering=-1, encoding=None,
... errors=None, newline=None, closefd=True, opener=None)

Grdnz gibi, bu fonksiyon pek ok farkl parametre alabiliyor. Biz imdiye kadar bu
parametrelerin yalnzca en sk kullanlanlarn ilemitik. imdi ise geri kalan parametrelerin
ne ie yaradn da ele alacaz.
Yukardaki formlden de grebileceiniz gibi, open() fonksiyonunun ilk parametresi
dosya_adi dr. Yani amak veya oluturmak istediimiz dosya adn bu parametre ile
belirtiyoruz:
>>> open('falanca_dosya.txt')

Elbette eer amak istediiniz dosya, o anda iinde bulunduunuz dizinde deilse dosya ad
olarak, o dosyann tam adresini yazmanz gerekir. Mesela:

35.43. min() 579


Python 3 iin Trke Klavuz, Srm 3

>>> open('/home/istihza/Desktop/dosya.txt')

Bu arada, dosya adresini yazarken ters taksim yerine dz taksim iaretlerini kullanmak daha
doru olacaktr. Bu taksim tr hem Windowsta hem de GNU/Linuxta alr. Ancak eer
ters taksim iaretlerini kullanacaksanz, dosya yolu iindeki sinsi ka dizilerine kar dikkatli
olmalsnz:
>>> f = open('test\nisan.txt')

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument: 'test\nisan.txt'

Burada problemin nisan.txt adl dosyann ilk har ile, bundan nce gelen ters taksim
iaretinin birleerek tesadfen bir ka dizisi oluturmas olduunu biliyorsunuz. Bu tr
hatalara kar ters taksim yerine dz taksim iaretlerini kullanabileceiniz gibi r adl ka
dizisinden de yararlanabilirsiniz:
f = open(r'test\nisan.txt')

open() fonksiyonunun ikinci parametresi olan mode un da ne olduunu biliyorsunuz. Bu


parametre yardmyla, herhangi bir dosyay hangi kipte amak istediimizi belirtebiliyoruz.
Bildiiniz gibi, eer mode parametresine herhangi bir deer vermezseniz Python ilgili dosyay
okuma kipinde aacaktr.
Bu parametreye verebileceiniz deerleri yle zetleyebiliriz:
Karakter Anlam
r Okuma kipidir. ntanml deer budur.
w Yazma kipidir. Eer belirtilen adda dosya zaten varsa o dosya silinir.
x Yeni bir dosya oluturulup yazma kipinde alr.
a Dosya ekleme kipinde alr. Bu kip ile, varolan bir dosyann sonuna
eklemeler yaplabilir.
b Dosyalar ikili kipte amak iin kullanlr.
t Dosyalar metin kipinde amak iin kullanlr. ntanml deerdir.
+ Ayn dosya zerinde hem okuma hem de yazma ilemleri yaplmasn
salar.
open() fonksiyonunun alabilecei bir baka parametre de buffering parametresidir. Bildiiniz
gibi, open() fonksiyonuyla bir dosyay ap bu dosyaya veri girdiimizde bu veriler nce
tampona alnacak, dosya kapandktan sonra ise tamponda bekletilen veriler dosyaya
ilenecektir. te bu buffering parametresi yardmyla bu tampona alma ileminin nasl
yryeceini belirleyebiliriz.
Eer dosyaya ilenecek verilerin tampona alnmadan dorudan dosyaya ilenmesini
isterseniz buffering deerini 0 olarak belirlersiniz. Yalnz bu deer sadece ikili kipte
etkindir. Yani bir dosyay eer metin kipinde ayorsanz buffering parametresinin deerini 0
yapamazsnz.
Eer dosyaya veri ilerken tampona alnan verilerin satr satr dosyaya eklenmesini isterseniz
buffering deerini 1 olarak belirlersiniz. Bunun nasl altn anlamak iin u rnei
dikkatlice inceleyin:
>>> f = open('ni.txt', 'w', buffering=1)
>>> f.write('birinci satr\n')

580 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

14

>>> f.write('ikinci satr\n')

13

>>> f.write('aaa')

>>> f.write('\n')

Burada her write() komutundan sonra ni.txt adl dosyay ap bakarsanz, u durumu
grrsnz:
f.write(birinci satr\n) komutuyla dosyaya bir satrlk veri ekledik ve bu veri
dosyaya annda ilendi.
f.write(ikinci satr\n) komutuyla dosyaya bir satrlk baka bir veri daha ekledik
ve bu veri de dosyaya annda ilendi.
f.write(aaa) komutuyla eklenen veri satr deil. nk satr sonuna iaret eden satr
ba ka dizisini kullanmadk.
f.write(\n) komutuyla satr ba ka dizisini eklediimiz anda bir nceki karakter
dizisi (aaa) de dosyaya eklenecektir.
Ancak buffering parametresi bu 1 deerini yalnzca metin kipinde alabilir. Bu kstlamay da
aklmzn bir kenarna not edelim...
0 ve 1 dnda buffering parametresine 1den byk bir deer verdiinizde ise tampon
boyutunun ne kadar olacan kendiniz belirlemi olursunuz.
Yalnz ou durumda buffering parametresine herhangi bir zel deer atamanz
gerekmeyecektir. Bu parametreye herhangi bir deer atamadnzda, kullandnz iletim
sistemi tampona alma ilemlerininin nasl yrtleceine ve tampon boyutuna kendisi
karar verecektir. letim sisteminin sizin yerinize verdii bu karar da ounlukla istediiniz
ey olacaktr... Eer kendi sisteminizde ntanml tampon boyutunun ne olduunu merak
ediyorsanz u komutlar kullanabilirsiniz:
>>> import io
>>> io.DEFAULT_BUFFER_SIZE

ou sistemde bu deer 4096 ve 8192 bayt olacaktr.


open() fonksiyonunun alabilecei bir baka parametre de encoding parametresidir. Bu
parametre, dosyann hangi karakter kodlamas ile alacan belirler. rnein bir dosyay
UTF-8 karakter kodlamas ile amak iin u komutu kullanyoruz:
>>> f = open('dosya', encoding='utf-8')

zerinde ilem yaptnz dosyalarda zellikle Trke karakter sorunlar yaamak


istemiyorsanz, bir dosyay aarken mutlaka encoding parametresinin deerini de
ayarlamanz tavsiye ederim.

35.44. open() 581


Python 3 iin Trke Klavuz, Srm 3

Bir dosyay aarken veya okurken herhangi bir karakter kodlama hatas ile karlatnzda
Pythonn ne tepki vermesi gerektiini ise errors adl parametre yardmyla belirleyebilirsiniz.
Eer bu parametreye strict deerini verirseniz karakter kodlama hatalar programnzn
ValueError trnde bir hata vererek almay kesmesine neden olacaktr. Bu parametreye
herhangi bir deer vermediinizde de Python sanki strict deerini vermisiniz gibi davranr.
Eer errors parametresine ignore deerini verirseniz kodlama hatalar grmezden gelinecek,
bu hataya sebep olan karakter silinecektir. Yalnz bu deerin veri kaybna yol ama ihtimalini
de gz nnde bulundurmalsnz.
Eer errors parametresine replace deerini verirseniz kodlama hatasna yol aan karater ?
veya ufffd karakterleri ile deitirilecektir.
open() fonksiyonunun kabul ettii bir baka parametre de newline adl parametredir. Peki
bu parametre ne ie yarar?
Windows ve GNU/Linux iletim sistemleri satr sonlarn birbirlerinden farkl ekilde gsterir.
GNU/Linuxta yazlm dosyalarda satr sonlar \n karakteri ile gsterilirken, Windowsta
yazlm dosyalarda satr sonunda \r\n karakterleri bulunur. Eer Windows ve GNU/Linux
sistemleri arasnda dosya alverii yapyorsanz kimi durumlarda bu farkllk eitli sorunlarn
ortaya kmasna yol aabilir. te dosyalarnzn hangi satr sonu karakterine sahip olacan
yukarda bahsettiimiz newline adl parametre ile belirleyebilirsiniz. rnein:
>>> f = open('dosya', newline='\n')

Bu ekilde dosyanz hangi iletim sisteminde olursa olsun satr sonlarnda \n karakterine
sahip olacaktr.
Dosyalarn metotlarn incelerseniz o listede fileno() adl bir metodun olduunu
greceksiniz. Bu metot, bize bir dosyann dosya tanmlaycsn (le descriptor ) verir. Dosya
tanmlayclar, dosyaya iaret eden pozitif tam saylardr. 0, 1 ve 2 saylar standart girdi,
standart kt ve standart hata dosyalarna ayrlm olduu iin, sizin atnz ve zerinde
ilem yaptnz dosyalarn tanmlayclar 2 saysndan byk olacaktr.
Bir rnek verelim:
>>> f = open('ni.txt')
>>> f.fileno()

te burada grdnz say, ni.txt adl dosyann dosya tanmlaycsdr. Her dosyann dosya
tanmlaycs benzersizdir:
>>> g = open('zi.txt')
>>> g.fileno()

Pythonda bir dosyay open() fonksiyonuyla aarken dosya adn vermenin yansra, dosyann
tanmlaycsn da kullanabilirsiniz:
>>> z = open(4)

veya:

582 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

>>> z = open(g.fileno())

Bu sayede, eer isterseniz, elinizdeki dosyalarla daha ileri dzeyli ilemler yapabilirsiniz. Bir
rnek verelim.
Dediimiz gibi, bir dosyann tanmlaycs tek ve benzersizdir. Farkl dosyalar ayn
tanmlayclara sahip olmaz:
>>> a = open('aaa.txt')
>>> a.fileno()

>>> b = open('bbb.txt')
>>> b.fileno()

imdi u rneklere bakn:


>>> c = open(b.fileno(), closefd=False)

Bu ekilde b adl dosyann tanmlaycsn kullanarak, ayn dosyay bir de c adyla atk.
Ancak burada kullandmz closefd=False parametresine dikkat edin. Normalde dosyay
kapattmzda dosyann tanmlaycs serbest kalr ve baka bir dosya aldnda bu
tanmlayc yeni dosyaya atanr. Ama closefd parametresine False deeri verdiimizde dosya
kapansa bile, o dosyaya ait dosya tanmlaycs varolmaya devam edecektir.

35.45 pow()

Daha nceki derslerimizde pek ok kez rneklerini verdiimiz bu fonksiyon ngilizcedeki


power (kuvvet) kelimesinin ksaltmasndan oluur. Adnn anlamna uygun olarak, bu
fonksiyonu bir saynn kuvvetlerini hesaplamak iin kullanyoruz.
Bu fonksiyon en temel ekilde yle kullanlr:
>>> pow(2, 3)

Bu komutla 2 saysnn 3. kuvvetini hesaplam oluyoruz.


pow() fonksiyonu toplamda farkl parametre alr. lk iki parametrenin ne olduunu
yukarda rnekledik. nc parametre ise kuvvet hesaplamas sonucu elde edilen saynn
modlsn hesaplayabilmemizi salar. Yani:
>>> pow(2, 3, 2)

Burada yaptmz ey u: ncelikle 2 saysnn 3. kuvvetini hesapladk. Elde ettiimiz say


8. Ardndan da bu saynn 2 ye blnmesi ileminden kalan sayy elde ettik. Yani 0. nk
bildiiniz gibi 8 % 2 ileminin sonucu 0 dr. Dolaysyla yukardaki komut una edeerdir:

35.45. pow() 583


Python 3 iin Trke Klavuz, Srm 3

>>> (2 ** 3) % 2

Ancak nceki derslerimizde de sylediimiz gibi, pow() fonksiyonu ounlukla yanlzca ilk iki
parametresi ile birlikte kullanlr:
>>> pow(12, 2)

144

35.46 print()

print() fonksiyonunu artk gayet iyi tanyoruz. Bu fonksiyonu, bildiiniz gibi, kullanclarmza
birtakm mesajlar gstermek iin kullanyoruz.
Kullanmn daha nce ayrntl bir ekilde anlatm olduumuz bu fonksiyonu u ekilde
formle edebiliriz:
print(deg1, deg2, deg3, ..., sep=' ', end='\n', file=sys.stdout, flush=False)

Burada;
degx kt verilecek deerlerin ne olduunu belirtir. Buraya 256 adete
kadar deer yazabilirsiniz.
sep kt verilirken deerlerin arasna hangi karakterin yerletirileceini
belirtir. Bu deer ntanml olarak boluk karakteridir.
end kt verilecek son deerin ardndan hangi karakterin ilitirileceini
belirtir. Bu deer ntanml olarak satr ba (\n ) karakteridir.
le ktlarn hangi dosyaya yazlacan belirtir. ntanml olarak
bu parametrenin deeri sys.stdout tur. Yani print() fonksiyonu
ktlarn ntanml olarak standart kt konumuna gnderir.
ush Bildiiniz gibi, herhangi bir dosyaya yazma ilemi srasnda
dosyaya yazlacak deerler ncelikle tampona alnr. lem
tamamlandktan sonra tampondaki bu deerler topluca dosyaya
aktarlr. te bu parametre, deerleri tampona almadan dorudan
dosyaya gnderebilmemizi salar. Bu parametrenin ntanml
deeri False tur. Yani deerler dosyaya yazlmadan nce ntanml
olarak ncelikle tampona gider. Ama eer biz bu parametrenin
deerini True olarak deitirirsek, deerler dorudan dosyaya
yazlr.

35.47 quit()

Bu fonksiyonu programdan kmak iin kullanyoruz. Eer bu fonksiyonu etkileimli kabukta


verecek olursanz etkileimli kabuk kapanacaktr.

584 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

35.48 range()

Bu fonksiyonu belli bir aralktaki saylar listelemek iin kullanyoruz. Yani mesela 0 ile 10
aras saylarn listesini almak istersek yle bir komut yazabiliriz:
>>> l = range(0, 10)

Ancak burada dikkat etmemiz gereken bir zellik var: Bu fonksiyon aslnda dorudan
herhangi bir say listesi oluturmaz. Yukarda l deikenine atadmz komutu ekrana
yazdrrsak bunu daha net grebilirsiniz:
>>> print(l)

range(0, 10)

Bir de bu verinin tipine bakalm:


>>> type(l)

<class 'range'>

Grdnz gibi, elimizdeki ey aslnda bir say listesi deil, bir range (aralk) nesnesidir.
Biz bu nesneyi istersek baka veri tiplerine dntrebiliriz. Mesela bunu bir listeye
dntrelim:
>>> list(l)

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

veya bir demete:


>>> tuple(l)

(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

ya da bir kmeye veya dondurulmu kmeye:


>>> set(l) #kme

{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

>>> frozenset(l) #dondurulmu kme

frozenset({0, 1, 2, 3, 4, 5, 6, 7, 8, 9})

Bu range nesnesini istediiniz veri tipine dntrdkten sonra, dntrdnz veri


tipinin kurallar erevesinde elinizdeki veriyi ileyebilirsiniz.
range() fonksiyonundan elde ettiiniz range nesnesinin ieriini elde etmek iin bunu baka
bir veri tipine dntrmenin yansra, bu nesne zerinde bir for dngs de kurabilirsiniz:
>>> for i in range(10):
... print(i)
...
0
1
2

35.48. range() 585


Python 3 iin Trke Klavuz, Srm 3

3
4
5
6
7
8
9

Ya da yldzl parametreler yardmyla bu nesneyi print() fonksiyonuna gndererek, bu


nesneyi istediiniz gibi evirip evirebilirsiniz:
>>> print(*range(10), sep=', ')

0, 1, 2, 3, 4, 5, 6, 7, 8, 9

Esasnda, yukarda nasl kullanlacana dair baz rnekler verdiimiz bu range()


fonksiyonunu temel olarak u ekilde formle edebiliriz:
range(balang_deer, biti_deeri, atlama_deeri)

Aadaki rnei tekrar ele alalm:


>>> range(0, 10)

Burada 0 balang deeri, 10 ise biti deeridir. Buna gre oluturulacak saylar 0 ile 10
arasnda olacaktr. Yalnz burada retilecek say listesinde 0 saysnn dahil, 10 saysnn
ise hari olduunu unutmuyoruz. Yani bu komutun bize verecei ilk say 0 ; son say ise 9
olacaktr.
range() fonksiyonunda balang deerinin ntanml deeri 0 dr. Dolaysyla istersek biz
yukardaki komutu yle de yazabiliriz:
>>> range(10)

Bylece Python bizim range(0, 10) komutunu kastettiimizi varsayacaktr. Elbette eer
balang deerinin 0 dnda bir deer olmasn istiyorsanz bunu zellikle belirtmeniz
gerekir:
>>> range(10, 100)

Bu komut bize 10 ile (10 dahil) 100 aras (100 hari) saylar ieren bir range nesnesi
verecektir.
Yukarda verdiimiz formlden de greceiniz gibi, balang_deer ve biti_deer dnda
range() fonksiyonu nc bir parametre daha alabiliyor. Bu parametreye atlama_deeri
ad verdik. Bu parametreyi yle kullanyoruz:
>>> list(range(0, 10, 2))

[0, 2, 4, 6, 8]

Grdnz gibi, range() fonksiyonuna nc parametre olarak verdiimiz 2 says, 0 ile


10 aras saylarn ikier ikier atlanarak retilmesini salad.

586 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

35.49 reversed()

Diyelim ki elimizde yle bir liste var:


>>> isimler = ['ahmet', 'mehmet', 'veli', 'aye', 'idem', 'k']

Eer bu listedeki isimleri ters evirmek, yani yle bir liste elde etmek isterseniz:
['k', 'idem', 'aye', 'veli', 'mehmet', 'ahmet']

... ne yapmanz gerektiini biliyorsunuz. Bu ama iin liste dilimleme yntemlerinden


yararlanabilirsiniz:
>>> isimler[::-1]

['k', 'idem', 'aye', 'veli', 'mehmet', 'ahmet']

te ayn ilevi reversed() adl bir fonksiyon yardmyla da yerine getirebilirsiniz:


>>> reversed(isimler)

<list_reverseiterator object at 0x00EB9710>

Grdnz gibi, tpk range() fonksiyonunda olduu gibi, reversed() fonksiyonu da bize
rettii elerin kendisi yerine, bir nesne veriyor. Ama tabii ki bu bizim iin bir sorun deil.
Biz bu nesnenin ieriini nasl elde edebileceimizi gayet iyi biliyoruz:
>>> list(reversed(isimler))

['k', 'idem', 'aye', 'veli', 'mehmet', 'ahmet']

range() fonksiyonunu anlatrken szn ettiimiz ierik elde etme yntemlerini reversed()
fonksiyonuna da uygulayabilirsiniz.

35.50 sorted()

Bu metot, daha nceki derslerimizden de bildiiniz gibi, bir dizi iindeki eleri belirli bir
lte gre sraya dizmemizi salyor. Bununla ilgili ok basit bir rnek verelim:
>>> sorted('ahmet')

['a', 'e', 'h', 'm', 't']

Bu kodlar yardmyla ahmet adl karakter dizisi iindeki hareri alfabe srasna dizdik.
Elbette bu fonksiyonu sadece karakter dizileri zerine uygulamyoruz. sorted() adl
fonksiyon, dizi zellii tayan her trl nesne zerine uygulanabilir. Mesela demetlerin ve
listelerin bir dizi olduunu biliyoruz. Dolaysyla:
>>> sorted(('elma', 'armut', 'kiraz', 'badem'))

['armut', 'badem', 'elma', 'kiraz']

>>> sorted(['elma', 'armut', 'kiraz', 'badem'])


['armut', 'badem', 'elma', 'kiraz']

35.49. reversed() 587


Python 3 iin Trke Klavuz, Srm 3

sorted() fonksiyonuna hangi trde bir veri tipi verirseniz verin, aldnz kt her zaman bir
liste olacaktr. Bunu unutmayn.
Grdnz gibi, sorted() fonksiyonu nesneler zerinde bir sralama ilemi gerekletiriyor.
Ancak bu fonksiyonun bir problemi var.
Dikkatlice bakn:
>>> isimler = ['ahmet', 'idem', 'k', 'ebnem', 'zeynep', 'selin']
>>> sorted(isimler)

['ahmet', 'selin', 'zeynep', 'idem', 'k', 'ebnem']

Bu fonksiyon, Trke karakter ieren eleri dzgn sralayamaz.


Bu sorunu ksmen zebilmek iin locale adl bir modl iindeki strxfrm() adl bir
fonksiyondan yararlanabilirsiniz:
>>> import locale

Henz modlleri renmemi de olsak, bir modl kullanabilmek iin ncelikle o modl
ie aktarmamz gerektiini artk biliyorsunuz. Bu ilemi import adl bir komut yardmyla
yaptmz da biliyorsunuz.
imdi de yerelimizi (locale ) Trke olarak ayarlayalm:
>>> locale.setlocale(locale.LC_ALL, 'tr_TR') #GNU/Linux
>>> locale.setlocale(locale.LC_ALL, 'Turkish_Turkey.1254') #Windows

Bu ilemleri yaptktan sonra, sorted() fonksiyonunun key adl bir parametresini kullanarak
ve yine locale modlnn strxfrm() adl fonksiyonundan faydalanarak Trke karakterler
ieren listemizi sralamay deneyebiliriz:
>>> sorted(isimler, key=locale.strxfrm)

['ahmet', 'idem', 'k', 'selin', 'ebnem', 'zeynep']

locale modl iinde bulunan strxfrm() adl fonksiyon, karakter dizilerinin, o anda etkin
yerel neyse, ona gre muamele grmesini salar. Biz yukarda yerelimizi Trke olarak
ayarladmz iin strxfrm() fonksiyonu, sorted() ile yaplan alfabe srasna dizme ileminin
Trkenin kurallarna gre yaplmasn salyor.
Ancak bu yntemin de sorunlu olduunu bir sre sonra kendiniz de farkedeceksiniz. Mesela
u rnei inceleyin:
>>> sorted('afgdhki', key=locale.strxfrm)

['a', 'd', 'f', 'g', 'h', 'i', '', 'k']

Grdnz gibi, listede i har harnden nce geliyor. Ama aslnda bunun tersi olmalyd.
te byle bir durumda, kendi sralama mekanizmamz kendimiz icat etmeliyiz. Peki ama
nasl?
Bilgisayarlar farkl dillerdeki karakterleri her zaman doru sralayamasa da, saylar her zaman
doru sralar:

588 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

>>> sorted([10, 9, 4, 14, 20])

[4, 9, 10, 14, 20]

Bilgisayarlarn bu zelliinden ve Pythondaki szlk veri tipinden yararlanarak kendi sralama


mekanizmamz rahatlkla icat edebiliriz.
ncelikle harerimizi yazalm:
>>> harfler = "abcdefghijklmnoprstuvyz"

Burada Trk alfabesini oluturan hareri srasna gre dizdik. imdi bu harerin her birine
bir say vereceiz:
>>> evrim = {'a': 0, 'b': 1, 'c': 2, '': 3, 'd': 4,
... 'e': 5, 'f': 6, 'g': 7, '': 8, 'h': 9,
... '': 10, 'i': 11, 'j': 12, 'k': 13,
... 'l': 14, 'm': 15, 'n': 16, 'o': 17,
... '': 18, 'p': 19, 'r': 20, 's': 21,
... '': 22, 't': 23, 'u': 24, '': 25,
... 'v': 26, 'y': 27, 'z': 28}

Yalnz byle her harfe karlk gelen sayy elle yazmak yorucu olacaktr. Bu ilemi daha kolay
bir ekilde yapabilmek iin farkl teknikleri kullanabilirsiniz. Mesela daha nce rendiimiz
szlk retelerinden yararlanabilirsiniz:
>>> evrim = {i: harfler.index(i) for i in harfler}

Bu ekilde harer deikeni iindeki herbir harn bir anahtar; bu harerin harer deikeni
iindeki srasn gsteren herbir saynn ise bir deer olduu bir szlk oluturmu olduk.
imdi isim listemizi alalm karmza:
isimler = ["ahmet", "k", "ismail",
"idem", "can", "ule"]

Normal bir sorted() ileminin yanl sonu dndreceini biliyoruz:


>>> sorted(isimler)

['ahmet', 'can', 'ismail',


'idem', 'k', 'ule']

Ayn ekilde key parametresine locale.strxfrm deerinin verilmesi de yetersiz kalacaktr:


>>> sorted(isimler, key=locale.strxfrm)

['ahmet', 'can', 'idem', 'ismail',


'k', 'ule']

Ama biraz nce oluturduumuz evrim anahtarn kullanrsak durum bambaka olacaktr:
>>> sorted(isimler, key=lambda x: evrim.get(x[0]))

['ahmet', 'can', 'idem', 'k', 'ismail', 'ule']

Ancak aslnda burada da olduka sinsi bir problem var. Bu metot ile kelime listesini oluturan
kelimeleri yalnzca ilk harerine gre sralyoruz (x[0]). Peki ya ayn liste iinde ilk hareri

35.50. sorted() 589


Python 3 iin Trke Klavuz, Srm 3

ayn olup, sonraki harerde farkllaan kelimeler varsa ne olacak? Yani mesela bu metot
acaba ismail ve iskender kelimelerini doru bir ekilde sralayabilir mi? Bakalm:
harfler = "abcdefghijklmnoprstuvyz"
evrim = {i: harfler.index(i) for i in harfler}

isimler = ["ahmet", "k", "ismail", "idem",


"can", "ule", "iskender"]

print(sorted(isimler, key=lambda x: evrim.get(x[0])))

Buradan u kty alyoruz:


['ahmet', 'can', 'idem', 'k', 'ismail', 'iskender', 'ule']

Grdnz gibi ismail ve iskender kelimeleri doru bir ekilde sralanmad; iskender
kelimesinin ismail kelimesinden nce gelmesi gerekiyordu...
Demek ki imdiye kadar kullandmz btn sralama yntemlerinin bir eksii varm. O
halde baka bir metot bulmaya alalm.
Dikkatlice bakn:
harfler = 'abcdefghijklmnoprstuvyz'
evrim = {i: harfler.index(i) for i in harfler}

def srala(kelime):
return ([evrim.get(kelime[i]) for i in range(len(kelime))])

isimler = ['ahmet', 'can', 'iskender', 'cigdem',


'ismet', 'ismail', 'ismit', 'idem',
'ismt', 'k', 'ule']

print(*sorted(isimler, key=srala), sep='\n')

Gelin bu kodlar biraz inceleyelim.


Burada ilk grdmz kodlar unlar:
harfler = 'abcdefghijklmnoprstuvyz'
evrim = {i: harfler.index(i) for i in harfler}

Esasnda siz bu kodlarn anlamn biliyorsunuz. nceki derslerimizde de ayn kodlar


birka kez kullanmtk. Yalnz biz burada, rnek olmas asndan, harer deikeni iin
deer olarak yalnzca kk hareri kullandk. Bu kodlar daha kapsaml bir program
iinde kullanacaksanz bu deikenin uygun yerlerine mesela byk hareri ve noktalama
iaretleriyle saylar da eklemek isteyebilirsiniz.
Sonraki satrlarda srala() adl bir fonksiyon tanmladk:
def srala(kelime):
return ([evrim.get(kelime[i]) for i in range(len(kelime))])

Burada liste retelerinden yararlandmza dikkatinizi ekmek isterim:


[evrim.get(kelime[i]) for i in range(len(kelime))]

Bu kod yardmyla kelime iinde geen herbir har evrim adl szlkte sorgulayarak, szlkte
ilgili harfe karlk gelen sayy buluyoruz.

590 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Aslnda bu kodlar daha iyi anlayabilmek iin Pythondaki sorted() fonksiyonunun mantn
biraz daha derinlemesine incelememiz gerekiyor. Gelin imdi bu inceleme iini yapalm:
Diyelim ki elimizde yle bir liste var:
elemanlar = [('ahmet', 33, 'karata'),
('mehmet', 45, 'arpabahi'),
('sevda', 24, 'arsuz'),
('arzu', 40, 'siverek'),
('abdullah', 30, 'payas'),
('ilknur', 40, 'kilis'),
('abdurrezzak', 40, 'bolvadin')]

Bu liste, her biri isim, ya ve memleket bilgilerini ieren eli birer demetten oluuyor.
Eer biz bu liste zerine sorted() fonksiyonunu uygularsak:
print(*sorted(elemanlar), sep='\n')

Python elemanlar demetlerin ilk esine gre sralayacaktr. Yani isme gre.
Peki ya biz bu elemanlar yaa gre sralamak istersek ne yapacaz?
Bu amac gerekletirmek iin yle bir kod yazabiliriz:
def srala(liste):
return liste[1]

elemanlar = [('ahmet', 33, 'karata'),


('mehmet', 45, 'arpabahi'),
('sevda', 24, 'arsuz'),
('arzu', 40, 'siverek'),
('abdullah', 30, 'payas'),
('ilknur', 40, 'kilis'),
('abdurrezzak', 40, 'bolvadin')]

print(*sorted(elemanlar, key=srala), sep='\n')

Bu rnek bize key parametresinin de ne ie yaradn ak seik gsteriyor. Eer Pythonn


kendi sralama ynteminin dnda bir sralama yntemi uygulayacaksak, bu sralama
ynteminin ne olduunu bir fonksiyon yardmyla tarif edip bunu key parametresine deer
olarak veriyoruz. rnein biz yukardaki Pythonn elemanlar adl listeyi ilk stuna (isim
stunu) gre deil, ikinci stuna (ya stunu) gre sralamasn istedik. Bunun iin de yle
bir fonksiyon yazdk:
def srala(liste):
return liste[1]

Bu fonksiyon, kendisine parametre olarak verilen nesnenin ikinci esini dndryor. te


biz sorted() fonksiyonunun key parametresine bu fonksiyonu verdiimizde Python sralama
ileminde elemanlar listesinin ikinci esini dikkate alacaktr. Eer Pythonn sralama
ileminde mesela nc stunu dikkate almasn isterseniz srala() fonksiyonunu yle
yazabilirsiniz:
def srala(liste):
return liste[2]

Grdnz gibi, elemanlar listesinin ikinci stununda deeri ayn olan eler var. Mesela
arzu, ilknur ve abdurrezzak 40 yanda. Python bu eleri sralarken, bunlarn listede

35.50. sorted() 591


Python 3 iin Trke Klavuz, Srm 3

getii sray dikkate alacaktr. Ama bazen biz sralamann byle olmasn istemeyebiliriz.
Mesela bizim istediimiz ey, deeri ayn olan eler iin nc stunun (veya birinci
stunun) dikkate alnmas olabilir. te bunun iin de srala() fonksiyonunu u ekilde
tanmlayabiliriz:
def srala(liste):
return (liste[1], liste[2])

Grdnz gibi burada srala() fonksiyonu bize iki eli bir demet dndryor.
Kodlarmz tam olarak yle grnecek:
def srala(liste):
return (liste[1], liste[2])

elemanlar = [('ahmet', 33, 'karata'),


('mehmet', 45, 'arpabahi'),
('sevda', 24, 'arsuz'),
('arzu', 40, 'siverek'),
('abdullah', 30, 'payas'),
('ilknur', 40, 'kilis'),
('abdurrezzak', 40, 'bolvadin')]

print(*sorted(elemanlar, key=srala), sep='\n')

Kodlarmz byle yazdmzda Python listeyi ilk olarak ikinci stundaki ya deerlerine gre
sralar. Deeri ayn olan elerle karlatnda ise nc stundaki memleket deerlerine
bakar ve sralamay ona gre yapar.
Btn bu aklamalardan sonra yukardaki u kodlar daha iyi anlyor olmalsnz:
harfler = 'abcdefghijklmnoprstuvyz'
evrim = {i: harfler.index(i) for i in harfler}

def srala(kelime):
return ([evrim.get(kelime[i]) for i in range(len(kelime))])

isimler = ['ahmet', 'can', 'iskender', 'cigdem',


'ismet', 'ismail', 'ismit', 'idem',
'ismt', 'k', 'ule']

print(*sorted(isimler, key=srala), sep='\n')

Biz yine de her eyin iyiden iyine anlaldndan emin olmak iin durumu ksaca aklayalm.
ncelikle ilgili fonksiyonu nmze alalm:
def srala(kelime):
return ([evrim.get(kelime[i]) for i in range(len(kelime))])

Burada yaptmz ey biraz nce yaptmz eyle tamamen ayn aslnda. Tek fark, Pythonn
sralamada kullanmasn istediimiz eleri tek tek elle yazmak yerine, bunlar bir liste reteci
yardmyla otomatik olarak belirlemek.
Eer yukardaki kodlar yle yazsaydk:
def srala(kelime):
return (evrim.get(kelime[0]))

592 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Bu durumda Python sralamada kelimelerin yalnzca ilk harerini dikkate alacakt. lk har
ayn olan kelimeleri ise bu yzden dzgn sralayamayacakt. Elbette Pythonn nce ilk harfe,
sonra ikinci harfe, sonra da nc harfe bakmasn salayabiliriz:
def srala(kelime):
return (evrim.get(kelime[0]), evrim.get(kelime[1]), evrim.get(kelime[2]))

Ancak bu yntemin uygulanabilir ve pratik olmad ortada. Kendi kendinize baz denemeler
yaparak bunu kendiniz de rahatlkla grebilirsiniz.
Pythonn, sralama yaparken kelimelerin nce ilk harerini, sonra ikinci, sonra nc, vb.
harerini karlatrmasn salamann en uygun yolu u olacaktr:
def srala(kelime):
return ([evrim.get(kelime[i]) for i in range(len(kelime))])

Grdnz gibi, burada kelimelerdeki harerin srasn tek tek elle yazmak yerine, bunu
bir for dngs iinde otomatik olarak yaptryoruz. Dolaysyla srala() fonksiyonuna
verilen parametrenin mesela ahmet olduu bir durumda yukardaki fonksiyon u demeti
dndryor:
def srala('ahmet'):
return (evrim.get('ahmet'[0]),
evrim.get('ahmet'[1]),
evrim.get('ahmet'[2]),
evrim.get('ahmet'[3]),
evrim.get('ahmet'[4]))

Mesela can iin ise unu:


def srala('can'):
return (evrim.get('can'[0]),
evrim.get('can'[1]),
evrim.get('can'[2]))

Bylece Python, hangi uzunlukta bir isimle karlarsa karlasn, sralama ilemini dzgn
bir ekilde gerekletirebiliyor.
Bu blmde Pythonda sralama konusunu epey ayrntl bir ekilde ele aldk.

Not: Sralama konusuna ilikin bir tartma iin http://www.istihza.com/forum/viewtopic.php?f=25&t=1523


adresindeki konuyu inceleyebilirsiniz.

35.51 slice()

Bildiiniz gibi, birtakm elerden oluan bir nesnenin yalnzca belli ksmlarn ayrp alma
ilemine dilimleme ad veriliyor. rnein elimizde yle bir liste olduunu dnelim:
>>> l = ['ahmet', 'mehmet', 'aye', 'senem', 'salih']

5 eli bu listenin yalnzca ilk iki esini almak, yani dilimlemek iin u yapy kullanyoruz:
>>> l[0:2]

['ahmet', 'mehmet']

35.51. slice() 593


Python 3 iin Trke Klavuz, Srm 3

Dilimleme ileminin yle bir formlden olutuunu biliyoruz:


l[balang:biti:atlama_deeri]

Balang parametresinin ntanml deeri 0 olduu iin yukardaki kodu yle de


yazabilirdik:
>>> l[:2]

['ahmet', 'mehmet']

Ayn listenin, ilk eden itibaren sonuna kadar olan btn elerini almak iin ise unu
yazyoruz:
>>> l[1:]

Eer bu listeyi, elerini ikier ikier atlayarak dilimlemek istersek de u yolu takip ediyoruz:
>>> l[::2]

['ahmet', 'aye', 'salih']

Bu rnekte balang ve biti parametrelerinin ntanml deerlerini kullandk. O yzden o


ksmlar bo braktk. eleri ikier ikier atlayabilmek iin ise atlama_deeri olarak 2 saysn
kullandk.
te yukardakine benzer dilimleme ilemleri iin slice() adl bir gml fonksiyondan da
yararlanabiliriz. Dikkatlice bakn:
Listemiz u:
>>> l = ['ahmet', 'mehmet', 'aye', 'senem', 'salih']

Bir dilimleme (slice ) nesnesi oluturuyoruz:


>>> dl = slice(0, 3)

Bu nesneyi liste zerine uyguluyoruz:


>>> l[dl]

['ahmet', 'mehmet', 'aye']

Grdnz gibi, slice() fonksiyonunu yukarda iki parametre ile kullandk. Tahmin
edebileceiniz gibi, bu fonksiyonunu forml u ekildedir:
slice(balang, biti, atlama)

35.52 sum()

Bu fonksiyonun temel grevi, bir dizi iindeki deerlerin toplamn bulmaktr. rnein:
>>> l = [1, 2, 3]
>>> sum(l)

594 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Bu fonksiyon genellikle yukardaki gibi tek parametreyle kullanlr. Ama aslnda bu fonksiyon
ikinci bir parametre daha alr. Dikkatlice bakn:
>>> l = [1, 2, 3]
>>> sum(l, 10)

16

Grdnz gibi, Python sum() fonksiyonuna verilen ikinci parametreyi, birinci


parametredeki toplam deerin zerine ekliyor.

35.53 type()

type() fonksiyonunun grevi bir nesnenin hangi veri tipine ait olduunu sylemektir. Bu
fonksiyonu artk yakndan tanyorsunuz:
>>> type('elma')

<class 'str'>

35.54 zip()

Gelin isterseniz bu fonksiyonu bir rnek zerinden aklamaya alalm.


Diyelim ki elimizde yle iki farkl liste var:
>>> a1 = ['a', 'b', 'c']
>>> a2 = ['d', 'e', 'f']

Eer bu listelerin elerini birbirleriyle eletirmek istersek zip() fonksiyonundan


yararlanabiliriz.
Dikkatlice bakn:
>>> zip(a1, a2)

<zip object at 0x00FD0BE8>

Grdnz gibi, yukardaki kod bize bir zip nesnesi veriyor. Bu nesnenin elerine nasl
ulaabileceinizi biliyorsunuz:
>>> print(*zip(a1, a2))

('a', 'd') ('b', 'e') ('c', 'f')

>>> list(zip(a1, a2))

[('a', 'd'), ('b', 'e'), ('c', 'f')]

>>> for a, b in zip(a1, a2):


... print(a, b)
...
a d
b e
c f

35.53. type() 595


Python 3 iin Trke Klavuz, Srm 3

Yukardaki ktlar incelediimizde, ilk listenin ilk esinin, ikinci listenin ilk esiyle; ilk
listenin ikinci esinin, ikinci listenin ikinci esiyle; ilk listenin nc esinin ise, ikinci
listenin nc esiyle eletiini gryoruz.
Bu zellikten pek ok farkl ekilde yararlanabilirsiniz. rnein:
>>> isimler = ['ahmet', 'mehmet', 'zeynep', 'ilker']
>>> yalar = [25, 40, 35, 20]
>>> for i, y in zip(isimler, yalar):
... print('isim: {} / ya: {}'.format(i, y))
...
isim: ahmet / ya: 25
isim: mehmet / ya: 40
isim: zeynep / ya: 35
isim: ilker / ya: 20

Burada isimler ve yalar adl listelerin elerini zip() fonksiyonu yardmyla birbirleriyle
eletirdik.

35.55 vars()

Bu fonksiyon, mevcut isim alan iindeki metot, fonksiyon ve nitelikleri listeler. Eer bu
fonksiyonu parametresiz olarak kullanrsak, daha nce grdmz locals() fonksiyonuyla
ayn kty elde ederiz:
>>> vars()

{'__builtins__': <module 'builtins' (built-in)>, '__name__': '__main__',


'__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>,
'__doc__': None}

Bu fonksiyonu, nesnelerin metotlarn ve niteliklerini renmek iin de kullanabilirsiniz:


>>> vars(str)
>>> vars(list)
>>> vars(dict)

Yukarda srasyla karakter dizilerinin, listelerin ve szlklerin metotlarn listeledik. Bu


ynyle vars() fonksiyonu dir() fonksiyonuna benzer.
Bylece Pythondaki gml fonksiyonlar tek tek incelemi olduk. Bu blmde
incelemediimiz gml fonksiyonlar unlar:
1. memoryview()
2. iter()
3. next()
4. object()
5. property()
6. staticmethod()
7. super()
8. getattr()

596 Blm 35. Gml Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

9. hasattr()
10. delattr()
11. classmethod()
12. issubclass()
13. setattr()
14. __import()
Bu fonksiyonlar, ilerleyen derslerle birlikte Python bilgimiz biraz daha arttnda ele alacaz.

35.55. vars() 597


BLM 36

leri Dzey Fonksiyonlar

Buraya gelinceye kadar fonksiyonlara ilikin epey sz syledik. Artk Python programlama
dilinde fonksiyonlara dair hemen her eyi bildiimizi rahatlkla syleyebiliriz. Zira bu noktaya
kadar hem fonksiyonlarn temel (ve orta dzey) zelliklerini rendik, hem de gml
fonksiyon kavramn ve gml fonksiyonlarn kendisini btn ayrntlaryla inceledik.
Dolaysyla yazdmz kodlarda fonksiyonlar olduka verimli bir ekilde kullanabilecek kadar
fonksiyon bilgisine sahibiz artk.
Dediimiz gibi, fonksiyonlara ilikin en temel bilgileri edindik. Ancak fonksiyonlara dair
henz bilmediimiz eyler de var. Ama artk Python programlama dilinde geldiimiz aamay
dikkate alarak ileriye doru bir adm daha atabilir, fonksiyonlara dair ileri dzey saylabilecek
konulardan da sz edebiliriz.
lk olarak lambda fonksiyonlarn ele alalm.

36.1 Lambda Fonksiyonlar

imdiye kadar Python programlama dilinde fonksiyon tanmlamak iin hep def adl
bir ifadeden yararlanmtk. Bu blmde ise Python programlama dilinde fonksiyon
tanmlamamz salayacak, tpk def gibi bir ifadeden daha sz edeceiz. Fonksiyon
tanmlamamz salayan bu yeni ifadeye lambda denir. Bu ifade ile oluturulan fonksiyonlara
ise lambda fonksiyonlar...
Bildiiniz gibi Pythonda bir fonksiyonu def ifadesi yardmyla yle tanmlyoruz:
>>> def fonk(param1, param2):
... return param1 + param2

Bu fonksiyon, kendisine verilen parametreleri birbiriyle toplayp bize bunlarn toplamn


dndryor:
>>> fonk(2, 4)

Peki ayn ilemi lambda fonksiyonlar yardmyla yapmak istersek nasl bir yol izleyeceiz?
Dikkatlice bakn:
>>> fonk = lambda param1, param2: param1 + param2

598
Python 3 iin Trke Klavuz, Srm 3

te burada tanmladmz ey bir lambda fonksiyonudur. Bu lambda fonksiyonunu da tpk


biraz nce tanmladmz def fonksiyonu gibi kullanabiliriz:
>>> fonk(2, 4)

Grdnz gibi lambda fonksiyonlarn tanmlamak ve kullanmak hi de zor deil.


Lambda fonksiyonlarnn neye benzediinden temel olarak bahsettiimize gre artk biraz
daha derine inebiliriz.
Lambda fonksiyonlar Python programlama dilinin ileri dzey fonksiyonlarndan biridir.
Yukardaki rnek yardmyla bu lambda fonksiyonlarnn nasl bir ey olduunu grdk.
Esasnda biz buraya gelene kadar bu lambda fonksiyonlarn hi grmemi de deiliz.
Hatrlarsanz daha nceki derslerimizde yle bir rnek kod yazmtk:
harfler = "abcdefghijklmnoprstuvyz"
evrim = {i: harfler.index(i) for i in harfler}

isimler = ["ahmet", "k", "ismail", "idem",


"can", "ule", "iskender"]

print(sorted(isimler, key=lambda x: evrim.get(x[0])))

Burada sorted() fonksiyonunun key parametresi iinde kullandmz ifade bir lambda
fonksiyonudur:
lambda x: evrim.get(x[0])

Peki lambda fonksiyonlar nedir ve ne ie yarar?


Lambda fonksiyonlarn, bir fonksiyonun ilevselliine ihtiya duyduumuz, ama konum
olarak bir fonksiyon tanmlayamayacamz veya fonksiyon tanmlamann zor ya da
meakkatli olduu durumlarda kullanabiliriz. Yukardaki rnek kod, bu tanma iyi bir rnektir:
sorted() fonksiyonunun key parametresi bizden bir fonksiyon tanm bekler. Ancak biz
elbette oraya def ifadesini kullanarak dorudan bir fonksiyon tanmlayamayz. Ama def
yerine lambda ifadesi yardmyla key parametresi iin bir lambda fonksiyonu tanmlayabiliriz.
Eer yukardaki kodlar normal bir fonksiyonla yazmak isteseydik u kodlar kullanabilirdik:
harfler = "abcdefghijklmnoprstuvyz"
evrim = {i: harfler.index(i) for i in harfler}

isimler = ["ahmet", "k", "ismail", "idem",


"can", "ule", "iskender"]

def srala(eleman):
return evrim.get(eleman[0])

print(sorted(isimler, key=srala))

Burada lambda fonksiyonu kullanmak yerine, srala() adl bir fonksiyon kullandk.
Eer yukarda lambda ile yazdmz rnei srala() fonksiyonu ile yazdmz rnekle
kyaslarsanz lambda fonksiyonlarnda hangi parann neye karlk geldiini veya ne anlama
sahip olduunu rahatlkla anlayabilirsiniz.
Gelin bir rnek daha verelim:

36.1. Lambda Fonksiyonlar 599


Python 3 iin Trke Klavuz, Srm 3

Diyelim ki bir saynn ift say olup olmadn denetleyen bir fonksiyon yazmak istiyorsunuz.
Bunun iin yle bir fonksiyon tanmlayabileceimizi biliyorsunuz:
def ift_mi(say):
return say % 2 == 0

Eer ift_mi() fonksiyonuna parametre olarak verilen bir say ift ise fonksiyonumuz True
kts verecektir:
print(ift_mi(100))

True

Aksi halde False kts alrz:


print(ift_mi(99))

False

te yukardaki etkiyi lambda fonksiyonlar yardmyla da elde edebiliriz.


Dikkatlice bakn:
>>> ift_mi = lambda say: say % 2 == 0
>>> ift_mi(100)

True

>>> ift_mi(99)

False

Baka bir rnek daha verelim. Diyelim ki bir liste iindeki btn saylarn karesini hesaplamak
istiyoruz. Elimizdeki liste u:
>>> l = [2, 5, 10, 23, 3, 6]

Bu listedeki saylarn her birinin karesini hesaplamak iin yle bir ey yazabiliriz:
>>> for i in l:
... print(i**2)

4
25
100
529
9
36

Veya yle bir ey:


>>> [i**2 for i in l]

[4, 25, 100, 529, 9, 36]

Ya da map() fonksiyonuyla birlikte lambday kullanarak u kodu yazabiliriz:


>>> print(*map(lambda say: say ** 2, l))

4 25 100 529 9 36

600 Blm 36. leri Dzey Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Son rnekte verdiimiz lambdal kodu normal bir fonksiyon tanmlayarak yle de
yazabilirdik:
>>> def karesi(say):
... return say ** 2
...
>>> print(*map(karesi, l))

4 25 100 529 9 36

Szn z, mesela u kod:


lambda x: x + 10

Trkede u anlama gelir:


'x' adl bir parametre alan bir lambda fonksiyonu tanmla. Bu fonksiyon, bu
'x parametresine 10 saysn eklesin.

Biz yukardaki rneklerde lambda fonksiyonunu tek bir parametre ile tanmladk. Ama elbette
lambda fonksiyonlarnn birden fazla parametre de alabileceini de biliyorsunuz.
rnein:
>>> birletir = lambda ifade, birletirici: birletirici.join(ifade.split())

Burada lambda fonksiyonumuz toplam iki farkl parametre alyor: Bunlardan ilki ifade,
ikincisi ise birletirici. Fonksiyonumuzun gvdesinde ifade parametresine split() metodunu
uyguladktan sonra, elde ettiimiz paralar birletirici parametresinin deerini kullanarak
birbirleriyle birletiriyoruz. Yani:
>>> birletir('istanbul bykehir belediyesi', '-')

'istanbul-bykehir-belediyesi'

Eer ayn ilevi normal bir fonksiyon yardmyla elde etmek isteseydik yle bir ey
yazabilirdik:
>>> def birletir(ifade, birletirici):
... return birletirici.join(ifade.split())
...
>>> birletir('istanbul bykehir belediyesi', '-')

'istanbul-bykehir-belediyesi'

Yukardaki rneklerin dnda, lambda fonksiyonlar zellikle grak arayz almalar


yaparken iinize yarayabilir. rnein:
import tkinter
import tkinter.ttk as ttk

pen = tkinter.Tk()

btn = ttk.Button(text='merhaba', command=lambda: print('merhaba'))


btn.pack(padx=20, pady=20)

pen.mainloop()

36.1. Lambda Fonksiyonlar 601


Python 3 iin Trke Klavuz, Srm 3

Not: Bu kodlardan hibir ey anlamam olabilirsiniz. Endie etmeyin. Burada amacmz


size sadece lambda fonksiyonlarnn kullanmn gstermek. Bu kodlarda yalnzca lambda
fonksiyonuna odaklanmanz imdilik yeterli olacaktr. Eer bu kodlar altramadysanz
http://www.istihza.com/forum adresinde sorununuzu dile getirebilirsiniz.

Bu kodlar altrp deneme dmesine bastnzda komut satrnda merhaba kts


grnecektir. Tkinterde fonksiyonlarn command parametresi bizden parametresiz bir
fonksiyon girmemizi bekler. Ancak bazen, elde etmek istediimiz ilevsellik iin oraya
parametreli bir fonksiyon yazmak durumunda kalabiliriz. te bunun gibi durumlarda lambda
fonksiyonlar faydal olabilir. Elbette yukardaki kodlar yle de yazabilirdik:
import tkinter
import tkinter.ttk as ttk

pen = tkinter.Tk()

def merhaba():
print('merhaba')

btn = ttk.Button(text='merhaba', command=merhaba)


btn.pack(padx=20, pady=20)

pen.mainloop()

Burada da lambda yerine isimli bir fonksiyon tanmlayp, command parametresine dorudan
bu fonksiyonu verdik.
Btn bu rneklerden grdnz gibi, lambda fonksiyonlar son derece pratik aralardr.
Normal, isimli fonksiyonlarla elde ettiimiz ilevsellii, lambda fonksiyonlar yardmyla ok
daha ksa bir ekilde elde edebiliriz. Ancak lambda fonksiyonlar normal fonksiyonlara gre
biraz daha okunaksz yaplardr. O yzden, eer lambda fonksiyonlarn kullanmaya mecbur
deilseniz, bunlarn yerine normal fonksiyonlar veya yerine gre liste retelerini tercih
edebilirsiniz.

36.2 zyinelemeli (Recursive ) Fonksiyonlar

Bu blmde, lambda fonksiyonlarnn ardndan, yine Pythonn ileri dzey konularndan


biri olan zyinelemeli fonksiyonlardan sz edeceiz. ngilizcede recursive functions olarak
adlandrlan zyinelemeli fonksiyonlarn, Python programlama dilinin anlamas en zor
konularndan biri olduu sylenir. Ama bu sylenti sizi hi endielendirmesin. Zira biz
burada bu aprak grnen konuyu size olabildiince basit ve anlalr bir ekilde sunmak
iin elimizden gelen btn abay gstereceiz.
O halde hemen balayalm...
imdiye kadar Pythonda pek ok fonksiyon grdk. Bu fonksiyonlar kimi zaman Python
programclarnca tanmlanp dile entegre edilmi gml fonksiyonlar (builtin functions )
olarak, kimi zamansa o anda iinde bulunduumuz duruma ve ihtiyalarmza gre bizzat
kendimizin tanmlad el yapm fonksiyonlar (custom functions ) olarak kt karmza.
imdiye kadar rendiimiz btn bu fonksiyonlarn ortak bir noktas vard. Bu ortak
nokta, u ana kadar fonksiyonlar kullanarak yaptmz rneklerden de grdnz gibi, bu
fonksiyonlar yardmyla baka fonksiyonlar arabiliyor olmamz. rnein:

602 Blm 36. leri Dzey Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

def selamla(kim):
print('merhaba', kim)

Burada selamla() adl bir fonksiyon tanmladk. Grdnz gibi bu fonksiyon print() adl
baka bir fonksiyonu aryor. Burada srad bir ey yok. Dediimiz gibi, imdiye kadar
zaten hep byle fonksiyonlar grmtk.
Python fonksiyonlar, yukardaki rnekte de grdnz gibi, nasl baka fonksiyonlar
arabiliyorsa, ayn ekilde, istenirse, kendi kendilerini de arabilirler. te bu tr
fonksiyonlara Python programlama dilinde kendi kendilerini yineleyen, veya daha teknik bir
dille ifade etmek gerekirse zyinelemeli (recursive ) fonksiyonlar ad verilir.
ok basit bir rnek verelim. Diyelim ki, kendisine parametre olarak verilen bir karakter dizisi
iindeki karakterleri teker teker azaltarak ekrana basan bir fonksiyon yazmak istiyorsunuz.
Yani mesela elinizde istihza adl bir karakter dizisi var. Sizin amacnz bu karakter dizisini u
ekilde basan bir fonksiyon yazmak:
istihza
stihza
tihza
ihza
hza
za
a

Elbette bu ii yapacak bir fonksiyonu, daha nce rendiiniz dngler ve baka yaplar
yardmyla rahatlkla yazabilirsiniz. Ama isterseniz ayn ii zyinelemeli fonksiyonlar
yardmyla da yapabilirsiniz.
imdi u kodlara dikkatlice bakn:
def azalt(s):
if len(s) < 1:
return s
else:
print(s)
return azalt(s[1:])

print(azalt('istihza'))

Bu kodlar bize yukarda bahsettiimiz kty verecek:


istihza
stihza
tihza
ihza
hza
za
a

Fonksiyonumuzu yazp altrdmza ve bu fonksiyonun bize nasl bir kt verdiini


grdmze gre fonksiyonu aklamaya geebiliriz.
Bu fonksiyon ilk bakta daha nce rendiimiz fonksiyonlardan ok da farkl grnmyor
aslnda. Ama eer fonksiyonun son ksmna bakacak olursanz, bu fonksiyonu daha nce
rendiimiz fonksiyonlardan ayran u satr grrsnz:

36.2. zyinelemeli (Recursive ) Fonksiyonlar 603


Python 3 iin Trke Klavuz, Srm 3

return azalt(s[1:])

Grdnz gibi, burada azalt() fonksiyonu iinde yine azalt() fonksiyonunu aryoruz.
Bylece fonksiyonumuz srekli olarak kendi kendini yineliyor. Yani ayn fonksiyonu tekrar
tekrar uyguluyor.
Peki ama bunu nasl yapyor?
Nasl bir durumla kar karya olduumuzu daha iyi anlamak iin yukardaki kodlar u ekilde
yazalm:
def azalt(s):
if len(s) < 1:
return s
else:
print(list(s))
return azalt(s[1:])

Burada fonksiyonun her yineleniinde, zyinelemeli fonksiyona parametre olarak giden


karakter dizisinin nasl deitiini birazck daha net olarak grebilmek iin karakter dizisi
iindeki karakterleri bir liste haline getirip ekrana basyoruz:
print(list(s))

Bu kodlar altrdmzda u kty alacaz:


['i', 's', 't', 'i', 'h', 'z', 'a']
['s', 't', 'i', 'h', 'z', 'a']
['t', 'i', 'h', 'z', 'a']
['i', 'h', 'z', 'a']
['h', 'z', 'a']
['z', 'a']
['a']

Yukardaki ktnn ilk satrnda grdnz gibi, fonksiyon ilk arldnda listede istihza
karakter dizisini oluturan btn harer var. Yani fonksiyonumuz ilk almada parametre
olarak karakter dizisinin tamamn alyor. Ancak fonksiyonun her yineleniinde listedeki
harer birer birer dyor. Bylece zyinelemeli fonksiyonumuz parametre olarak karakter
dizisinin her defasnda bir eksiltilmi biimini alyor.
Yukardaki szn ettiimiz dmenin yn karakter dizisinin bandan sonuna doru. Yani
her defasnda, elde kalan karakter dizisinin ilk har dyor. Dme ynnn byle olmas
bizim kodlar yaz eklimizden kaynaklanyor. Eer bu kodlar yle yazsaydk:
def azalt(s):
if len(s) < 1:
return s
else:
print(list(s))
return azalt(s[:-1])

Harerin dme yn sondan baa doru olacakt:


['i', 's', 't', 'i', 'h', 'z', 'a']
['i', 's', 't', 'i', 'h', 'z']
['i', 's', 't', 'i', 'h']
['i', 's', 't', 'i']
['i', 's', 't']

604 Blm 36. leri Dzey Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

['i', 's']
['i']

Burada, bir nceki koddaki azalt(s[1:]) satrn azalt(s[:-1]) eklinde deitirdiimize


dikkat edin.
Fonksiyonun nasl ilediini daha iyi anlamak iin, istihza karakter dizisinin son harnin her
yineleni esnasndaki konumunun nasl deitiini de izleyebilirsiniz:
n = 0

def azalt(s):
global n
mesaj = '{} harfinin {}. almadaki konumu: {}'
if len(s) < 1:
return s
else:
n += 1
print(mesaj.format('a', n, s.index('a')))
return azalt(s[1:])

azalt('istihza')

Bu kodlar u kty verir:


a harfinin 1. almadaki konumu: 6
a harfinin 2. almadaki konumu: 5
a harfinin 3. almadaki konumu: 4
a harfinin 4. almadaki konumu: 3
a harfinin 5. almadaki konumu: 2
a harfinin 6. almadaki konumu: 1
a harfinin 7. almadaki konumu: 0

Grdnz gibi istihza kelimesinin en sonunda bulunan a har her defasnda ba tarafa
doru ilerliyor.
Ayn ekilde, kodlar daha iyi anlayabilmek iin, fonksiyona parametre olarak verdiimiz
istihza kelimesinin her yinelemede ne kadar uzunlua sahip olduunu da takip edebilirsiniz:
def azalt(s):
if len(s) < 1:
return s
else:
print(len(s))
return azalt(s[:-1])

Bu fonksiyonu istihza karakter dizisine uyguladmzda bize u kty veriyor:


7
6
5
4
3
2
1

Grdnz gibi, fonksiyonun kendini her yineleyiinde karakter dizimiz klyor.


Bu durum bize zyinelemeli fonksiyonlar hakknda ok nemli bir bilgi veriyor esasnda:

36.2. zyinelemeli (Recursive ) Fonksiyonlar 605


Python 3 iin Trke Klavuz, Srm 3

zyinelemeli fonksiyonlar; byk bir problemin zlebilmesi iin, o problemin, problemin


btnn temsil eden daha kk bir paras zerinde ilem yapabilmemizi salayan
fonksiyonlardr.
Yukardaki rnekte de bu ilkeyi uyguluyoruz. Yani biz istihza karakter dizisinin ncelikle
yalnzca ilk karakterini dryoruz:
s[1:]

Daha sonra da bu yntemi zyinelemeli bir ekilde uyguladmzda, istihza karakter dizisinin
her defasnda daha kk bir paras bu yntemden etkileniyor:
azalt(s[1:])

Yani fonksiyonumuz ilk olarak istihza karakter dizisinin ilk har olan i harni dryor.
Sonra stihza kelimesinin ilk har olan s harni dryor. Ardndan tihza kelimesinin ilk
har olan t harni dryor ve kelime tkenene kadar bu ilemi devam ettiriyor.
Peki ama bunu nasl yapyor?
imdi yukardaki fonksiyondaki u ksma dikkatlice bakn:
if len(s) < 1:
return s

te burada zyinelemeli fonksiyonumuzun, karakter dizisi zerinde ne kadar derine inmesi


gerektiini belirliyoruz. Buna gre, karakter dizisinin uzunluu 1in altna dtnde eldeki
karakter dizisini dndryoruz. Yani karakter dizisinin uzunluu 1in altna dtnde elde
kalan karakter dizisi bo bir karakter dizisi olduu iin o bo karakter dizisini dndryoruz.
Eer istersek elbette bu durumda baka bir ey de dndrebiliriz:
def azalt(s):
if len(s) < 1:
return 'bitti!'
else:
print(s)
return azalt(s[1:])

te if len(s) < 1: blounun bulunduu bu kodlara dip nokta ad veriyoruz.


Fonksiyonumuzun yinelene yinelene (veya baka bir ifadeyle dibe ine ine) gelecei en son
nokta burasdr. Eer bu dip noktay belirtmezsek fonksiyonumuz, tpk dipsiz bir kuyuya
dm gibi, srekli daha derine inmeye alacak, sonunda da hata verecektir. Ne demek
istediimizi daha iyi anlamak iin kodlarmz yle yazalm:
def azalt(s):
print(s)
return azalt(s[1:])

Grdnz gibi burada herhangi bir dip nokta belirtmedik. Bu kodlar altrdmzda
Python bize yle bir hata mesaj verecek:
RuntimeError: maximum recursion depth exceeded

Yani:
almaZamanHatas: Azami zyineleme derinlii ald

606 Blm 36. leri Dzey Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Dediimiz gibi, zyinelemeli fonksiyonlar her yinelenite sorunun (yani zerinde ilem yaplan
parametrenin) biraz daha derinine iner. Ancak bu derine inmenin de bir snr vardr. Bu
snrn ne olduunu u kodlar yardmyla renebilirsiniz:
>>> import sys
>>> sys.getrecursionlimit()

te biz zyinelemeli fonksiyonlarmzda dip noktay mutlaka belirterek, Pythonn fonksiyonu


yinelerken ne kadar derine inip nerede duracan belirlemi oluyoruz.
imdi son kez, yukardaki rnek fonksiyonu, zyineleme mantn ok daha iyi anlamanz
salayacak bir ekilde yeniden yazacaz. Dikkatlice bakn:
def azalt(s):
if len(s) < 1:
return s
else:
print('zyineleme srecine girerken:', s)
azalt(s[1:])
print('zyineleme srecinden karken:', s)

azalt('istihza')

Burada, fonksiyon kendini yinelemeye balamadan hemen nce bir print() satr
yerletirerek s deikeninin durumunu takip ediyoruz:
print('zyineleme srecine girerken:', s)

Ayn ilemi bir de fonksiyonun kendini yinelemeye balamasnn hemen ardndan yapyoruz:
print('zyineleme srecinden karken:', s)

Yukardaki kodlar bize u kty verecek:


zyineleme srecine girerken: istihza
zyineleme srecine girerken: stihza
zyineleme srecine girerken: tihza
zyineleme srecine girerken: ihza
zyineleme srecine girerken: hza
zyineleme srecine girerken: za
zyineleme srecine girerken: a
zyineleme srecinden karken: a
zyineleme srecinden karken: za
zyineleme srecinden karken: hza
zyineleme srecinden karken: ihza
zyineleme srecinden karken: tihza
zyineleme srecinden karken: stihza
zyineleme srecinden karken: istihza

Grdnz gibi fonksiyon zyineleme srecine girerken drd her bir karakteri,
zyineleme srecinden karken yeniden dndryor. Bu, zyinelemeli fonksiyonlarn nemli
bir zelliidir. Mesela bu zellikten yararlanarak yle bir kod yazabilirsiniz:
def ters_evir(s):
if len(s) < 1:
return s
else:
ters_evir(s[1:])

36.2. zyinelemeli (Recursive ) Fonksiyonlar 607


Python 3 iin Trke Klavuz, Srm 3

print(s[0])

ters_evir('istihza')

Yazdmz bu kodda ters_evir() fonksiyonu, kendisine verilen parametreyi ters


evirecektir. Yani yukardaki kod bize u kty verir:
a
z
h
i
t
s
i

Burada yaptmz ey ok basit: Yukarda da sylediimiz gibi, zyinelemeli fonksiyonlar,


zyineleme srecine girerken yapt ii, zyineleme srecinden karken tersine evirir. te
biz de bu zellikten yararlandk. Fonksiyonun kendini yineledii noktann kna bir print()
fonksiyonu yerletirip, geri dnen karakterlerin ilk harni ekrana bastk. Bylece s adl
parametrenin tersini elde etmi olduk.
Ancak eer yukardaki kodlar bu ekilde yazarsak, fonksiyondan dnen deeri her yerde
kullanamayz. Mesela yukardaki fonksiyonu aadaki gibi kullanamayz:
def ters_evir(s):
if len(s) < 1:
return s
else:
ters_evir(s[1:])
print(s[0])

kelime = input('kelime girin: ')


print('Girdiiniz kelimenin tersi: {}'.format(ters_evir('istihza')))

Fonksiyonumuzun daha kullanl olabilmesi iin kodlarmz yle yazabiliriz:


def ters_evir(s):
if len(s) < 1:
return s
else:
return ters_evir(s[1:]) + s[0]

kelime = input('kelime girin: ')


print('Girdiiniz kelimenin tersi: {}'.format(ters_evir('istihza')))

Burada bizim amacmz gerekletirmemizi salayan satr u:


return ters_evir(s[1:]) + s[0]

lk bakta bu satrn nasl altn anlamak zor gelebilir. Ama aslnda son derece basit bir
mant var bu kodlarn. yle dnn: ters_evir() fonksiyonunu zyinelemeli olarak
ilettiimizde, yani u kodu yazdmzda:
return ters_evir(s[1:])

...dndrlecek son deer bo bir karakter dizisidir. te biz zyinelemeden klrken geri
dnen karakterlerin ilk harerini bu bo karakter dizisine ekliyoruz ve bylece girdiimiz
karakter dizisinin ters halini elde etmi oluyoruz.

608 Blm 36. leri Dzey Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

Yukardaki ilevin aynsn, zyinelemeli fonksiyonunuzu yle yazarak da elde edebilirdiniz:


def ters_evir(s):
if not s:
return s
else:
return s[-1] + ters_evir(s[:-1])

print(ters_evir('istihza'))

Burada ayn i iin farkl bir yaklam benimsedik. lk olarak, dip noktasn u ekilde belirledik:
if not s:
return s

Bildiiniz gibi, bo veri tiplerinin bool deeri Falsetur. Dolaysyla zyineleme srasnda s
parametresinin uzunluunun 1in altna dmesi, s parametresinin iinin boaldn gsterir.
Yani o anda s parametresinin bool deeri False olur. Biz de yukarda bu durumdan
faydalandk.
Bir nceki kodlara gre bir baka farkllk da u satrda:
return s[-1] + ters_evir(s[:-1])

Burada benimsediimiz yaklamn z u: Bildiiniz gibi bir karakter dizisini ters evirmek
istediimizde ncelikle bu karakter dizisinin en son karakterini alp en baa yerletiririz. Yani
mesela elimizdeki karakter dizisi istihza ise, bu karakter dizisini ters evirmenin ilk adm
bunun en son karakteri olan a harni alp en baa koymaktr. Daha sonra da geri kalan
hareri tek tek tersten buna ekleriz:
dz: istihza
ters: a + z + h + i + t + s + i

te yukardaki fonksiyonda da yaptmz ey tam anlamyla budur.


nce karakter dizisinin son harni en baa koyuyoruz:
return s[-1]

Ardndan da buna geri kalan hareri tek tek tersten ekliyoruz:


return s[-1] + ters_evir(s[:-1])

zyinelemeli fonksiyonlara ilikin olarak yukarda tek bir rnek zerinde epey aklama
yaptk. Bu rnek ve aklamalar, zyinelemeli fonksiyonlarn nasl alt konusunda size
epey kir vermi olmal. Ancak elbette bu fonksiyonlar tek bir rnek yardmyla tamamen
anlayamam olabilirsiniz. O yzden gelin isterseniz bir rnek daha verelim. Mesela bu kez
de basit bir saya yapalm:
def saya(say, snr):
print(say)
if say == snr:
return 'bitti!'
else:
return saya(say+1, snr)

Not: Bu fonksiyonun yapt ii elbette baka ekillerde ok daha kolay bir ekilde
halledebilirdik. Bu rnei burada vermemizin amac yalnzca zyinelemeli fonksiyonlarn

36.2. zyinelemeli (Recursive ) Fonksiyonlar 609


Python 3 iin Trke Klavuz, Srm 3

nasl ilediini gstermek. Yoksa byle bir ii zyinelemeli fonksiyonlarla yapmanz


beklemiyoruz.

Yukardaki fonksiyona dikkatlice bakarsanz aslnda yapt ii ok basit bir ekilde


gerekletirdiini greceksiniz.
Burada ncelikle saya() adl bir fonksiyon tanmladk. Bu fonksiyon toplam iki farkl
parametre alyor: say ve snr.
Buna gre fonksiyonumuzu yle kullanyoruz:
print(saya(0, 100))

Burada say parametresine verdiimiz 0 deeri sayacmzn saymaya katan balayacan


gsteriyor. snr parametresine verdiimiz 100 deeri ise kaa kadar saylacan gsteriyor.
Buna gre biz 0 dan 100 e kadar olan saylar sayyoruz...
Gelin imdi biraz fonksiyonumuzu inceleyelim.
lk olarak u satr gryoruz fonksiyon gvdesinde:
print(say)

Bu satr, zyinelemeli fonksiyonun her yineleniinde say parametresinin durumunu ekrana


basacak.
Sonraki iki satrda ise u kodlar gryoruz:
if say == snr:
return 'bitti!'

Bu bizim dip nokta adn verdiimiz ey. Fonksiyonumuz yalnzca bu noktaya kadar
yineleyecek, bu noktann ilerisine gemeyecektir. Yani say parametresinin deeri snr
parametresinin deerine ulatnda zyineleme ilemi de sona erecek. Eer byle bir
dip nokta belirtmezsek fonksiyonumuz sonsuza kadar kendini yinelemeye alacak, daha
nce szn ettiimiz zyineleme limiti nedeniyle de belli bir aamadan sonra hata verip
kecektir.
Sonraki satrlarda ise u kodlar gryoruz:
else:
return saya(say+1, snr)

Bu satrlar, bir nceki aamada belirttiimiz dip noktaya ulalana kadar fonksiyonumuzun
hangi ilemleri yapacan gsteriyor. Buna gre, fonksiyonun her yineleniinde say
parametresinin deerini 1 say artryoruz.
Fonksiyonumuzu saya(0, 100) gibi bir komutla altrdmz dnrsek, fonksiyonun
ilk almasnda 0 olan say deeri sonraki yinelemede 1, sonraki yinelemede 2, sonraki
yinelemede ise 3 olacak ve bu durum snr deer olan 100 e varlana kadar devam edecektir.
say parametresinin deeri 100 olduunda ise dip nokta olarak verdiimiz lt devreye
girecek ve fonksiyonun kendi kendisini yinelemesi ilemine son verilecektir.
Biz yukardaki rnekte yukarya doru sayan bir fonksiyon yazdk. Eer yukardan aaya
doru sayan bir saya yapmak isterseniz yukardaki fonksiyonu u ekle getirebilirsiniz:
def saya(say, snr):
print(say)

610 Blm 36. leri Dzey Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

if say == snr:
return 'bitti!'
else:
return saya(say-1, snr)

print(saya(100, 0))

Burada, nceki fonksiyonda + olan ileci - ilecine evirdik:


return saya(say-1, snr)

Fonksiyonumuzu arrken de elbette say parametresinin deerini 100 olarak, snr


parametresinin deerini ise 0 olarak belirledik.
Bu arada, daha nce de bahsettiimiz gibi, zyinelemeli fonksiyonlar, zyinelemeye balarken
dndrdkleri deeri, zyineleme ileminin sonunda tek tek geri dndrr. Bu zellii gz
nnde bulundurarak yukardaki fonksiyonu u ekilde de yazabilirdiniz:
def saya(say, snr):
if say == snr:
return 'bitti!'
else:
saya(say+1, snr)
print(say)

print(saya(0, 10))

Dikkat ederseniz burada print(say) satrn zyineleme ilevinin kna yerletirdik.


Bylece 0 dan 10 a kadar olan saylar tersten elde ettik. Ancak tabii ki yukardaki anlaml bir
kod yazm tarz deil. nk fonksiyonumuzun yazm tarzyla yapt i birbiriyle ok ilgisiz.
Saylar yukar doru saymak zere tasarland belli olan bu kodlar, yalnzca bir print()
fonksiyonunun zyineleme kna yerletirilmesi sayesinde yapt ii yapyor...
Yukarda verdiimiz rnekler sayesinde artk zyinelemeli fonksiyonlar hakknda en azndan
kir sahibi olduumuzu syleyebiliriz. Gelin isterseniz imdi zyinelemeli fonksiyonlarla ilgili
(biraz daha mantkl) bir rnek vererek bu etrelli konuyu zihnimizde netletirmeye alalm.
Bu defaki rneimizde i ie gemi listeleri tek katmanl bir liste haline getireceiz. Yani
elimizde yle bir liste olduunu varsayarsak:
l = [1, 2, 3, [4, 5, 6], [7, 8, 9, [10, 11], 12], 13, 14]

Yazacamz kodlar bu listeyi u hale getirecek:


[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

Bu amac gerekletirebilmek iin yle bir fonksiyon yazalm:


def dz_liste_yap(liste):
if not isinstance(liste, list):
return [liste]
elif not liste:
return []
else:
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])

l = [1, 2, 3, [4, 5, 6], [7, 8, 9, [10, 11], 12], 13, 14]

36.2. zyinelemeli (Recursive ) Fonksiyonlar 611


Python 3 iin Trke Klavuz, Srm 3

print(dz_liste_yap(l))

Bu fonksiyonu yukardaki i ie gemi listeye uyguladnzda istediiniz sonucu aldnz


greceksiniz.
lk bakta yukardaki kodlar anlamak biraz zor gelmi olabilir. Ama endie etmenize gerek
yok. Zira biz bu kodlar olabildiince ayrntl bir ekilde aklayacaz.
lk olarak dip noktamz tanmlyoruz her zamanki gibi:
if not isinstance(liste, list):
return [liste]

Fonksiyonumuzun temel alma prensibine gre liste iindeki btn eleri tek tek alp baka
bir liste iinde toplayacaz. Eer liste elemanlar zerinde ilerlerken karmza liste olmayan
bir eleman karsa bu eleman [liste] koduyla bir listeye dntreceiz.
nceki rneklerden farkl olarak, bu kez kodlarmzda iki farkl dip noktas kontrol gryoruz.
lkini yukarda akladk. kinci dip noktamz u:
elif not liste:
return []

Burada yaptmz ey u: Eer zyineleme esnasnda bo bir liste ile karlarsak, tekrar bo
bir liste dndryoruz. Peki ama neden?
Bildiiniz gibi bo bir listenin 0. eleman olmaz. Yani bo bir liste zerinde u ilemi
yapamayz:
>>> a = []
>>> a[0]

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
IndexError: list index out of range

Grdnz gibi, bo bir liste zerinde indeksleme ilemi yapmaya kalktmzda hata
alyoruz. imdi durumu daha iyi anlayabilmek iin isterseniz yukardaki kodlar bir de ikinci
dip noktas kontrol olmadan yazmay deneyelim:
def dz_liste_yap(liste):
if not isinstance(liste, list):
return [liste]
else:
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])

l = [1, 2, 3, [4, 5, 6], [7, 8, 9, [10, 11], 12], 13, 14]

print(dz_liste_yap(l))

Bu kodlar altrdmzda u hata mesajyla karlayoruz:


Traceback (most recent call last):
File "deneme.py", line 9, in <module>
print(dz_liste_yap(l))
File "deneme.py", line 5, in dz_liste_yap
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
File "deneme.py", line 5, in dz_liste_yap

612 Blm 36. leri Dzey Fonksiyonlar


Python 3 iin Trke Klavuz, Srm 3

return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])


File "deneme.py", line 5, in dz_liste_yap
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
File "deneme.py", line 5, in dz_liste_yap
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
File "deneme.py", line 5, in dz_liste_yap
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
File "deneme.py", line 5, in dz_liste_yap
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
File "deneme.py", line 5, in dz_liste_yap
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
File "deneme.py", line 5, in dz_liste_yap
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])
IndexError: list index out of range

Grdnz gibi, biraz nce bo bir liste zerinde indeksleme yapmaya altmzda
aldmz hatann ayns bu. nk kodlarmzn else blouna bakarsanz liste zerinde
indeksleme yaptmz grrsnz:
return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])

Elbette bo bir liste liste[0] veya liste[1:] gibi sorgulamalara IndexError tipinde bir hata
mesajyla cevap verecektir. te byle bir durumda hata almamak iin u kodlar yazyoruz:
elif not liste:
return []

Bylece zyineleme esnasnda bo bir listeyle karlatmzda bu listeyi u ekle


dntryoruz:
[[]]

Byle bir yap zerinde indeksleme yaplabilir:


>>> a = [[]]
>>> a[0]

[]

Dip noktaya ulalana kadar yaplacak ilemler ise unlar:


return dz_liste_yap(liste[0]) + dz_liste_yap(liste[1:])

Yani listenin ilk esine, geri kalan eleri teker teker ekliyoruz.
Gelin bir rnek daha verelim:
def topla(sayilar):
if len(sayilar) < 1:
return 0
else:
ilk, son = sayilar[0], sayilar[1:]
return ilk+topla(son)

Bu fonksiyonun grevi, kendisine liste olarak verilen saylar birbiriyle toplamak. Biz bu ii
baka yntemlerle de yapabileceimizi biliyoruz, ama bizim burada amacmz zyinelemeli
fonksiyonlar anlamak. O yzden saylar birbiriyle toplama ilemini bir de bu ekilde
yapmaya alacaz.

36.2. zyinelemeli (Recursive ) Fonksiyonlar 613


Python 3 iin Trke Klavuz, Srm 3

Elimizde yle bir liste olduunu varsayalm:


liste = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Byle bir durumda fonksiyonumuz 55 kts verir.


Gelelim bu fonksiyonu aklamaya...
Her zamanki gibi ilk olarak dip noktamz tanmlyoruz:
if len(sayilar) < 1:
return 0

Buna gre sayilar adl listenin uzunluu 1in altna dnce 0 deerini dndryoruz. Burada
0 deerini dndrmemizin nedeni, listede e kalmadnda programmzn hata vermesini
nlemek. Eer 0 dnda baka bir say dndrrsek bu say toplama ileminin sonucuna etki
edecektir. Toplama ileminin sonucunu etkilemeyecek tek say 0 olduu iin biz de bu sayy
dndryoruz.
Taban noktaya varlncaya kadar yaplacak ilemler ise unlar:
ilk, son = sayilar[0], sayilar[1:]
return ilk+topla(son)

Burada amacmz, listenin ilk says ile listenin geri kalan elerini tek tek birbiriyle toplamak.
Bunun iin sayilar adl listenin ilk esini, listenin geri kalanndan ayryoruz ve ilk eyi ilk ;
geri kalan eleri ise son adl bir deikene gnderiyoruz:
ilk, son = sayilar[0], sayilar[1:]

Sonra da ilk eyi, geri kalan liste eleri ile tek tek topluyoruz. Bunun iin de topla()
fonksiyonunun kendisini son adl deiken iinde tutulan liste elerine zyinelemeli olarak
uyguluyoruz:
return ilk+topla(son)

Bylece liste iindeki btn elerin toplam deerini elde etmi oluyoruz.
Bu arada, yeri gelmiken Python programlama dilinin pratik bir zelliinden sz edelim.
Grdnz gibi saylarn ilk esini geri kalan elerden ayrmak iin yle bir kod yazdk:
ilk, son = sayilar[0], sayilar[1:]

Aslnda ayn ii ok daha pratik bir ekilde de halledebilirdik. Dikkatlice bakn:


ilk, *son = sayilar

Bylece sayilar deikenin ilk esi ilk deikeninde, geri kalan eleri ise son deikeninde
tutulacaktr. lerleyen derslerde Yrycler (Iterators ) konusunu ilerken bu yapdan daha
ayrntl bir ekilde sz edeceiz.

614 Blm 36. leri Dzey Fonksiyonlar


BLM 37

Modller

Bu blmde, geen derste ayrntl olarak incelediimiz Fonksiyonlar kadar nemli bir
konuyu ele alacaz. Bu nemli konunun ad modller.
Biz imdiye kadar modl konusunu hi ayrntl olarak ele almam olsak da esasnda siz
modl kavramna bsbtn yabanc saylmazsnz. Zira biz nceki derslerimizde zaman
zaman modllerden sz etmi, hatta yeri geldiinde bunlar kodlarmz iinde kullanmaktan
da ekinmemitik.
Bu konuya gelene kadar, eitli blmlerde u modllerden bahsettiimizi
hatrlyorsunuzdur:
sys
os
keyword
random
unicodedata
locale
te imdi, daha nce farkl blmlerde yle bir temas edip getiimiz modller konusunu
bu blmde derinlemesine incelemeye alacaz.

37.1 Modl Nedir?

Dediimiz gibi, bu blmde Pythondaki en nemli konulardan biri olan modllerden sz


edeceiz. Ancak modlleri kullanabilmek iin elbette ncelikle modl denen eyin ne
olduunu iyice bir anlamamz gerekiyor. Peki, nedir bu modl denen ey?
Bu soruyu, imdiye kadar grdmz modllere bakarak cevaplayacak olursak, modllerin,
baz ilevleri kolaylkla yerine getirmemizi salayan birtakm fonksiyonlar ve nitelikleri iinde
barndran aralar olduunu syleyebiliriz.
Mesela Kmeler ve Dondurulmu Kmeler adl blmde random adl bir modle
deindiimizi hatrlyor olmalsnz. Orada bu modlle ilgili yle bir rnek vermitik:
liste = [random.randint(0, 10000) for i in range(1000)]

Bu rnekte, random adl modln iindeki randint() adl faydal bir fonksiyondan
yararlanarak 0 ile 10.000 saylar arasnda 1000 adet rastgele say ieren bir liste

615
Python 3 iin Trke Klavuz, Srm 3

oluturmutuk. Dolaysyla, yukardaki tanmda da belirttiimiz gibi, bir modl olan random,
rnekte bahsettiimiz ilevi kolaylkla yerine getirmemizi salayan bir fonksiyon barndryor.
Biz de bu fonksiyonu kullanarak amacmz rahatlkla yerine getirebiliyoruz.
random modlnn dnda, nceki derslerimizde yle bir deinip getiimiz, sys, os ve
locale gibi modllerin de eitli grevleri kolayca yerine getirmemizi salayan birtakm
aralar barndrdn grmtk.
in dorusu, modl denen ey Python programlama dilinin bel kemiidir. Eer modller
olmasayd, Python programlama dili hem ok kullansz bir dil olurdu, hem de modller
sayesinde ok kolay bir ekilde stesinden gelebildiimiz zorluklar iin her defasnda
kendimiz yeniden bir zm icat etmek zorunda kalrdk.
Belki bu iddial laf size u anda pek anlaml gelmemi olabilir. u ana kadar modllerle ilgili
rendikleriniz, henz zihninizde bu lafn iddiasn teyit etmiyor olabilir. Ama modllerin
neden bu kadar nemli olduunu birazdan ok daha net bir ekilde anlayacaksnz. imdilik
okumaya devam edin.
Hatrlarsanz bir nceki blmde Pythondaki fonksiyonlardan bahsetmitik. Yine
hatrlarsanz o blmde pek ok rnek fonksiyon da tanmlamtk. Mesela kayt_olutur()
adl yle bir fonksiyon tanmladmz hatrlyor olmalsnz:
def kayt_olutur(isim, soyisim, isis, ehir):
print("-"*30)

print("isim : ", isim)


print("soyisim : ", soyisim)
print("iletim sistemi: ", isis)
print("ehir : ", ehir)

print("-"*30)

Bu fonksiyonu bir kez tanmladktan sonra, bu fonksiyonu ayn program iinde istediimiz
kadar kullanabiliyoruz. Yani kayt_olutur adl bir fonksiyon tanmlam olmamz sayesinde,
bu fonksiyonun gvdesinde belirttiimiz ilemleri her defasnda tekrar tekrar yapmak
zorunda kalmyoruz; btn bu ilemleri tek bir kayt_olutur ismine atam olduumuz
iin, bu fonksiyonun bize sunduu ileve ihtiya duyduumuz her yerde bu fonksiyonu
kullanabiliyoruz. rnein:

kayt_olutur('Frat', 'zgl', 'Debian', 'Arsuz')

Ya da:
kayt_olutur('Zerrin', 'Sz', 'Ubuntu', 'Bolvadin')

Eer yukardaki ilevsellii bir fonksiyon olarak tanmlam olmasaydk,


kayt_olutur(Frat, zgl, Debian, Arsuz) kodunun verdii kty elde
etmek iin u kodlar yazmak zorunda kalacaktk:
print("-"*30)

print("isim : ", "Frat")


print("soyisim : ", "zgl")
print("iletim sistemi: ", "Debian")
print("ehir : ", "Arsuz")

print("-"*30)

616 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

Burada isim, soyisim, iletim sistemi ve ehir bilgileri deitiinde de her defasnda ayn
eyleri uzun uzadya tekrar tekrar yazmamz gerekecekti:
print("-"*30)

print("isim : ", "Zerrin")


print("soyisim : ", "Sz")
print("iletim sistemi: ", "Ubuntu")
print("ehir : ", "Bolvadin")

print("-"*30)

te modller de buna benzer bir vazife grr. Yani Pythonn fonksiyon sistemi nasl bize bir
ilevsellii ayn dosya iinde tekrar tekrar kullanma imkan veriyorsa, modl sistemi de bir
fonksiyonu farkl dosyalar ve programlar iinde tekrar tekrar kullanma imkan verir.
Dolaysyla, eer modl sistemi olmasayd, biz bir kez yazdmz (veya baka bir Python
programcs tarafndan yazlm) kayt_olutur() fonksiyonunu baka bir programda da
kullanmak istediimizde, bu fonksiyonu alp her defasnda yeni programa elle kopyalamak
zorunda kalrdk. Ama modl sistemi sayesinde, bir program iinde bulunan fonksiyonlar
(ve dier nitelikleri) baka Python programlar iine aktarabiliyoruz. Bylece bir Python
programndaki (veya modlndeki) ilevsellikten, baka bir Python programnda da
yararlanabiliyoruz. Dolaysyla modller sayesinde, bir kez yazdmz kodlar pek ok farkl
program iinde kullanma imkan elde ediyoruz. Bu da bizim;
Daha az kod yazmamz,
Bir kez yazdmz kodlar tekrar tekrar kullanabilmemizi,
Daha dzenli, daha derli toplu bir ekilde alabilmemizi
salyor.
te bu blmde, modllerin btn bu ilevleri nasl yerine getirdiini, modl denen eyden
nasl faydalanabileceimizi ve modllerin neden bu kadar nemli olduunu reneceiz.
Dilerseniz laf daha fazla dolandrmadan modller konusuna hzl bir giri yapalm.

37.2 Hazr Modller

Hatrlarsanz, Pythonda iki farkl fonksiyon tr olduundan sz etmitik:


1. Kendi tanmladmz fonksiyonlar
2. Gml (built-in) fonksiyonlar
Ayn ekilde modller de iki farkl balk altnda incelenebilir:
1. Kendi tanmladmz modller
2. Hazr modller
Biz burada ncelikle hazr modlleri ele alacaz. Bu ekilde modl kavramn iyice anladktan
sonra da kendi modllerimizi nasl yazacamz reneceiz.
Hazr modller, Python gelitiricilerinin veya bizim dmzdaki Python programclarnn yazp
hizmetimize sunduu modllerdir.
Hazr modller de kendi iinde ikiye ayrlabilir:

37.2. Hazr Modller 617


Python 3 iin Trke Klavuz, Srm 3

1. Standart Ktphane Modlleri


2. nc ahs Modlleri
Standart Ktphane Modlleri, dorudan Python gelitiricileri tarafndan yazlp dile
kaynatrlm modllerdir. Bu ynyle bu modller daha nce rendiimiz gml
fonksiyonlara ok benzer. Tpk gml fonksiyonlarda olduu gibi, Standart Ktphane
Modlleri de her an emrimize amadedir. Biz bunlar istediimiz her an, herhangi bir ek yazlm
kurmak zorunda kalmadan, kendi programlarmz iinde kullanabiliriz.
Ayrca bkz.:
Pythonn Standart Ktphanesi iinde hangi modllerin olduunu
https://docs.python.org/3/library/ adresinden inceleyebilirsiniz.
Standart Ktphane iinde, Python ile programlama yaparken ilerinizi bir hayli
kolaylatracak pek ok modl bulacaksnz.
Bata da sylediimiz gibi, biz bu blme gelinceye kadar stnkr de olsa modllerden sz
etmitik. rnein nceki derslerimizde andmz sys, os, random ve benzeri modller hep
birer Standart Ktphane modldr. Dolaysyla bu modllerin sunduu ilevsellikten kendi
programlarmzda istediimiz her an yararlanabiliriz.

37.3 Modllerin e Aktarlmas

Pythonda herhangi bir modl kullanabilmek iin ncelikle onu ie aktarmamz gerekir.
e aktarmak, bir modl iindeki fonksiyon ve nitelikleri baka bir program (veya ortam)
iinden kullanlabilir hale getirmek demektir. sterseniz bu soyut tanmlamay bir rnek ile
somutlatralm. Mesela, bir Standart Ktphane modl olduunu rendiimiz ve nceki
derslerimizde de deindiimiz os adl modl ie aktaralm. Bunun iin ncelikle etkileimli
kabuu altralm ve u komutu verelim:
>>> import os

Bylece os adl modl ie aktarm, yani bu modl iindeki fonksiyon ve nitelikleri


kullanlabilir hale getirmi olduk.
Hatrlarsanz modl kavramn tanmlarken, bunlarn bize birtakm yararl fonksiyonlar
ve nitelikler sunan aralar olduunu sylemitik. te, mesela bu os modlnn bize
hangi yararl fonksiyonlar ve nitelikleri sunduunu renmek iin dir() fonksiyonunu
kullanabiliriz:
>>> dir(os)

Grdnz gibi bu modl pek ok fonksiyon ve nitelik barndryor.


Bu modle adn veren os kelimesi operating system (iletim sistemi) ifadesinin ksaltmasdr.
Bu modl, kullandmz iletim sistemine ilikin ilemler yapabilmemiz iin bize eitli
fonksiyonlar ve nitelikler sunar. Hemen bir rnek verelim.
Diyelim ki bir program yazdnz. Ancak yazdnz bu programn yalnzca Windows iletim
sisteminde almasn istiyorsunuz. Buna gre, eer programnz Windows iletim sistemi
kurulu bir bilgisayarda altrlrsa programnzn normal bir ekilde balamasn, ama eer
Windows d bir iletim sisteminde altrlrsa da kullancya bir uyar mesaj verilmesini
istiyorsunuz.

618 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

te bunun iin os modlnden yararlanabilirsiniz. imdi dir(os) komutuyla elde ettiimiz


listeye bakalm. Orada name adl bir nitelik olduunu greceksiniz. Bu nitelik, bize
kodlarmzn hangi iletim sisteminde altn gsterir. Dolaysyla da yukarda tarif
ettiimiz i iin gayet uygun bir aratr.
nceden import os komutuyla os modln ie aktarm olduumuzu varsayarsak, modln
bu niteliini yle kullanyoruz:
>>> os.name

'posix'

os adl modln iindeki name niteliine nasl eritiimize ok dikkat edin. nce
modlmzn ad olan osu yazyoruz. Ardndan bir nokta iareti koyup, ihtiyacmz olan
niteliin adn belirtiyoruz. Yani yle bir forml takip ediyoruz:
modl_ad.fonksiyon_veya_nitelik

os.name komutu, kullandnz iletim sistemine bal olarak farkl ktlar verir. Eer bu
komutu bir GNU/Linux datmnda veya bir Mac bilgisayarda verirsek yukardaki gibi posix
kts alrz. Ama eer ayn komutu Windowsta verirsek nt kts alrz. Dolaysyla os
modlnn name niteliini kullanarak, yazdmz bir programn hangi iletim sisteminde
altn denetleyebiliriz:
>>> if os.name != 'nt':
... print('Kusura bakmayn! Bu program yalnzca',
... 'Windows\'ta kullanabilirsiniz!')
... else:
... print('Hogeldin Windows kullancs!')

Etkileimli kabukta yazdmz bu program gelin bir de bir metin dosyasna kaydedelim. Zira
biz henz modlleri renme aamasnda olduumuz iin imdilik bunlar etkileimli kabukta
test ediyor olsak da, gerek hayatta programlarmz etkileimli kabua deil, program
dosyalar iine yazacaz.
Yukardaki kodlar bir dosyaya kaydettiimizde programmz yle grnr:
import os

if os.name != 'nt':
print('Kusura bakmayn! Bu program yalnzca',
'Windows\'ta kullanabilirsiniz!')
else:
print('Hogeldin Windows kullancs!')

Grdnz gibi, programmz kaydederken, programmzn en bana import os komutunu


yazarak ncelikle ilgili modl ie aktaryoruz. Pythonda modller genellikle programn en
banda ie aktarlr. Ama bu bir zorunluluk deildir. Modlleri programn istediiniz her
yerinde ie aktarabilirsiniz (bununla ilgili bir istisnadan biraz sonra sz edeceiz).
Modl ie aktarmaya ilikin en nemli kural, modle ait bir nitelik veya fonksiyonun
kullanlmasndan nce modln ie aktarlm olmas gerekliliidir. Yani mesela yukardaki
programda os modl iindeki name niteliini kullanmadan nce os modln ie aktarm
olmamz gerekir. Eer Python, if os.name != nt: satrndan nce herhangi bir yerde
import os gibi bir komutla os modlnn ie aktarldn gremezse hata verecektir.
Bu program yukardaki gibi bir dosyaya kaydettikten sonra bunu herhangi bir Python

37.3. Modllerin e Aktarlmas 619


Python 3 iin Trke Klavuz, Srm 3

program gibi altrabilirsiniz.


Eer bu program Windows dndaki bir iletim sisteminde altrrsanz u kty alrsnz:
Kusura bakmayn! Bu program yalnzca
Windows'ta kullanabilirsiniz!

Ama eer bu program Windows iletim sisteminde altrlrsa u kty verir:


Hogeldin Windows kullancs!

Bylece modl iindeki bir nitelie erimi olduk. Yalnz burada asla unutmamamz gereken
ey, ncelikle kullanacamz modl import modl_ad komutuyla ie aktarmak olacaktr.
Modl ie aktarmazsak tabii ki o modldeki fonksiyon veya niteliklere de eriemeyiz. (Sk
yaplan bir hata olduu iin, bunu tekrar tekrar vurguluyoruz...)
Bu arada bir modl, her etkileimli kabuk oturumunda yalnzca bir kez ie aktarmak
yeterlidir. Yani siz etkileimli kabuu altrdktan sonra bir kez import os komutuyla modl
ie aktardktan sonra, o etkileimli kabuk oturumunu kapatana kadar, ayn modl tekrar ie
aktarmak zorunda kalmadan bu modln ieriini kullanabilirsiniz.
Ayn ekilde, eer bu kodlar etkileimli kabua deil de bir program dosyasna yazyorsanz,
import os komutunu dosyann bana bir kez yazdktan sonra ayn modl programn
ilerleyen ksmlarnda tekrar ie aktarmak zorunda kalmadan, o modlnn ieriinden
yararlanabilirsiniz.
Grdnz gibi, bir Standart Ktphane Modl olan os bize name adl ok kullanl bir
nitelik sunuyor. Eer os modl olmasayd, name adl niteliin sunduu ilevi kendimiz icat
etmek zorunda kalrdk.
Baka bir rnek daha verelim...
Diyelim ki yine bir program yazdnz. Programnzn almas iin, programnz kullanan
kiinin bilgisayarnda birtakm dizinler oluturmanz gerekiyor. te bu i iin de os
modlnden yararlanabilirsiniz.
Bu modl iindeki makedirs() fonksiyonunu kullanarak, o anda iinde bulunduunuz dizinde
yeni bir dizin oluturabilirsiniz:
>>> os.makedirs('DATA')

Bu komutu verdikten sonra, o anda altnda bulunduunuz dizinde DATA adl bir dizin
oluacaktr. Eer o anda hangi dizin altnda bulunduunuzu renmek isterseniz de yine
os modlnden faydalanabilirsiniz:
>>> os.getcwd()

os modlnn getcwd() fonksiyonu bize o anda hangi dizin altnda bulunduumuzu gsterir.
Bu komutun ktsnda hangi dizin adn gryorsanz, biraz nce makedirs() fonksiyonu ile
oluturduunuz DATA dizini de o dizin altnda olumutur...
Grdnz gibi, bir rpda os modlnn birka zelliinden birden yararlandk. Daha nce
de sylediimiz gibi, eer os modl olmasayd yukarda gerekletirdiimiz btn ilevleri
kendiniz icat etmek zorunda kalrdnz.
Bylece Pythondaki modllerin neye benzediini ve nasl kullanldn anlam olduk.
Modllerin faydal aralar olduu konusunda sizleri ikna edebilmi olduumuzu varsayarak
bir sonraki blme geelim.

620 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

37.3.1 Farkl e Aktarma Yntemleri

Biz imdiye kadar, modlleri import modl_ad eklinde ie aktardk. Esasnda standart ie
aktarma yntemi de budur. Bir modl bu ekilde ie aktardmz zaman, modl adn
kullanarak, o modln ieriine eriebiliriz:
>>> import sys
>>> sys.version #Python'n srmn verir

veya:
>>> import os
>>> os.name #letim sistemimizin adn verir

gibi...
Ancak Pythonda bir modl ie aktarmann tek yntemi bu deildir. Eer istersek modlleri
daha farkl ekillerde de ie aktarabiliriz.
Gelin imdi bu alternatif modl aktarma biimlerinin neler olduunu grelim.

import modl_ad as farkl_isim

Baz koullar, bir modl kendi adyla deil de baka bir isimle ie aktarmanz gerektirebilir.
Ya da siz bir modl kendi ad dnda bir adla ie aktarmann daha iyi bir kir olduunu
dnebilirsiniz.
Peki ama ne tr koullar bir modl farkl bir adla ie aktarmamz gerektirebilir veya biz
hangi sebeple bir modl farkl adla ie aktarmay isteyebiliriz?
Bu sorularn cevabn verebilmek iin, gelin isterseniz subprocess adl bir Standart Ktphane
modlnden yararlanalm. Hem bu vesileyle yeni bir modl de renmi oluruz...

Not: subprocess modl, harici komutlar Python iinden altrabilmemizi salayan


olduka faydal bir aratr. Bu modl kullanarak Python programlarmz iinden, baka
programlar altrabiliriz.

Bir modln iindeki fonksiyon ve nitelikleri her kullanmak isteyiimizde, o fonksiyon veya
niteliin bana modl adn da eklememiz gerektiini artk gayet iyi biliyorsunuz. rnein
subprocess adl modl
>>> import subprocess

komutuyla ie aktardktan sonra, bu modl iindeki herhangi bir fonksiyon veya nitelii
kullanabilmenin birinci art, modl adn ilgili fonksiyon veya niteliin nne getirmektir.
Mesela biz subprocess modlnn call() adl fonksiyonunu kullanmak istersek, yle bir
kod yazmamz gerekir:
>>> subprocess.call('notepad.exe')

Bu ekilde Notepad programn Python iinden altrm olduk.


Ancak grdnz gibi, subprocess biraz uzun bir kelime. Bu modl her kullanmak
isteyiinizde nitelik veya fonksiyon adnn nne bu uzun kelimeyi getirmek bir sre sonra
skc bir hal alabilir. Bu yzden eer isterseniz modl import subprocess eklinde kendi
adyla deil de daha ksa bir adla ie aktarmay tercih edebilirsiniz:

37.3. Modllerin e Aktarlmas 621


Python 3 iin Trke Klavuz, Srm 3

>>> import subprocess as sp

Burada yle bir forml uyguladmza dikkat edin:


>>> import modl_ad as farkl_bir_isim

Bylece artk bu modl yalnzca sp nekiyle kullanabilirsiniz:


>>> sp.call('notepad.exe')

rnek olmas asndan baka bir modl daha ele alalm. Modlmzn ad webbrowser.

Not: webbrowser modl, bilgisayarmzda kurulu internet taraycsn kullanarak internet


sitelerini aabilmemizi salar.

Tpk subprocess gibi, webbrowser kelimesi de, her defasnda tekrar etmesi skc olabilecek
bir kelime. Dolaysyla dilerseniz bu modl import webbrowser yerine farkl bir isimle ie
aktarabilirsiniz. rnein:
>>> import webbrowser as br

veya:
>>> import webbrowser as web

Modl hangi adla ie aktaracanz tamamen size kalm. Diyelim ki bu modl web adyla
ie aktardk. Artk bu modln iindeki aralar web nekiyle kullanabiliriz:
>>> web.open('www.istihza.com')

Uyar: Baz GNU/Linux datmlarnda websitesi adresini http nekiyle birlikte


belirtmeniz gerekebilir. rn. web.open(http://www.istihza.com).

Bu kod, bilgisayarmzdaki ntanml web taraycs hangisiyse onu altracak ve bizi,


parantez iinde gsterilen web sayfasna gtrecektir.
Eer biz webbrowser modln dorudan kendi adyla ie aktarsaydk:
>>> import webbrowser

Bu durumda yukardaki komutu u ekilde vermek zorunda kalacaktk:


>>> webbrowser.open('www.istihza.com')

Ama bu modl daha ksa bir adla ie aktarm olmamz sayesinde, bu modl gayet pratik
bir ekilde kullanma imkanna kavuuyoruz.

from modl_ad import isim1, isim2

imdiye kadar verdiimiz rneklerden de grdnz gibi, Standart Ktphane Modllerinin


iinde ok sayda fonksiyon ve nitelik bulunuyor. Mesela os modln ele alalm:
>>> import os
>>> dir(os)

622 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

Listede epey isim var...


Biz import os komutunu verdiimizde, listedeki btn o isimleri os ismi altnda ie aktarm
oluyoruz. Bunun bir sakncas yok, ancak yazdmz programlarda bu fonksiyon ve niteliklerin
hepsine ihtiya duymayz. O yzden, eer arzu ederseniz, import os gibi bir komutla
btn o isimleri ie aktarmak yerine, yalnzca kullanacanz isimleri ie aktarmay tercih
de edebilirsiniz. Mesela os modlnn yalnzca name niteliini kullanacaksanz, modl u
ekilde ie aktarabilirsiniz:
>>> from os import name

Bu ekilde os modlnden yalnzca name ismi ie aktarlm olur ve yalnzca bu ismi


kullanabiliriz:
>>> name

'posix'

Bu durumda os.name komutu hata verecektir:


>>> os.name

NameError: name 'os' is not defined

nk biz from os import name komutunu verdiimizde, os modln deil, bu modl


iindeki bir nitelik olan name i ie aktarm oluyoruz. Dolaysyla os ismini kullanamyoruz.
Bu ekilde, ayn modl iinden birka farkl nitelik ve fonksiyonu da ie aktarabilirsiniz:
>>> from os import name, listdir, getcwd

Bu komutla os modl iinden yalnzca name niteliini, listdir() fonksiyonunu ve getcwd()


fonksiyonunu aktarm olduk:
>>> listdir()

Bu fonksiyon, o anda iinde bulunduumuz dizindeki dosyalar listeler.


name ve getcwd() isimlerinin grevini ise daha nce renmitik:
>>> name

'nt'

>>> getcwd()

'C:\\Documents and Settings\\fozgul\\'

Gelelim bir baka modl aktarma biimine...

from modl_ad import isim as farkl_isim

Bir modl, kendi adndan farkl bir adla nasl ie aktarabileceinizi biliyorsunuz:
import subprocess as sp

Bu ekilde subprocess modln sp adyla ie aktarm oluyoruz.

37.3. Modllerin e Aktarlmas 623


Python 3 iin Trke Klavuz, Srm 3

Ayn ekilde, bir modl iinden belli nitelik ve fonksiyonlar da nasl ie aktaracanz
biliyorsunuz:
from os import path, listdir

Bu ekilde os modlnden path niteliini ve listdir() fonksiyonunu ie aktarm oluyoruz.


Peki ya bir modl iinden belli nitelik ve fonksiyonlar farkl bir adla ie aktarmak isterseniz
ne yapacaksnz?
te Python size bunun iin de bir yol sunar. Dikkatlice bakn:
from os import path as p

veya:
from os import listdir as ld

gibi...
Bu rneklerde, os modl iinden path adl nitelii p adyla; listdir() fonksiyonunu ise ld
adyla ie aktardk. Bylece path niteliini p adyla; listdir() fonksiyonunu da ld adyla
kullanabiliriz.
Yalnz bu yntem ok sk kullanlmaz. Bunu da not edip, ie aktarma yntemlerinin
sonuncusuna geelim.

from modl_ad import *

Pythondaki modlleri from modl_ad import * formlne gre ie aktarmak da


mmkndr (bu ynteme yldzl ie aktarma diyebilirsiniz). Bu ekilde bir modl iindeki
btn fonksiyon ve nitelikleri ie aktarm oluruz (ismi _ ile balayanlar hari):
>>> from sys import *

Bylece sys modl iindeki btn fonksiyon ve nitelikleri, balarna modl adn eklemeye
gerek olmadan kullanabiliriz:
>>> version

Ancak bu yntem pek tavsiye edilmez. nk bu ekilde, modl iindeki btn isimleri
kontrolsz bir ekilde mevcut ortama boaltm oluyoruz. Mesela eer modl bu ekilde ie
aktarlmadan nce version diye baka bir deiken tanmlamsanz, modl ie aktarldktan
sonra, nceden tanmladnz bu version deikeninin deeri kaybolacaktr:
>>> version = '1.0'
>>> print(version)

1.0

Bu ortama from sys import * komutuyla sys modlnn btn ieriini aktaralm:
>>> from sys import *

imdi de version deikeninin deerini yazdralm:


>>> print(version)

624 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

Burada alacamz kt u olur:


`3.5.1 (default, 20.04.2016, 12:24:55)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'
Grdnz gibi, sys modlnn iindeki version nitelii bizim nceden tanmladmz
version deikeniyle akt ve herhangi bir uyar vermeden, bizim tanmladmz version
deerini silip kendi version deerini bizimkinin yerine geirdi...
from modl_ad import * komutunun yapt eyi, sktrlm bir klasrn btn ieriini
olduu gibi masastne amaya benzetebilirsiniz. Byle bir durumda, eer masastnde
sktrlm klasrdekilerle ayn adl dosyalar varsa, sktrlm klasr iindeki dosya adlar,
masastnde halihazrda varolan dosya adlaryla akacaktr.
Bir sonraki konuya gemeden nce, yldzl ie aktarma ile ilgili nemli bir noktaya deinelim.
Hatrlarsanz, bu konunun banda, modlleri programmzn her yerinden ie
aktarabileceimizi sylemitik. Mesela bir modl, program dosyamzn en banda ie
aktarabiliriz:
from os import *

Ama bunun bir istisnas var. Bir modl yldzl olarak ie aktaracaksak, bu ilemi lokal etki
alanlar iinden gerekletiremeyiz. Yani mesela bir fonksiyonun lokal isim alan iinde yle
bir kod yazabiliriz:
def fonksiyon():
import os

Veya:
def fonksiyon():
import subprocess as sp

Ama yle bir kod yazamayz:


def fonksiyon():
from os import *

Bu kodlar bir dosyaya kaydedip altrdmzda una benzer bir hata alrz:
File "falanca.py", line 1
def fonksiyon():
SyntaxError: import * only allowed at module level

Bunun anlam u: Yldzl ie aktarma ilemleri ancak modl seviyesinde, yani global isim
alannda gerekletirilebilir. Dolaysyla yukardaki ie aktarma ilemini ancak fonksiyonun
dnda gerekletirebiliriz:
from os import *

def fonksiyon():
pass

Veya:
def fonksiyon():
pass

37.3. Modllerin e Aktarlmas 625


Python 3 iin Trke Klavuz, Srm 3

from os import *

Bu istisnai duruma dikkat ediyoruz. Elbette modl ie aktarma ilemlerini gerekletirmenin


en salkl yolu btn modlleri program dosyasnn en banda ie aktarmaktr.

37.4 Kendi Tanmladmz Modller

Buraya gelene kadar sadece Pythondaki hazr modllerden sz ettik. Hazr modllerin,
Standart Ktphane Modlleri ve nc ahs Modlleri olarak ikiye ayrldn
renmitiniz. Yukarda bu hazr modllerin Standart Ktphane Modlleri adn verdiimiz
alt baln halihazrda ele aldk. Dolaysyla artk standart modllerin neler olduunu ve
genel olarak bunlarn nasl kullanldn biliyoruz.
Hazr modl bal altnda bir de nc ahs modllerinin bulunduunu da sylemitik.
Birazdan nc ahs modllerinden de sz edeceiz. Ama isterseniz ondan nce hazr
modllere bir ara verelim ve biraz da kendi modllerimizi nasl yazabileceimize bakalm.
Kendi modllerimizi yazmak, modl konusunu biraz daha net bir ekilde anlamamz
salayacaktr.

37.4.1 Modllerin Tanmlanmas

Hatrlarsanz bu blmn banda, modl nedir? sorusuna u cevab vermitik:


Baz ilevleri kolaylkla yerine getirmemizi salayan birtakm fonksiyonlar ve
nitelikleri iinde barndran aralar...
Esasnda Pythondaki modlleri yle de tanmlayabiliriz:
Diyelim ki bir program yazyorsunuz. Yazdnz bu programn iinde karakter
dizileri, saylar, deikenler, listeler, demetler, szlkler ve fonksiyonlar var.
Programnz da .py uzantl bir metin dosyas iinde yer alyor. te btn bu
eleri ve veri tiplerini ieren .py uzantl dosyaya modl ad verilir. Yani imdiye
kadar yazdnz ve yazacanz btn Python programlar ayn zamanda birer
modl adaydr.
Gelin isterseniz yukardaki bu tanmn doruluunu test edelim.
imdi Pythonn etkileimli kabuunu altrn ve ktphane modllerinden biri olan os
modln ie aktarn:
>>> import os

dir(os) komutunu kullanarak modln ieriini kontrol ettiinizde, o listede __le__ adl bir
niteliin olduunu greceksiniz. Bu nitelik Python ile yazlm tm modllerde bulunur. Bu
nitelii u ekilde kullanyoruz:
>>> os.__file__

`C:\Python35\lib\os.py'
te buradan aldmz kt bize os modlnn kaynak dosyasnn nerede olduunu
gsteriyor. Hemen ktda grnen konuma gidelim ve os.py dosyasn aalm.

626 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

Dosyay atnzda, gerekten de bu modln aslnda sradan bir Python program olduunu
greceksiniz. Dosyann ieriini incelediinizde, dir(os) komutuyla elde ettiimiz nitelik
ve fonksiyonlarn dosya iinde nasl tanmlandn grebilirsiniz. Mesela yeni dizinler
oluturmak iin os.makedirs() eklinde kullandmz makedirs fonksiyonunun os.py iinde
tanmlanm alelade bir fonksiyon olduunu grebilirsiniz.
Ayn ekilde, nceki sayfalarda rneklerini verdiimiz webbrowser modl de,
bilgisayarmzdaki sradan bir Python programndan ibarettir. Bu modln nerede olduunu
da u komutla grebilirsiniz:
>>> import webbrowser
>>> webbrowser.__file__

Grdnz gibi, webbrowser modl de, tpk os modl gibi, bilgisayarmzdaki .py uzantl
bir dosyadan baka bir ey deil. sterseniz bu dosyann da iini ap inceleyebilirsiniz.
Yalnz u gerei de unutmamalyz: Pythondaki btn modller Python programlama dili
ile yazlmamtr. Baz modller C ile yazlmtr. Dolaysyla C ile yazlm bir modln
.py uzantl bir Python dosyas bulunmaz. Mesela sys byle bir modldr. Bu modl C
programlama dili ile yazld iin, kaytl bir .py dosyasna sahip deildir. Dolaysyla bu
modln bir __le__ nitelii de bulunmaz:
>>> import sys
>>> sys.__file__

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__file__'

Ama tabii ki, Pythondaki standart ktphane modllerinin ok byk blm Python ile
yazlmtr ve bu modllerin kaynak dosyalarn os ve webbrowser modllerini bulduunuz
dizinde grebilirsiniz. rnein nceki derslerimizde bahsi geen locale ve random gibi
modllerin kaynak dosyalarn da burada bulabilirsiniz.
Gelelim asl konumuz olan modl tanmlamaya...
Hatrlarsanz, Pythonda bir fonksiyon tanmlamak iin u sz dizimini kullanyorduk:
def fonksiyon_ad(parametreler):
fonksiyon_gvdesi

Ancak yukardaki rneklerden de rahatlkla grebileceiniz gibi, modller iin byle zel bir
sz dizimi yoktur. Yazdnz her Python program ayn zamanda potansiyel bir modldr.
O halde imdi gelin bir tane de kendimiz modl yazalm.
Mesela bir program dosyas oluturalm ve adn da szlk.py koyalm. te bu program, ayn
zamanda bir Python modldr. Bu modln ad da szlktr. Dediimiz gibi, Pythonda
modller genellikle .py uzantsna sahiptir. Ancak bir modln ad sylenirken bu .py uzants
dikkate alnmaz. Bu yzden elinizdeki szlk.py adl programn modl ad szlk olacaktr.
Grdnz gibi, modl tanmlamakta herhangi bir zel zorluk yok. Yazdmz her program,
otomatik olarak, ayn zamanda bir modl oluyor.
szlk.py adl programmzn ierii yle olsun:
szlk = {"kitap" : "book",
"bilgisayar" : "computer",

37.4. Kendi Tanmladmz Modller 627


Python 3 iin Trke Klavuz, Srm 3

"programlama": "programming"}

def ara(szck):
hata = "{} kelimesi szlkte yok!"
return szlk.get(szck, hata.format(szck))

te bylece ilk modlmz tanmlam olduk. imdi de, yazdmz bu modl nasl
kullanacamz renelim.
Esasnda ktphane modlleriyle kendi yazdmz modller arasnda kullanm asndan pek
bir fark yoktur. Bu blmn banda grdmz ktphane modllerini nasl kullanyorsak,
kendi modllerimizi de yle kullanyoruz.
Ktphane modllerini anlatrken grdmz gibi, modl sistemi sayesinde, bir program
iinde bulunan fonksiyon (ve nitelikleri) baka Python programlar iine aktarabiliyoruz.
Bylece bir Python programndaki (veya modlndeki) ilevsellikten, baka bir Python
programnda da yararlanabiliyoruz.
imdi, eer bu szlk.py dosyasn, mesela masastne kaydettiyseniz, masastnn
bulunduu konumda bir komut satr an ve Pythonn etkileimli kabuunu balatn. Tpk
ktphane modllerinde olduu gibi, etkileimli kabukta u komutu vererek szlk adl
modl ie aktarn:
>>> import szlk

Eer hibir ey olmadan bir alt satra geildiyse modlnz baaryla ie aktardnz demektir.
Eer No module named szlk gibi bir hata mesajyla karlayorsanz, muhtemelen Python
szlk.py dosyasnn olduu dizinde balatamamsnzdr.
import szlk komutunun baarl olduunu varsayarak yolumuza devam edelim...

37.4.2 Modllerin Yolu

Python gelitiricilerinin yazp dile kaynatrd ktphane modlleri ile kendi yazdnz
modller arasnda pek bir fark bulunmadn ifade etmitik. Her iki modl tr de, iinde
Python komutlarn ve veri tiplerini barndran alelade Python programlarndan ibarettir.
Ancak imdiye kadar yaptmz rneklerde bir ey dikkatinizi ekmi olmal. Ktphane
modllerini her yerden ie aktarabiliyoruz. Yani, komut satrn altrdmz her
konumda veya program dosyamzn bulunduu her dizin altnda bu modlleri rahatlkla
kullanabiliyoruz. Pythonn bu modlleri bulamamas gibi bir ey sz konusu deil.
Ama kendi yazdmz modlleri ie aktarabilmemiz iin, bu modllerin o anda iinde
bulunduumuz dizin altnda yer almas gerekiyor. Yani mesela yukarda rneini verdiimiz
szlk modln, szlk.py dosyasn bilgisayarmzdaki hangi konuma kaydetmisek o
konumdan ie aktarabiliyoruz.
Diyelim ki szlk.py dosyasn masastne kaydetmitik. te bu modl komut satrnda ie
aktarabilmemiz iin, komut satrn da masastnn bulunduu konumda altrm olmamz
gerekiyor.
Ayn ekilde eer biz bu szlk modln, deneme.py adl baka bir program iinde
kullanacaksak, bu deneme.py dosyasnn da szlk.py adl dosya ile ayn dizinde yer almas
gerekiyor.
Aksi halde, import szlk komutu hata verecektir.

628 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

Peki neden ktphane modllerini her yerden ie aktarabilirken, kendi yazdmz modlleri
yalnzca bulunduklar dizin altnda ie aktarabiliyoruz?
Aslnda bunun cevab ok basit: Biz bir program dosyasnda veya komut satrnda import
modl_ad gibi bir komut verdiimizde Python modl_ad olarak belirttiimiz modl bulmak
iin bir arama ilemi gerekletirir. Elbette Python bu modl sabit diskin tamamnda
aramaz. Python, ie aktarmak istediimiz modl bulmak iin belli birtakm dizinlerin iini
kontrol eder. Peki Python modl dosyasn bulmak iin hangi dizinlerin iine bakar? Bu
sorunun cevabn bize sys modlnn path adl bir nitelii verecek. Hemen bakalm:
>>> import sys
>>> sys.path

te Python bir modl dosyasn ararken, import komutunun verildii dizin ile birlikte,
sys.path ktsnda grnen dizinlerin iine de bakar. Eer modl dosyasn bu dizinlerin
iinde bulursa modl baaryla ie aktarr, ama eer bulamazsa ImportError cinsinden bir
hata verir.
Peki eer biz kendi modllerimizi de her yerden ie aktarabilmek istersek ne yapmamz
gerekiyor?
Bunun iin iki seeneimiz var: Birincisi, modln yolunu sys.path listesine ekleyebiliriz.
kincisi, modlmz sys.path iinde grnen dizinlerden birine kopyalayabilir veya
tayabiliriz.
ncelikle birinci seenei ele alalm.
Grdnz gibi, sys.path komutunun kts aslnda basit bir listeden baka bir ey deildir.
Dolaysyla Pythonda liste adl veri tipi zerinde ne tr ilemler yapabiliyorsanz, sys.path
zerinde de ayn eyleri yapabilirsiniz.
Mesela, modl dosyasnn /home/istihza/programlar adl dizin iinde bulunduunu
varsayarsak, modl dosyasnn yolunu sys.path listesinin en sonuna u ekilde ekleyebiliriz:
sys.path.append(r'/home/istihza/programlar')

Burada listelerin append() metodunu kullandmza dikkat edin. Dediimiz gibi, sys.path
aslnda basit bir listeden ibarettir. Dolaysyla bir listeye nasl e ekliyorsak, sys.pathe de
ayn ekilde e ekliyoruz.
Modl dosyasnn bulunduu /home/istihza/programlar yolunu sys.path listesine
eklediimize gre, artk modlmz her yerden ie aktarabiliriz.
Kendi yazdmz bir modl her yerden ie aktarabilmenin ikinci ynteminin, ilgili modl
dosyasn sys.path ktsnda grnen dizinlerden herhangi birine kopyalamak olduunu
sylemitik. Dolaysyla, sys.path ktsna bakp, modl dosyanz orada grnen dizinlerden
herhangi biri iine kopyalayabilirsiniz. Yaygn olarak tercih edilen konum, Python kurulum
dizini iindeki site-packages adl dizindir. Bu dizinin yerini u ekilde tespit edebilirsiniz:
>>> from distutils import sysconfig
>>> sysconfig.get_python_lib()

Modl dosyanz, bu komutlardan aldnz ktnn gsterdii dizin iine kopyaladktan sonra,
modlnz her yerden ie aktarabilirsiniz.
Bu konuyu kapatmadan nce sys.path ile ilgili nemli bir bilgi daha verelim. Python, ie
aktarmak istediimiz bir modl bulabilmek iin dizinleri ararken sys.path listesindeki dizin

37.4. Kendi Tanmladmz Modller 629


Python 3 iin Trke Klavuz, Srm 3

adlarn soldan saa doru okur. Modl dosyasn bulduu anda da arama ilemini sona
erdirir ve modl ie aktarr. Diyelim ki sys.path ktmz yle:
['A', 'B', 'C']

Eer hem A, hem de B dizininde szlk.py adl bir dosya varsa, Python A dizinindeki
szlk modln ie aktarr. nk sys.path ktsnda A dizini B dizininden nce
geliyor. Eer siz ie aktarma srasnda bir dizine ncelik vermek isterseniz o dizini append()
metoduyla sys.path listesinin sonuna eklemek yerine, insert() metoduyla listenin en bana
ekleyebilirsiniz:
>>> sys.path.insert(0, r'dizin/ad')

Bylece Python, modlnz en baa eklediiniz dizinden ie aktaracaktr.


Tekrar tekrar sylediimiz gibi, sys.path sradan bir listedir. Dolaysyla listelerin zerine
hangi metotlar uygulayabiliyorsanz sys.path zerine de o metotlar uygulayabilirsiniz.

37.4.3 Modllerde Deiiklik Yapmak

Pythonda bir modl baka bir ortama aktarldnda, o modln iinde yer alan nitelik
ve fonksiyonlarn o ortam iinden kullanlabilir hale geldiini biliyorsunuz. Yukardaki
rnekte biz import szlk komutuyla, szlk adl modln btn ieriini etkileimli kabuk
ortamna (veya program dosyasna) aktarm olduk. Dolaysyla da artk bu modln btn
ieriine eriebiliriz. Peki acaba bu modl iinde bizim eriebileceimiz hangi nitelik ve
fonksiyonlar bulunuyor?
Tpk ktphane modllerini ilerken yaptmz gibi, dir() fonksiyonundan yararlanarak, ie
aktardmz bu modl iindeki kullanlabilir fonksiyon ve nitelikleri grebilirsiniz:
>>> dir(szlk)

Bu komut bize yle bir kt verir:


['__builtins__', '__cached__', '__doc__',
'__file__', '__loader__', '__name__',
'__package__', '__spec__', 'ara', 'szlk']

Grdnz gibi, nasl os modlnn iinde name, listdir() ve getcwd() gibi nitelik ve
fonksiyonlar varsa, kendi yazdmz szlk modl iinde de ara() adl bir fonksiyon ve
szlk adl bir nitelik var.
te biz bu fonksiyon ve nitelii kullanma imkanna sahibiz. Gelin birka deneme almas
yapalm:
>>> szlk.szlk

Bu komutun, bir ktphane modlndeki niteliklere erimekten hibir fark olmadna


dikkatinizi ekmek isterim. Mesela sys modlnn version niteliine nasl eriiyorsak, szlk
modlnn szlk niteliine de ayn ekilde eriiyoruz.
szlk.szlk komutu bize szlk modl iindeki szlk adl deikenin ieriini
verecektir.
imdi de ayn modl iindeki ara() fonksiyonuna erielim:

630 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

>>> szlk.ara('kitap')

Bu da bize ara() fonksiyonunu kitap argmanyla birlikte arma imkan veriyor.


Yukarda verdiimiz rnekte szlk modln etkileimli kabuk zerinde kullandk. Elbette
program yazarken modlleri etkileimli kabukta deil, program dosyalar iinde kullanacaz.
Ancak zellikle bir modln gelitirilme aamasnda o modl test etmek iin etkileimli
kabuk zerinde almak olduka pratik ve faydal bir yoldur. Mesela yazmakta olduunuz bir
programn (dier bir deyile modln) nitelik ve fonksiyonlarn test etmek iin, o program
etkileimli kabukta bir modl olarak ie aktarp eitli deneme almalar yapabilirsiniz.
Dilerseniz yine yukardaki rnek zerinden gidelim:
szlk = {"kitap" : "book",
"bilgisayar" : "computer",
"programlama": "programming"}

def ara(szck):
hata = "{} kelimesi szlkte yok!"
return szlk.get(szck, hata.format(szck))

Bu modl ie aktaralm:
>>> import szlk

Modln ieriini kontrol edelim:


>>> dir(szlk)

Bu komutun ktsnda szlk niteliini ve ara() fonksiyonunu gryoruz. Gelin imdi


programmza bir ekleme yapalm:
szlk = {"kitap" : "book",
"bilgisayar" : "computer",
"programlama": "programming"}

def ara(szck):
hata = "{} kelimesi szlkte yok!"
return szlk.get(szck, hata.format(szck))

def ekle(szck, anlam):


mesaj = "{} kelimesi szle eklendi!"
szlk[szck] = anlam
print(mesaj.format(szck))

Burada szlk modlne ekle() adl bir fonksiyon ilave ettik. Bu fonksiyon, szle yeni
kelimeler eklememizi salayacak. imdi tekrar modlmzn ieriini kontrol edelim:
>>> dir(szlk)

Ancak grdnz gibi, modle yeni eklediimiz ekle() fonksiyonu bu ktda grnmyor.
Bunun nedeni, etkileimli kabukta modl bir kez ie aktarldktan sonra, o modlde yaplan
deiikliklerin otomatik olarak etkinlemiyor oluudur. Yani deiikliklerin etkileimli kabukta
etkinleebilmesi iin o modl yeniden yklememiz lazm. Bunu iki ekilde yapabiliriz:
Birincisi, etkileimli kabuu kapatp yeniden atktan sonra import szlk komutuyla szlk
modln tekrar ie aktarabiliriz.

37.4. Kendi Tanmladmz Modller 631


Python 3 iin Trke Klavuz, Srm 3

kincisi, importlib adl bir ktphane modlnden yararlanarak kendi modlmzn tekrar
yklenmesini salayabiliriz. Bu modl yle kullanyoruz:
>>> import importlib
>>> importlib.reload(szlk)

Bu iki komutu verdikten sonra, szlk zerinde tekrar dir() fonksiyonunu uygularsak, yeni
eklediimiz ekle() fonksiyonunun ktya yansdn grrz:
>>> dir(szlk)

['__builtins__', '__cached__', '__doc__', '__file__',


'__loader__', '__name__', '__package__', '__spec__',
'ara', 'ekle', 'szlk']

Tpk nceki derslerimizde grdmz sys, os ve keyword modlleri gibi, importlib de bir
ktphane modldr. Bu modln bizim yukarda yazdmz szlk adl modlden fark,
Python gelitiricileri tarafndan yazlp dile entegre edilmi bir hazr modl olmasdr. Yani
szlk modln biz kendimiz yazdk, importlib modln ise Python gelitiricileri yazd.
kisi arasndaki tek fark bu.
Ne diyorduk? Evet, szlk adl modle ekle() adl yeni bir fonksiyon ilave ettik. Bu
fonksiyona da, tpk szlk niteliinde ve ara() fonksiyonunda olduu gibi, modl adn
kullanarak eriebiliriz:
>>> szlk.ekle('araba', 'car')

araba kelimesi szle eklendi!

Szlmze, araba adl yeni bir kelimeyi, car karl ile birlikte ekledik. Hemen bunu
sorgulayalm:
>>> szlk.ara('araba')

'car'

Gayet gzel! imdi szlmze bir ekleme daha yapalm:


szlk = {"kitap" : "book",
"bilgisayar" : "computer",
"programlama": "programming"}

def ara(szck):
hata = "{} kelimesi szlkte yok!"
return szlk.get(szck, hata.format(szck))

def ekle(szck, anlam):


mesaj = "{} kelimesi szle eklendi!"
szlk[szck] = anlam
print(mesaj.format(szck))

def sil(szck):
try:
szlk.pop(szck)
except KeyError as err:
print(err, "kelimesi bulunamad!")
else:
print("{} kelimesi szlkten silindi!".format(szck))

632 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

Bu defa da modlmze sil() adl baka bir fonksiyon ekledik. Bu fonksiyon, szlkten e
silmemizi salayacak:
>>> szlk.sil('kitap')

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'sil'

Grdnz gibi, bu kez bir hata mesaj aldk. Peki sizce neden? Elbette deiiklik yaptktan
sonra modl yeniden yklemediimizden... O halde nce modlmz yeniden ykleyelim:
>>> importlib.reload(szlk)

imdi bu fonksiyonu kullanabiliriz:


>>> szlk.sil('kitap')

kitap kelimesi szlkten silindi!

Bu noktada, importlib modlnn reload() fonksiyonunun alma sistemine ilikin birka


nemli bilgi verelim.
importlib modlnn reload() fonksiyonu, bir modle yeni eklenen eleri yeniden
ykleyerek, bunlarn etkileimli kabukta kullanlabilir hale gelmesini salar. Bunun ne demek
olduunu biliyoruz. Yukarda bunun rneklerini vermitik.
Eer bir modldeki baz nitelik veya fonksiyonlar silerseniz, importlib modlnn reload()
fonksiyonu ile bu modl yeniden ykledikten sonra bile bu nitelik ve fonksiyonlar nbellekte
tutulmaya devam eder. rnein, yukardaki szlk modln nce ie aktaralm:
>>> import szlk

imdi modln ieriini kontrol edelim:


>>> dir(szlk)

['__builtins__', '__cached__', '__doc__', '__file__',


'__loader__', '__name__', '__package__', '__spec__',
'ara', 'ekle', 'sil', 'szlk']

Modl dosyasndan sil() adl fonksiyonu karalm. Yani modlmzn son hali yle olsun:
szlk = {"kitap" : "book",
"bilgisayar" : "computer",
"programlama": "programming"}

def ara(szck):
hata = "{} kelimesi szlkte yok!"
return szlk.get(szck, hata.format(szck))

def ekle(szck, anlam):


mesaj = "{} kelimesi szle eklendi!"
szlk[szck] = anlam
print(mesaj.format(szck))

Tekrar etkileimli kabua dnp, importlib modlnn reload() fonksiyonu araclyla


modlmz yeniden ykleyelim:

37.4. Kendi Tanmladmz Modller 633


Python 3 iin Trke Klavuz, Srm 3

>>> import importlib


>>> importlib.reload(szlk)

imdi szlk modlnn ieriini tekrar kontrol edelim:


>>> dir(szlk)

['__builtins__', '__cached__', '__doc__', '__file__',


'__loader__', '__name__', '__package__', '__spec__',
'ara', 'ekle', 'sil', 'szlk']

Grdnz gibi, biz sil() fonksiyonunu karm olduumuz halde, dir(szlk) ktsnda
bu e grnmeye devam ediyor. stelik bu fonksiyon halen kullanlabilir durumda!
>>> szlk.sil('programlama')

programlama kelimesi szlkten silindi!

Ancak bu durumu rahatlkla grmezden gelebilirsiniz. Ama eer o enin orada olmas sizi
rahatsz ediyorsa, u komutla o eyi silebilirsiniz:
>>> del szlk.sil

Dediimiz gibi, modlden silinen eler, reload() ile yeniden yklendikten sonra dahi
kullanlr durumda kalmaya devam eder. Ama eer modl iinde varolan bir e zerinde
deiiklik yaparsanz o deiiklik, reload() sonras modln grnmne yansyacaktr. Yani
mesela, modlde halihazrda varolan sil() fonksiyonu zerinde bir deiiklik yaparsanz, bu
deiiklik reload() ile yeniden ykleme sonrasnda etkileimli kabua yansyacaktr.

37.5 nc ahs Modlleri

Buraya kadar Pythondaki ktphane modllerinden ve kendi yazdmz modllerden sz


ettik. Artk modllerin ne olduunu ve ne ie yaradn gayet iyi biliyoruz. Bu blmde ise,
yine bir hazr modl tr olan nc ahs modllerinden bahsedeceiz.
nc ahs modlleri, baka Python programclar tarafndan yazlp hizmetimize sunulmu
programlardr. Bu ynyle bunlar ktphane modllerine ok benzer. Ama bu ikisi
arasnda nemli bir fark bulunur: Ktphane modlleri Python programlama dilinin bir
parasdr. Dolaysyla ktphane modllerini kullanmak iin herhangi bir ek yazlm
indirmemiz gerekmez. nc ahs modlleri ise dilin bir paras deildir. Bu modlleri
kullanabilmek iin, ncelikle bunlar modl gelitiricisinin koyduu yerden bilgisayarmza
indirmemiz gerekir.
Hatrlarsanz ilk derslerimizde Cx_Freeze adl bir yazlmdan sz etmitik. te bu yazlm bir
nc ahs modldr. Bu modl kullanabilmek iin ncelikle ilgili yazlm programmza
kurmamz gerekmiti.
Python iin yazlm nc ahs modllerine eitli kaynaklardan ulaabilirsiniz. Bu tr
modlleri bulabileceiniz en geni kaynak https://pypi.python.org/pypi adresidir. Burada
60.000in zerinde modle ulaabilirsiniz.
Peki bu modlleri nasl kuracaz?
Eer bir modl https://pypi.python.org/pypi adresinde ise, bu modl sistem komut satrnda
u ekilde kurabilirsiniz:

634 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

pip3 install modl_ad

Not: Pythonn 2.7.9 ve 3.4.0 srmlerinden itibaren, pip adl yazlm ntanml olarak
Python kurulumuyla birlikte geliyor. Dolaysyla Python2deki pipi kullanmak isterseniz pip2
komutunu, Python3teki pipi kullanmak isterseniz de pip3 komutunu kullanabilirsiniz.

rnein amacnz Django adl nc ahs modln kurmak ise bu modl u komut ile
kurabilirsiniz:
pip3 install django

Eer bir nc ahs modln https://pypi.python.org/pypi adresinden deil de baka bir


kaynaktan indiriyorsanz, kurulum iin birka farkl seenek olabilir.
Eer indireceiniz dosya Windows iletim sistemine uyumlu bir .exe dosyasysa, bunu
herhangi bir Windows program gibi kurabilirsiniz.
Eer indireceiniz dosya .tar.gz veya .zip gibi sktrlm bir klasr olarak iniyorsa ncelikle
bu sktrlm klasr an. Eer klasr ieriinde setup.py adl bir dosya grrseniz bu
dosyann bulunduu konumda bir komut satr an ve u komutu verin:
python setup.py install

Tabii burada python komutunun python3 m, py -3 m yoksa baka bir ey mi olaca


tamamen sizin Python kurulumunu nasl yaptnza baldr. Neticede siz oraya, Python
hangi komutla balatyorsanz onu yazacaksnz. Yani eer Python python3 komutuyla
balatyorsanz yukardaki komutu yle vereceksiniz:
python3 setup.py install

Ayn ekilde, GNU/Linux kullanclarnn da bu komutu yetkili kullanc olarak vermesi


gerekecektir muhtemelen:
sudo python3 setup.py install

Veya nce:
su -

Ardndan:
python3 setup.py install

ndirip kurduunuz bir nc ahs modln nasl kullanacanz, indirdiiniz modln


belgelerine bakarak renebilirsiniz.

Not: Paketler konusunu ilerken nc ahs modllerinden daha ayrntl bir ekilde sz
edeceiz.

37.6 __all__ Listesi

nceki balklar altnda da ifade ettiimiz gibi, farkl ie aktarma yntemlerini kullanarak,
bir modl iindeki eleri farkl ekillerde ie aktarabiliyoruz. Gelin isterseniz Pythonn ie
aktarma mekanizmasn anlayabilmek iin ufak bir test yapalm.

37.6. __all__ Listesi 635


Python 3 iin Trke Klavuz, Srm 3

imdi masastnde, ierii aadaki gibi olan, modl.py adl bir dosya oluturun:
def fonk1():
print('fonk1')

def fonk2():
print('fonk2')

def fonk3():
print('fonk3')

def fonk4():
print('fonk4')

def fonk5():
print('fonk5')

def _fonk6():
print('_fonk6')

def __fonk7():
print('__fonk7')

def fonk8_():
print('fonk8_')

Daha sonra, masastnn bulunduu konumda bir komut penceresi aarak Pythonn
etkileimli kabuunu altrn ve orada u komutu verip bu modl.py adl dosyay bir modl
olarak ie aktarn:
>>> import modl

imdi de u komutu kullanarak modl ieriini kontrol edin:


>>> dir(modl)

Buradan u kty alyoruz:


['__builtins__', '__cached__', '__doc__', '__file__', '__fonk7',
'__loader__', '__name__', '__package__', '__spec__', '_fonk6',
'fonk1', 'fonk2', 'fonk3', 'fonk4', 'fonk5', 'fonk8_']

Grdnz gibi, modl iinde tanmladmz btn fonksiyonlar bu listede var. Dolaysyla
bu fonksiyonlara u ekilde eriebiliyoruz:
>>> modl.fonk1()

fonk1

>>> modl.fonk2()

fonk2

>>> modl._fonk6()

_fonk6

>>> modl.__fonk7()

636 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

__fonk7

>>> modl.fonk8_()

fonk8_

Bu ekilde, istisnasz btn fonksiyonlara eriim yetkisi elde ettiimize dikkatinizi ekmek
isterim.
imdi etkileimli kabuu kapatp tekrar aalm ve bu kez modlmz u ekilde ie
aktaralm:
>>> from modl import *

Bu ekilde, ismi _ ile balayanlar hari btn fonksiyonlar, modl neki olmadan mevcut etki
alanna aktardmz biliyoruz.
Kontrol edelim:
>>> dir()

Buradan u kty alyoruz:


['__builtins__', '__doc__', '__loader__', '__name__',
'__package__', '__spec__', 'fonk1', 'fonk2', 'fonk3',
'fonk4', 'fonk5', 'fonk8_']

Grdnz gibi, gerekten de ismi _ ile balayanlar hari, btn fonksiyonlar, modl neki
olmadan kullanlmaya hazr bir ekilde mevcut etki alanmz iinde grnyor. Bunlar u
ekilde kullanabileceimizi biliyorsunuz:
>>> fonk4()

fonk4

>>> fonk8_()

fonk8_

Elbette, ismi _ ile balayan fonksiyonlar, dorudan isimlerini kullanarak ie aktarma imkanna
sahipsiniz:
>>> from modl import __fonk7
>>> from modl import _fonk6

Tabii, bu fonksiyonlar ie aktarabilmek iin bunlarn isimlerini biliyor olmanz lazm...


Peki siz, yazdnz bir programda yalnzca kendi belirlediiniz isimlerin ie aktarlmasn
isterseniz ne yapacaksnz? te bunun iin, balkta szn ettiimiz __all__ adl bir listeden
yararlanabilirsiniz.
imdi biraz nce oluturduunuz modl.py dosyasnn en bana u satr ekleyin:
__all__ = ['fonk1', 'fonk2', 'fonk3']

Daha sonra etkileimli kabukta modlnz u ekilde ie aktarn:

37.6. __all__ Listesi 637


Python 3 iin Trke Klavuz, Srm 3

>>> from modl import *

imdi de ie aktarlan fonksiyonlarn neler olduunu kontrol edin:


>>> dir()

['__builtins__', '__doc__', '__loader__', '__name__', '__package__',


'__spec__', 'fonk1', 'fonk2', 'fonk3']

Grdnz gibi, yalnzca __all__ listesi iinde belirttiimiz fonksiyonlar ie aktarld. Bu


listeyi kullanarak, yldzl ie aktarmalarda nelerin ie aktarlp nelerin darda braklacan
kontrol edebilirsiniz. Yalnz unutmamanz gereken nokta, bu yntemin teki ie aktarma
trlerinde hibir ie yaramayacadr. Yani mesela modl adl modlmz import modl
eklinde ie aktarrsak __all__ listesi dikkate alnmayacaktr.
Peki ya __all__ listesini bo brakrsak ne olur?
__all__ = []

Tabii ki, bu ekilde yldzl aktarmalarda (modln kendi varsaylan fonksiyonlar hari) hibir
fonksiyon ie aktarlmaz...

37.7 Modllerin zel Nitelikleri

Pythonda btn modllerin ortak olarak sahip olduu baz nitelikler vardr. Bu niteliklerin
hangileri olduunu grmek iin kesiim kmelerinden yararlanarak yle bir kod yazabiliriz:
import os, sys, random

set_os = set(dir(os))
set_sys = set(dir(sys))
set_random = set(dir(random))

print(set_os & set_sys & set_random)

Bu kodlar, os, sys ve random modllerinin kesiim kmesini, yani her modlde ortak
olarak bulunan nitelikleri verecektir. Bu kodlar altrdmzda u kty alyoruz:
{'__doc__', '__package__', '__loader__', '__name__', '__spec__'}

Demek ki hem os hem sys hem de random modlnde ortak olarak bulunan nitelikler
bunlarm... Eer bu modln btn modlleri temsil etmiyor olabileceinden endie
ediyorsanz, bildiiniz baka modlleri de bu kodlara ekleyerek testinizin kapsamn
geniletebilirsiniz.
Mesela bu kodlara bir de subprocess modln ekleyelim:
import os, sys, random, subprocess

set_os = set(dir(os))
set_sys = set(dir(sys))
set_random = set(dir(random))
set_subprocess = set(dir(subprocess))

print(set_os & set_sys & set_random & set_subprocess)

638 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

Yalnz burada yle bir ey dikkatinizi ekmi olmal: Kesiim kmesini bulmak istediimiz
elere baka eler de eklemek istediimizde her defasnda birka farkl ilem yapmak
zorunda kalyoruz. Bu da hem kodlarmz hatalara ak hale getiriyor, hem de aslnda kolayca
halledebileceimiz bir ii gereksiz yere uzatmamza yol ayor.
Gelin bu kodlar biraz daha genel amal bir hale getirelim. Zira kodlarn yeniden kullanlabilir
zellikte olmas (code reusability ) programclkta aranan bir niteliktir:
modller = ['os', 'sys', 'random']

def kesiim_bul(modller):
kmeler = [set(dir(__import__(modl))) for modl in modller]
return set.intersection(*kmeler)

print(kesiim_bul(modller))

Eer bu kodlara yeni bir modl eklemek istersek, yapmamz gereken tek ey en bataki
modller listesini gncellemek olacaktr. Mesela bu listeye bir de subprocess modln
ekleyelim:
modller = ['os', 'sys', 'random', 'subprocess']

def kesiim_bul(modller):
kmeler = [set(dir(__import__(modl))) for modl in modller]
return set.intersection(*kmeler)

print(kesiim_bul(modller))

Grdnz gibi, bu kodlar iimizi epey kolaylatrd. Sadece tek bir noktada deiiklik
yaparak istediimiz sonucu elde ettik.
Bu arada, __import__() fonksiyonu hari, bu kodlardaki her eyi daha nceki derslerimizde
renmitik. Ama gelin isterseniz biz yine de bu kodlarn zerinden yle bir geelim.
Burada ilk yaptmz i, kullanmak istediimiz modl adlarn tutmas iin bir liste
tanmlamak:
modller = ['os', 'sys', 'random', 'subprocess']

Bu listede modl adlarnn birer karakter dizisi olarak gsterildiine dikkat edin. Zaten bu
modlleri henz ie aktarmadmz iin, bunlar dorudan trnaksz isimleriyle kullanamayz.
Daha sonra, asl ii yapacak olan kesiim_bul() adl fonksiyonumuzu tanmlyoruz:
def kesiim_bul(modller):
kmeler = [set(dir(__import__(modl))) for modl in modller]
return set.intersection(*kmeler)

Bu fonksiyon, modller adl tek bir parametre alyor.


Fonksiyonumuzun gvdesinde ilk olarak yle bir kod yazyoruz:
kmeler = [set(dir(__import__(modl))) for modl in modller]

Burada modller adl listedeki her e zerine srasyla __import() fonksiyonunu, dir()
fonksiyonunu ve set() fonksiyonunu uyguluyoruz. Daha sonra elde ettiimiz sonucu bir liste
reteci yardmyla liste haline getirip kmeler deikenine atyoruz.
Gelelim __import__() fonksiyonunun ne olduuna...

37.7. Modllerin zel Nitelikleri 639


Python 3 iin Trke Klavuz, Srm 3

Bir gml fonksiyon olan __import__() fonksiyonu, modl adlarn ieren karakter dizilerini
kullanarak, herhangi bir modl ie aktarmamz salayan bir aratr. Bu fonksiyonunu yle
kullanyoruz:
>>> __import__('os')
>>> __import__('sys')

Bu fonksiyonun parametre olarak bir karakter dizisi alyor olmasnn bize nasl bir esneklik
saladna dikkatinizi ekmek isterim. Bu fonksiyon sayesinde modl aktarma ilemini, kod
paralar iine programatik olarak yerletirebilme imkan elde ediyoruz. Yani, modl aktarma
ilemini mesela bir for dngs iine alamyorken:
>>> modller = ['os', 'sys', 'random']
>>> for modl in modller:
... import modl
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ImportError: No module named 'modl'

__import__() fonksiyonu bize byle bir ilem yapabilme olana sunuyor:


>>> modller = ['os', 'sys', 'random']
>>> for modl in modller:
... __import__(modl)

<module 'os' from 'C:\\Python34\\lib\\os.py'>


<module 'sys' (built-in)>
<module 'random' from 'C:\\Python34\\lib\\random.py'>

Yalnz, __import__(os) gibi bir komut verdiimizde, os ismi dorudan kullanlabilir hale
gelmiyor. Yani:
>>> __import__('os')

...komutunu verdiimizde, mesela os modlnn bir nitelii olan name i kullanamyoruz:


>>> os.name

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
NameError: name 'os' is not defined

os ismini kullanabilmemiz iin yle bir ey yazm olmalydk:


>>> os = __import__('os')

Eer __import__() fonksiyonu yardmyla ie aktardmz os modln bu ekilde bir isme


atamazsak, __import__(os) komutu ile ie aktarlan btn os fonksiyon ve nitelikleri, bu
komut bir kez altktan sonra unutulacaktr. Eer __import__() fonksiyonunu bir isme
atamadan, ie aktarlan modln niteliklerine erimek isterseniz ie aktarma ilemi ile nitelie
erime ilemini ayn satrda gerekletirmeniz gerekir:
>>> __import__('os').name

'nt'

640 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

__import__() fonksiyonu ok sk kullanacanz bir ara deildir. Ancak zellikle tek satrda
hem bir modl ie aktarmanz, hem de hemen ardndan baka ilemler yapmanz gereken
durumlarda bu fonksiyon iinize yarayabilir:
>>> open('den.txt', 'w').write('merhaba'); __import__('subprocess').call('notepad.exe den.txt')

Gerekli modlleri ie aktardktan ve kmemimizi tanmladktan sonra da fonksiyon tanmn


u kodla bitiriyoruz:
return set.intersection(*kmeler)

Burada kmelerin intersection() metodundan faydalandk. Bu metodu nceki


derslerimizde ele almtk. Bu metot yardmyla birden fazla kmenin kesiimini
bulabiliyoruz.
Bu fonksiyonu normalde yle kullanyorduk:
>>> kme1.intersection(kme2)

Bu komut, kme1 ile kme2 adl kmelerin kesiimini bulacaktr. Eer bizim kodlarmzda
olduu gibi kme ismi belirtmeksizin birden fazla kmenin kesiimini bulmak isterseniz bu
metodu dorudan kme veri tipi (set ) zerine uygulayabilirsiniz:
>>> set.intersection(kme1, kme2)

Eer intersection() metoduna parametreleri bir liste iinden atamak isterseniz bu listeyi
yldz ileci yardmyla zmeniz gerekir:
>>> liste = [kme1, kme2, kme3]
>>> set.intersection(*liste)

te bizim yukarda return set.intersection(*kmeler) komutuyla yaptmz ey de tam


olarak budur. Burada intersection() metodunu dorudan set veri tipi zerine uyguladk ve
bu metodun parametrelerini kmeler adl listeden yldz ileci yardmyla zdk.
Son olarak da, tanmladmz kesiim_bul() fonksiyonunu modller adl parametre ile
ardk:
print(kesiim_bul(modller))

Btn bu kodlar altrdktan sonra ise yle bir kt elde ettik:


{'__doc__', '__name__', '__loader__', '__spec__', '__package__'}

te bu blmn konusu, btn modllerde ortak olan bu be zel nitelik. lk olarak


__doc__ nitelii ile balayalm.

37.7.1 __doc__ Nitelii

sterseniz __doc__ niteliini tarif etmeye almak yerine, bunu bir rnek zerinden anlatalm.
imdi Python kurulum dizini iinde os.py dosyasnn bulunduu konuma gidelim ve bu
dosyay aalm. Dosyay atnzda, sayfann en banda u karakter dizisini greceksiniz:
r"""OS routines for NT or Posix depending on what system we're on.

This exports:
- all functions from posix, nt or ce, e.g. unlink, stat, etc.

37.7. Modllerin zel Nitelikleri 641


Python 3 iin Trke Klavuz, Srm 3

- os.path is either posixpath or ntpath


- os.name is either 'posix', 'nt' or 'ce'.
- os.curdir is a string representing the current directory ('.' or ':')
- os.pardir is a string representing the parent directory ('..' or '::')
- os.sep is the (or a most common) pathname separator ('/' or ':' or '\\')
- os.extsep is the extension separator (always '.')
- os.altsep is the alternate pathname separator (None or '/')
- os.pathsep is the component separator used in $PATH etc
- os.linesep is the line separator in text files ('\r' or '\n' or '\r\n')
- os.defpath is the default search path for executables
- os.devnull is the file path of the null device ('/dev/null', etc.)

Programs that import and use 'os' stand a better chance of being
portable between different platforms. Of course, they must then
only use functions that are defined by all platforms (e.g., unlink
and opendir), and leave all pathname manipulation to os.path
(e.g., split and join).
"""

imdi Pythonn etkileimli kabuunu an ve u komutlar verin:


>>> import os
>>> print(os.__doc__)

Bu komutlar verdiinizde, yukardaki karakter dizisinin kt olarak verildiini greceksiniz.


Teknik dilde, trnak iinde gsterilen karakter dizilerine belge dizisi (docstring ) veya
belgelendirme dizisi (documentation string ) ad verilir. Modllerin __doc__ niteliini
kullanarak, bir modl dosyasnn en banda bulunan belgelendirme dizilerine eriebiliriz.
Bir rnek daha verelim. Mesela random modlne bakalm:
>>> import random
>>> print(random.__doc__)

os.py dosyas ile ayn konumda bulunan random.py dosyasn atnzda, yukardaki
komutlardan aldnz ktnn random.py dosyasnn en bandaki uzun karakter dizisi
olduunu greceksiniz.
eitli yazlmlar, bu belge dizilerini kullanarak, ilgili modle ilikin ksa klavuzlar oluturur.
Mesela Pythonn help() fonksiyonu bu belge dizilerinden yararlanr:
>>> help(os)

Siz de kendi yazdnz modllerde bu belge dizilerinden yararlanabilirsiniz. Ancak aklnzda


bulundurmanz gereken nemli nokta, bu belge dizilerini trnak iinde belirtmeniz
gerektiidir. Alt alta ift veya tek trnak ile tanmladnz karakter dizilerine __doc__ nitelii
araclyla erimeye altnzda sadece ilk satrdaki karakter dizisine ularsnz. Yani:
"satr1"
"satr2"
"satr3"

...eklinde tanmladnz karakter dizileri __doc__ nitelii ile arldnda yalnzca satr1
grntlenecektir. Eer bu satrn da kapsama alanna girmesini istiyorsak yukardaki
karakter dizilerini yle tanmlamalyz:

642 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

'''
satr1
satr2
satr3
'''

37.7.2 __name__ Nitelii

yle bir program yazdmz varsayalm:


szlk = {"kitap" : "book",
"bilgisayar" : "computer",
"programlama": "programming"}

def ara(szck):
hata = "{} kelimesi szlkte yok!"
print(szlk.get(szck, hata.format(szck)))

def ekle(szck, anlam):


mesaj = "{} kelimesi szle eklendi!"
szlk[szck] = anlam
print(mesaj.format(szck))

def sil(szck):
try:
szlk.pop(szck)
except KeyError as err:
print(err, "kelimesi bulunamad!")
else:
print("{} kelimesi szlkten silindi!".format(szck))

no = input('Yapmak istediiniz ilemin numarasn girin: ')


print('1. Szlkte kelime ara')
print('2. Szle kelime ekle')
print('3. Szlkten kelime sil')

if no == '1':
szck = input('Aradnz szck: ')
ara(szck)

elif no == '2':
szck = input('Ekleyeceiniz szck: ')
anlam = input('Eklediiniz szcn anlam: ')
ekle(szck, anlam)

elif no == '3':
szck = input('Sileceiniz szck: ')
sil(szck)

else:
print('Yanl ilem')

szlk.py adn verdiimiz bu program normal bir ekilde komut satrnda


python szlk.py

37.7. Modllerin zel Nitelikleri 643


Python 3 iin Trke Klavuz, Srm 3

gibi bir komutla altrdmzda bize birtakm sorular sorulacak ve verdiimiz cevaplara gre
szlk zerinde baz ilemler yaplacaktr.
Hatrlarsanz, modller konusunu anlatmaya balarken, yazdmz btn programlarn
aslnda birer modl olduunu, dolaysyla bunlarn baka programlarn iine aktarlarak, sahip
olduklar ilevlerden baka programlarda da yararlananlabileceini sylemitik.
Yukardaki kodlar, komut satr zerinde bamsz bir program gibi altrabiliyoruz. Peki
acaba biz bu program dorudan altrmak deil de baka bir programn iine aktarp sahip
olduu ilevlerden yararlanmak istersek ne yapacaz?
te bunun iin __name__ adl bir nitelikten yararlanacaz.
Pythondaki herhangi bir modl ie aktardktan sonra bu modl zerine dir() fonksiyonunu
uygularsanz, istisnasz her modln __name__ adl bir nitelii olduunu grrsnz.
__name__ nitelii iki farkl deer alabilir: inde bulunduu modln ad veya "__main__" adl
zel bir deer.
Eer bir Python program baka bir program iinden modl olarak ie aktarlyorsa,
__name__ niteliinin deeri o modln ad olacaktr.
Eer bir Python program dorudan bamsz bir program olarak altrlyorsa,
__name__ niteliinin deeri bu defa "__main__" olacaktr.
Gelin isterseniz bu durumu bir rnek zerinde somutlatralm. Mesela masastnde
deneme.py adl bir dosya oluturup iine sadece unu yazalm:
print(__name__)

imdi nce bu dosyay bamsz bir program olarak altralm:


python deneme.py

Programmz bu ekilde altrdmzda alacamz kt u olacaktr:


__main__

Demek ki __name__ niteliinin deeri "__main__" imi...


imdi de deneme.py dosyasnn bulunduu konumda Pythonn etkileimli kabuunu
altralm ve u komut yardmyla bu dosyay bir modl olarak ie aktaralm:
>>> import deneme

Bu defa u kty aldk:


deneme

Grdnz gibi, __name__ niteliinin deeri bu kez de modl dosyasnn ad oldu.


te bu zellikten yararlanarak, yazdnz programlarn bamsz altrlrken ayr, modl
olarak ie aktarlrken ayr davranmasn salayabilirsiniz.
Gelin bu bilgiyi yukardaki szlk.py dosyasna uygulayalm.
Bu program komut satr zerinde bamsz bir program olarak altrdnzda ne olacan
biliyorsunuz. Peki ya ayn program bir modl olarak ie aktarrsak ne olur?
Deneyelim:

644 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

>>> import szlk

Yapmak istediiniz ilemin numarasn girin:

Grdnz gibi, programmz dorudan almaya balad. Ama biz bunu istemiyoruz. Biz
istiyoruz ki, szlk.py bir modl olarak aktarldnda almaya balamasn. Ama biz onun
iindeki nitelikleri kullanabilelim.
Bunun iin szlk.py dosyasnda u deiiklii yapacaz:
szlk = {"kitap" : "book",
"bilgisayar" : "computer",
"programlama": "programming"}

def ara(szck):
hata = "{} kelimesi szlkte yok!"
print(szlk.get(szck, hata.format(szck)))

def ekle(szck, anlam):


mesaj = "{} kelimesi szle eklendi!"
szlk[szck] = anlam
print(mesaj.format(szck))

def sil(szck):
try:
szlk.pop(szck)
except KeyError as err:
print(err, "kelimesi bulunamad!")
else:
print("{} kelimesi szlkten silindi!".format(szck))

#BURAYA DKKAT!!!
if __name__ == '__main__':
no = input('Yapmak istediiniz ilemin numarasn girin: ')
print('1. Szlkte kelime ara')
print('2. Szle kelime ekle')
print('3. Szlkten kelime sil')

if no == '1':
szck = input('Aradnz szck: ')
ara(szck)

elif no == '2':
szck = input('Ekleyeceiniz szck: ')
anlam = input('Eklediiniz szcn anlam: ')
ekle(szck, anlam)

elif no == '3':
szck = input('Sileceiniz szck: ')
sil(szck)

else:
print('Yanl ilem')

Grdnz gibi, ok basit bir if deyimi yardmyla dosyamzn bamsz bir program
olarak m altrldn yoksa bir modl olarak ie mi aktarldn kontrol ettik. Eer
__name__ niteliinin deeri __main__ ise, yani programmz bamsz olarak altrlyorsa

37.7. Modllerin zel Nitelikleri 645


Python 3 iin Trke Klavuz, Srm 3

if blou iindeki kodlar iletiyoruz. Eer bu niteliin deeri baka bir ey ise (yani modln
ad ise), bu durumda programmz bir modl olarak ie aktarlyor demektir. Bu durumda if
blou iindeki kodlar altrmyoruz...
Her eyin yolunda olup olmadn kontrol etmek iin szlk modln ie aktaralm:
>>> import szlk

Bu kez, tam da istediimiz ekilde, programmz dorudan almaya balamadan bize


iindeki fonksiyonlar kullanma imkan sundu:
>>> dir(szlk)

['__builtins__', '__cached__', '__doc__', '__file__',


'__loader__', '__name__', '__package__', '__spec__',
'ara', 'ekle', 'sil', 'szlk']

37.7.3 __loader__ Nitelii

Pythonda ie aktarlan btn modllerin __loader__ adl bir nitelii bulunur. Bu nitelik, ilgili
modl ie aktaran mekanizma hakknda bize eitli bilgiler veren birtakm aralar sunar:
>>> import os
>>> ykleyici = os.__loader__

>>> dir(ykleyici)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',


'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__le__', '__lt__', '__module__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', '__weakref__', '_cache_bytecode',
'exec_module', 'get_code', 'get_data', 'get_filename', 'get_source',
'is_package', 'load_module', 'name', 'path', 'path_mtime', 'path_stats',
'set_data', 'source_to_code']

Mesela, ie aktardnz bir modln kaynak kodlarn grntlemek iin bu modlden


yararlanabilirsiniz:
>>> import webbrowser
>>> ykleyici = webbrowser.__loader__
>>> kaynak = ykleyici.get_data(webbrowser.__file__)
>>> kaynak

Burada, daha nce rendiimiz __le__ niteliini kullandmza dikkat edin.


__loader__ niteliinin get_data() adl metodu, parametre olarak, sorgulayacamz
modln dizin adresini ister. Bir modln dizin adresini __le__ nitelii yardmyla
elde edebileceimizi biliyoruz. Dolaysyla da get_data() metoduna parametre olarak
webbrowser.__file__ kodunu veriyoruz. Elde ettiimiz ey ise, sorguladmz modln
kaynak kodlarn ieren bir bayt (bytes ) veri tipi oluyor.
__loader__, gnlk olarak kullanacamz bir ara deil. Eer yazdnz kodlarda bu niteliin
sunduu olanaklara ihtiya duyarsanz, dorudan bu nitelik yerine pkgutil adl bir modl
kullanabilirsiniz.

646 Blm 37. Modller


Python 3 iin Trke Klavuz, Srm 3

37.7.4 __spec__ Nitelii

__spec__ nitelii de bize modller hakknda eitli bilgiler sunan birtakm aralar iinde
barndrr. Mesela bir modln ad ve konum bilgilerine ulamak iin bu nitelii kullanabiliriz:
>>> import subprocess
>>> ad = subprocess.__spec__.name
>>> konumu = subprocess.__spec__.origin
>>> ad

'subprocess'

>>> konumu

'C:\\Pythonxy\\lib\\subprocess.py'

Tpk __loader__ gibi, bu nitelik de gnlk olarak kullanacamz bir ara deil. Bu niteliin
iindeki aralarn sunduu bilgileri baka yollardan da elde edebileceimizi biliyorsunuz.

37.7.5 __package__ Nitelii

Henz bu niteliin ne olduunu anlayacak bilgiye sahip olmadmz iin, bu niteliin


incelemesini Paketler konusunu ilediimiz blme brakyoruz.
Bylece modller konusunu tamamlam olduk. Bu blmde modllere ilikin epey bilgi
verdik. Eer modller konusunda aklnza yatmayan yerler varsa, hi mitsizlie kaplmadan
okumaya devam edin. Birazdan snar konusunu ilerken, modllerden ve modllerin
eitli zelliklerinden de sz edeceiz. O zaman, burada anlamam olabileceiniz konular
ok daha net bir ekilde anlayacaksnz.

37.7. Modllerin zel Nitelikleri 647


BLM 38

Nesne Tabanl Programlama (OOP)

Bu blmde, programlama faaliyetlerimizin nemli bir ksmn oluturacak olan nesne


tabanl programlama yaklamna bir giri yaparak, bu yaklamn temel kavramlarndan
biri olan snara deineceiz. Bu blmde amacmz, snar zerinden hem nesne
tabanl programlamay tanmak, hem bu yaklama ilikin temel bilgileri edinmek, hem de
etrafmzda grdmz nesne tabanl yaplarn byk ounluunu anlayabilecek seviyeye
gelmek olacaktr. Bu blm tamamladktan sonra, nesne tabanl programlamay orta
dzeyde bildiimizi iddia edebileceiz.

38.1 Giri

imdiye kadar Python programlama dili ile ilgili olarak grdmz konulardan rendiimiz
ok nemli bir bilgi var: Aslna bakarsak, bu programlama dilinin btn felsefesi, bir kez
yazlan kodlarn en verimli ekilde tekrar tekrar kullanlabilmesi, krine dayanyor.
imdi bir geriye dnp baktmzda, esasnda bu krin izlerini ta ilk derslerimize kadar
srebiliyoruz. Mesela deikenleri ele alalm. Deikenleri kullanmamzdaki temel gereke,
bir kez yazdmz bir kodu baka yerlerde rahata kullanabilmek. rnein, isim = Uzun
hsan Efendi gibi bir tanmlama yaptktan sonra, bu isim deikeni araclyla Uzun
hsan Efendi adl karakter dizisini her defasnda tekrar tekrar yazmak zorunda kalmadan,
kodlarmzn her yannda kullanabiliyoruz.
Ayn krin fonksiyonlar ve geen blmde incelediimiz modller iin de geerli olduunu
bariz bir ekilde grebilirsiniz. Gml fonksiyonlar, kendi tanmladmz fonksiyonlar,
hazr modller, nc ahs modlleri hep belli bir karmak sreci basitletirme, bir kez
tanmlanan bir prosedrn tekrar tekrar kullanlabilmesini salama amac gdyor.
te bu kir nesne tabanl programlama ve dolaysyla snf (class ) ad verilen zel bir veri tipi
iin de geerlidir. Bu blmde, bunun neden ve nasl byle olduunu btn ayrntlaryla ele
almaya alacaz.
Bu arada, ngilizcede Object Oriented Programming olarak ifade edilen programlama
yaklam, Trkede Nesne Tabanl Programlama, Nesne Ynelimli Programlama ya da
Nesneye Ynelik Programlama olarak karlk bulur. Biz bu karlklardan, ad Nesne Tabanl
Programlama olan tercih edeceiz.
Unutmadan, nesne tabanl programlamaya girmeden nce deinmemiz gereken bir ey
daha var. Eer rendiiniz ilk programlama dili Python ise, nesne tabanl programlamay
renmenin (aslnda yle olmad halde) zor olduunu dnebilir, bu konuyu biraz

648
Python 3 iin Trke Klavuz, Srm 3

karmak bulabilirsiniz. Bu durumda da kanlmaz olarak kendi kendinize u soruyu


sorarsnz: Acaba ben nesne tabanl programlamay renmek zorunda mym?
Bu sorunun ksa cevab, eer iyi bir programc olmak istiyorsanz nesne tabanl
programlamay renmek zorundasnz, olacaktr.
Uzun cevap ise u:
Nesne tabanl programlama, pek ok yazlm gelitirme ynteminden yalnzca biridir.
Siz bu yntemi, yazdnz programlarda kullanmak zorunda deilsiniz. Nesne tabanl
programlamadan hi yararlanmadan da faydal ve iyi programlar yazabilirsiniz elbette.
Python sizi bu yntemi kullanmaya asla zorlamaz. Ancak nesne tabanl programlama
yaklam program gelitirme alannda olduka yaygn kullanlan bir yntemdir. Dolaysyla,
etrafta nesne tabanl programlama yaklamndan yararlanlarak yazlm pek ok kodla
karlaacaksnz. Hi deilse karlatnz bu kodlar anlayabilmek iin nesne tabanl
programlamay biliyor ve tanyor olmanz lazm. Aksi halde, bu yntem kullanlarak
gelitirilmi programlar anlayamazsnz.
Mesela, grak bir arayze sahip (yani dmeli, menl) programlarn ezici ounluu nesne
tabanl programlama yntemiyle gelitiriliyor. Grak arayz gelitirmenizi salayacak aralar
tanmanz, renmenizi salayan kitaplar ve makaleler de bu konular hep nesne tabanl
programlama yaklam zerinden anlatyor.

Uyar: Yalnz bu sylediimizden, nesne tabanl programlama sadece grak


arayzl programlar gelitirmeye yarar gibi bir anlam karmamalsnz. Nesne tabanl
programlama, komut arayzl programlar gelitirmek iin de kullanl bir programlama
yntemidir.

Szn z, nesne tabanl programlamadan kaamazsnz! yi bir programc olmak istiyorsanz,


kendiniz hi kullanmasanz bile, nesne tabanl programlamay renmek zorundasnz. Hem
imdi nesne tabanl programlamaya dudak bkseniz bile, bunu kullandka ve size salad
faydalar grdke onu siz de seveceksiniz...

38.2 Snar

Nesne tabanl programlamann temelinde, yukardaki giri blmnde de adn andmz


snf (class ) adl bir kavram bulunur. Bu blmde, bu temel kavram hakkyla ele almaya
alacaz.
Peki tam olarak nedir bu snf denen ey?
ok kaba ve olduka soyut bir ekilde tanmlayacak olursak, snar, nesne retmemizi
salayan veri tipleridir. te nesne tabanl programlama, adndan da anlalaca gibi,
nesneler (ve dolaysyla snar) temel alnarak gerekletirilen bir programlama faaliyetidir.
Hibir ey anlamadm! dediinizi duyar gibiyim. nk yukardaki tanm, nesne ne
demek, snf ne anlama geliyor gibi sorulara cevap vermiyor. Yani programclk asndan
nesne ve snf kelimelerini burada ne anlamda kullandmz, yukardaki tanma bakarak
kestiremiyoruz. Eer siz de bu kirdeyseniz okumaya devam edin...

38.2. Snar 649


Python 3 iin Trke Klavuz, Srm 3

38.3 Snar Ne e Yarar?

Buraya gelene kadar Pythonda pek ok veri tipi olduunu rendik. Mesela nceki
derslerimizde incelediimiz listeler, demetler, karakter dizileri, szlkler ve hatta fonksiyonlar
hep birer veri tipidir. Bu tiplerin, verileri eitli ekillerde evirip evirmemizi salayan birtakm
aralar olduunu biliyoruz. te snar da, tpk yukarda saydmz teki veri tipleri gibi,
verileri maniple etmemizi salayan bir veri tipidir.
Peki bu blmde ele alacamz snf (class ) veri tipi ne ie yarar?
Dilerseniz bunu basit bir rnek zerinde anlatmaya alalm.
Diyelim ki, kullancnn girdii bir kelimedeki sesli hareri sayan bir kod yazmak istiyorsunuz.
Bu amac gerekletirebilmek iin yazabileceiniz en basit kod herhalde u olacaktr:
sesli_harfler = 'aeiou'
saya = 0

kelime = input('Bir kelime girin: ')

for harf in kelime:


if harf in sesli_harfler:
saya += 1

mesaj = '{} kelimesinde {} sesli harf var.'


print(mesaj.format(kelime, saya))

Dzgn bir ekilde alan, gayet basit kodlardr bunlar. Ayrca amacmz da kusursuz bir
ekilde yerine getirir. stelik kodlardaki btn eler tek bir isim/etki alan (namespace,
scope ) iinde bulunduu iin, bunlara eriimde hibir zorluk ekmeyiz. Yani mesela
sesli_harer, saya, kelime, harf, mesaj deikenlerine kodlar iinde her yerden eriebiliriz.

Not: Eer isim/etki alan ile ilgili sylediimiz eyi anlamadysanz endie etmeyin. Birazdan
vereceimiz rnekle durumu daha net kavrayacaksnz.

Ancak bu kodlarn nemli bir dezavantaj, kodlarda benimsediimiz yaklamn genilemeye


pek msait olmamasdr. Daha dorusu, yukardaki kodlara yeni kodlar ekledike
programmz karmak hale gelecek, kodlar anlamak zorlaacaktr.
Kod yapsn biraz olsun rahatlatmak iin baz nlemler alabiliriz. Mesela kullanc tarafndan
girilen kelimedeki bir harn sesli olup olmadn denetleyen kodlar bir fonksiyon iine
alarak, o ksm daha belirgin hale getirebiliriz:
sesli_harfler = 'aeiou'
saya = 0

kelime = input('Bir kelime girin: ')

def seslidir(harf):
return harf in sesli_harfler

for harf in kelime:


if seslidir(harf):
saya += 1

650 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

mesaj = '{} kelimesinde {} sesli harf var.'


print(mesaj.format(kelime, saya))

Burada, kontrol ettiimiz harn sesli_harer adl deiken iinde bulunup bulunmamasna
gre True veya False kts veren, seslidir() adl bir fonksiyon tanmladk. Eer kontrol
ettiimiz harf sesli_harer deikeni iinde geiyorsa, yani bu bir sesli harf ise, seslidir()
fonksiyonu True kts verecektir. Aksi durumda ise bu fonksiyondan False kts alacaz.
Bylece sesli harf kontrol yapmak istediimiz her yerde yalnzca seslidir() fonksiyonunu
kullanabileceiz. Bu da bize, bir kez yazdmz kodlar tekrar tekrar kullanma imkan verecek.
Eer yukardaki kodlar daha da genel amal bir hale getirmek istersek, sayac artran kodlar
da bir fonksiyon iine almay dnebiliriz:
sesli_harfler = 'aeiou'
saya = 0

kelime = input('Bir kelime girin: ')

def seslidir(harf):
return harf in sesli_harfler

def artr():
global saya
for harf in kelime:
if seslidir(harf):
saya += 1
return saya

mesaj = '{} kelimesinde {} sesli harf var.'


print(mesaj.format(kelime, artr()))

Hatrlarsanz, ilk bata yazdmz kodlarn en byk avantajnn, kodlarda geen btn
elerin tek bir isim/etki alannda bulunmas olduunu sylemitik. Bu sayede btn elere
her yerden eriebiliyorduk. Yukardaki kodlarda ise birden fazla isim/etki alan var:
1. sesli_harer, saya, kelime ve mesaj deikenlerinin bulunduu global isim/etki alan.
2. seslidir() fonksiyonunun lokal isim/etki alan.
3. artr() fonksiyonunun lokal isim/etki alan.
Bildiiniz gibi, global isim alannda bulunan deikenlere her yerden ulaabiliyoruz. Ancak
bunlar her yerden deitiremiyoruz. Yani mesela global isim alannda bulunan saya
deikeninin deerini, seslidir() fonksiyonu iinden grntleyebiliriz.
Bunu teyit edelim:
sesli_harfler = 'aeiou'
saya = 0

kelime = input('Bir kelime girin: ')

def seslidir(harf):
print('saya deikeninin deeri u anda: ', saya)
return harf in sesli_harfler

def artr():
global saya

38.3. Snar Ne e Yarar? 651


Python 3 iin Trke Klavuz, Srm 3

for harf in kelime:


if seslidir(harf):
saya += 1
return saya

mesaj = '{} kelimesinde {} sesli harf var.'


print(mesaj.format(kelime, artr()))

Grdnz gibi, global isim alanndaki saya deikeninin deerini seslidir() fonksiyonu
iinde kullanabildik. Ama eer bu deiken zerinde deiiklik yapacaksak ilave admlar
atmak zorundayz. Dolaysyla, mesela artr() fonksiyonunun etki alanndan, global etki
alanndaki saya deikeni zerinde deiiklik yapabilmek iin global deyimini kullanmamz
gerekiyor. Bu ekilde, global isim alannda bulunan saya adl deikenin deerini
artrabiliyoruz.
Dikkat ederseniz, artr() fonksiyonunda iki tane global deiken var: saya ve kelime. Ama
biz bunlardan yalnzca saya deikenini global olarak belirledik. br global deikenimiz
kelime iin ise bu ilemi yapmadk. nk kelime adl deikeni deitirmek gibi bir niyetimiz
yok. Biz bu deikeni sadece kullanmakla yetiniyoruz. O yzden bu deikeni global olarak
belirlemek zorunda deiliz.
Ancak bildiiniz gibi, global deyimini kullanmak pek tavsiye edilen bir ey deil. Eer siz de
bu deyimi kullanmak istemezseniz, yukardaki kodlar u ekilde yazmay yeleyebilirsiniz:
sesli_harfler = 'aeiou'
saya = 0

kelime = input('Bir kelime girin: ')

def seslidir(harf):
return harf in sesli_harfler

def artr(saya):
for harf in kelime:
if seslidir(harf):
saya += 1
return saya

mesaj = '{} kelimesinde {} sesli harf var.'


print(mesaj.format(kelime, artr(saya)))

Grdnz gibi, bu kodlarda global deyimini kullanmak yerine, artr() fonksiyonuna


verdiimiz saya parametresi zerinden global isim alanyla iletiim kurarak, saya
deikenini maniple edebildik. Sadece deerini kullandmz global deiken kelime iin
ise zel bir ey yapmamza gerek kalmad.
Bu arada, tabii ki, artr() fonksiyonunda parametre olarak kullandmz kelime saya olmak
zorunda deil. Kodlarmz mesela yle de yazabilirdik:
sesli_harfler = 'aeiou'
saya = 0

kelime = input('Bir kelime girin: ')

def seslidir(harf):
return harf in sesli_harfler

652 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

def artr(n):
for harf in kelime:
if seslidir(harf):
n += 1
return n

mesaj = '{} kelimesinde {} sesli harf var.'


print(mesaj.format(kelime, artr(saya)))

nemli olan, artr() fonksiyonunun, bizim global isim alanyla iletiim kurmamz salayacak
bir parametre almas. Bu parametrenin adnn ne olduunun bir nemi yok.
Yukardaki kodlarda birka deiiklik daha yaparak, bu kodlar iyice geniletilebilir hale
getirebiliriz:
sesli_harfler = 'aeiou'
saya = 0

def kelime_sor():
return input('Bir kelime girin: ')

def seslidir(harf):
return harf in sesli_harfler

def artr(saya, kelime):


for harf in kelime:
if seslidir(harf):
saya += 1
return saya

def ekrana_bas(kelime):
mesaj = "{} kelimesinde {} sesli harf var."
print(mesaj.format(kelime, artr(saya, kelime)))

def altr():
kelime = kelime_sor()
ekrana_bas(kelime)

altr()

Bu kodlarda, fonksiyonlara verdiimiz parametreler yardmyla, farkl fonksiyonlarn lokal


etki alanlarnda yer alan eler arasnda nasl iletiim kurduumuza dikkat edin. Bir nceki
kodlarda global etki alannda bulunan kelime deikenini bu kez altr() fonksiyonunun
lokal etki alan iine yerletirdiimiz iin, artr() fonksiyonu iindeki kelime deikeni
boa dt. O yzden, bu deikeni artr() fonksiyonuna bir parametre olarak verdik
ve ekrana_bas() fonksiyonu iinde bu fonksiyonu arrken, hem saya hem de kelime
argmanlarn kullandk.
Ayrca, kullancya kelime sorup, ald kelimeyi ekrana basan kod paralarn, yani
programmz balatan kodlar altr() bal altnda toplayarak bu ksm tam anlamyla
modler, yani esnek ve taklp karlabilir bir hale getirdik.
Grdnz gibi, yazdmz kodlarn olabildiince anlalr ve ynetilebilir olmasn
salayabilmek iin, bu kodlar kk birtakm birimlere bldk. Bu ekilde hem hangi ilevin
nerede olduunu bulmak kolaylat, hem kodlarn grn daha anlalr oldu, hem de bu
kodlara ileride yeni zellikler eklemek basitleti. Unutmayn, bir programcnn grevi yalnzca
alan kodlar yazmak deildir. Programc ayn zamanda kodlarnn okunaklln artrmak ve

38.3. Snar Ne e Yarar? 653


Python 3 iin Trke Klavuz, Srm 3

bakmn kolaylatrmakla da ykmldr.


Bu bakmdan, programc ile kod arasndaki ilikiyi, yazar ile kitap arasndaki ilikiye
benzetebilirsiniz. Tpk bir programc gibi, yazarn da grevi aklna gelenleri bir kada
geliigzel boca etmek deildir. Yazar, yazd kitabn daha anlalr olmasn salamak
iin kitabna bir balk atmal, yazd yazlar alt balklara ve paragraara blmeli,
ayrca noktalama iaretlerini yerli yerinde kullanarak yazlarn olabildiince okunakl hale
getirmelidir. Bir ana bal ve alt balklar olmayan, sadece tek bir byk paragraftan
oluan, iinde hibir noktalama iaretinin kullanlmad bir makaleyi okumann veya bu
makaleye sonradan yeni bir eyler eklemenin ne kadar zor olduunu dnn. te ayn ey
bir programcnn yazd kodlar iin de geerlidir. Eer yazdnz kodlar anlalr birimlere
blmeden ekrana yarsanz bu kodlar ne bakalar okuyup anlayabilir, ne de siz ileride bu
kodlara yeni ilevler ekleyebilirsiniz.
Python programlama dili, kodlarnz olabildiince anlalr, okunakl ve ynetilebilir hale
getirmeniz iin size pek ok ara sunar. nceki derslerde grdmz deikenler,
fonksiyonlar ve modller bu aralardan yalnzca birkadr. te bu blmde inceleyeceimiz
snar da kodlarmz ehliletirmek iin kullanacamz son derece faydal aralardr.
Birazdan, snf denen bu faydal aralar enine boyuna inceleyeceiz. Ama gelin isterseniz,
anlatmaya devam etmeden nce, verdiimiz son kodlar biraz daha kurcalayalm.
Hatrlarsanz, geen blmde, yazdmz Python kodlarnn ayn zamanda hem bamsz bir
program olarak hem de bir modl olarak kullanlabileceini sylemitik.
Mesela, yukardaki kodlar sayac.py adl bir dosyaya kaydettiimizi varsayarsak, bu program
komut satr zerinden python sayac.py gibi bir kodla altrabiliyoruz. Biz bu program
bu ekilde komut satr zerinden veya zerine ift tklayarak altrdmzda, bu kodlar
bamsz bir program olarak altrm oluyoruz. Gelin bir de bu kodlar bir modl olarak
nasl ie aktaracamz inceleyelim.
imdi, sayac.py programnn bulunduu dizin altnda Python komut satrn balatalm ve
orada u komutu vererek sayac modln ie aktaralm:
>>> import sayac

Bu komutu verdiimiz anda, sayac.py program almaya balayacaktr. Ancak bizim


istediimiz ey bu deil. Biz sayac.py programnn almaya balamasn istemiyoruz. Bizim
istediimiz ey, bu sayac.py dosyasn bamsz bir program olarak deil, bir modl olarak
kullanmak ve bylece bu modl iindeki nitelik ve fonksiyonlara erimek. Tam bu noktada
yle bir soru aklmza geliyor: Acaba bir insan neden bir program modl olarak ie aktarmak
istiyor olabilir?
Bir Python dosyasna modl olarak erimek istemenizin birka sebebi olabilir. Mesela bir
program yazyorsunuzdur ve amacnz yazdnz kodlarn dzgn alp almadn test
etmektir. Bunun iin, programnz etkileimli kabuk ortamna bir modl olarak aktarp,
bu modln test etmek istediiniz ksmlarn tek tek altrabilirsiniz. Ayn ekilde, kendi
yazdnz veya bakas tarafndan yazlm bir program iindeki ilevsellikten baka bir
program iinde de yararlanmak istiyor olabilirsiniz. te bunun iin de, ilgili program,
baka bir program iinden ararak, yani o program teki program iine bir modl olarak
aktararak, ilgili modl iindeki ilevleri kullanabilirsiniz.
Diyelim ki biz, yukarda yazdmz sayac.py adl dosya iindeki kodlarn dzgn alp
almadn kontrol etmek istiyoruz. Bunun iin sayac.py dosyasndaki kodlarda u
deiiklii yapalm:

654 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

sesli_harfler = 'aeiou'
saya = 0

def kelime_sor():
return input('Bir kelime girin: ')

def seslidir(harf):
return harf in sesli_harfler

def artr(saya, kelime):


for harf in kelime:
if seslidir(harf):
saya += 1
return saya

def ekrana_bas(kelime):
mesaj = "{} kelimesinde {} sesli harf var."
print(mesaj.format(kelime, artr(saya, kelime)))

def altr():
kelime = kelime_sor()
ekrana_bas(kelime)

if __name__ == '__main__':
altr()

Grdnz gibi, burada altr() fonksiyonunu if __name__ == __main__ blouna


aldk. Buna gre, eer __name__ niteliinin deeri __main__ ise altr() fonksiyonu
ilemeye balayacak. Aksi halde herhangi bir ey olmayacak.
imdi sayac.py programn komut satr zerinden python sayac.py gibi bir komutla
altrn. Programnz normal bir ekilde alacaktr. nk, bildiiniz gibi, bir Python
program bamsz bir program olarak altrldnda __name__ niteliinin deeri __main__
olur. Dolaysyla da altr() fonksiyonu ilemeye balar.
imdi de etkileimli kabuu tekrar an ve u komutu vererek modl ie aktarn:
>>> import sayac

Bu defa programmz almaya balamad. nk bu kez, programmz bir modl olarak


ie aktardmz iin, __name__ niteliinin deeri __main__ deil, ilgili modln ad oldu (yani
bizim rneimizde sayac ).
Bylece __name__ niteliinin farkl durumlarda farkl bir deere sahip olmasndan
yararlanarak, programnzn farkl durumlarda farkl tepkiler vermesini salam olduk.
sayac modln ie aktardktan sonra, bu modln iinde neler olduunu nasl kontrol
edebileceinizi biliyorsunuz:
>>> dir(sayac)

['__builtins__', '__cached__', '__doc__', '__file__', '__loader__',


'__name__', '__package__', '__spec__', 'artr', 'ekrana_bas',
'kelime_sor', 'saya', 'sesli_harfler', 'seslidir', 'altr']

Bu listede, sayac modlne ait btn nitelik ve fonksiyonlar grebiliyoruz. Bunlar, baka
modllerde olduu gibi kullanma imkanna sahibiz.

38.3. Snar Ne e Yarar? 655


Python 3 iin Trke Klavuz, Srm 3

Mesela bu listede grnen seslidir() fonksiyonunu kullanalm:


>>> sayac.seslidir('')

True

>>> sayac.seslidir('')

False

Grdnz gibi, sayac.py iinde tanmladmz seslidir() fonksiyonunu, rastgele harerin


birer sesli harf olup olmadn denetlemek iin de kullanabiliyoruz. Bu ekilde ayn zamanda
seslidir() fonksiyonunun dzgn bir ekilde alp almadn, sesli olan ve olmayan
hareri baarl bir ekilde birbirinden ayrt edip edemediini de test etmi oluyoruz.
Devam edelim:
>>> sayac.sesli_harfler

'aeiou'

Modllerin ne kadar faydal aralar olabileceini bu rnek gayet net bir ekilde gsteriyor.
Eer ileride sesli hareri kullanmamz gerektiren baka bir program yazacak olursak, bu
hareri yeniden tanmlamak yerine, sayac.py dosyasndan ie aktarabiliriz.
Btn bu rnekler sayesinde, snar daha iyi anlamamz salayacak altyapy oluturmu,
bir yandan da eski bilgilerimizi pekitirmi olduk. Dilerseniz, snar anlatmaya gemeden
nce, yukarda verdiimiz kodlar sn bir yap iinde nasl ifade edebileceimizi de grelim.
Elbette aadaki kodlar anlamanz u aamada sizden beklemiyoruz. Bu blmn sonuna
vardmzda, zihninizde her ey berraklam olacak. Siz imdilik sadece aadaki kodlara
bakn ve hem okunakllk hem de ynetilebilirlik bakmndan bu kodlarn bize ne gibi faydalar
salyor olabileceine dair kir yrtmeye aln. Anlamadnz ksmlar olursa bunlar gein
gitsin. Anladnz ksmlar ise yannza kr kalsn.
class HarfSayac:
def __init__(self):
self.sesli_harfler = 'aeiou'
self.saya = 0

def kelime_sor(self):
return input('Bir kelime girin: ')

def seslidir(self, harf):


return harf in self.sesli_harfler

def artr(self):
for harf in self.kelime:
if self.seslidir(harf):
self.saya += 1
return self.saya

def ekrana_bas(self):
mesaj = "{} kelimesinde {} sesli harf var."
sesli_harf_says = self.artr()
print(mesaj.format(self.kelime, sesli_harf_says))

def altr(self):

656 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

self.kelime = self.kelime_sor()
self.ekrana_bas()

if __name__ == '__main__':
saya = HarfSayac()
saya.altr()

Hakknda herhangi bir kre sahip olmadnz bir kod parasn anlamann en iyi yolu,
anlamadnz ksm kodlardan karp, kodlar bir de o ekilde altrmaktr. Mesela
yukardaki __init__, self ve class gibi elerin ismini deitirin, bunlar kodlardan karn veya
baka bir yere koyun. Elde ettiiniz sonular gzlemleyerek bu kodlar hakknda en azndan
bir kir sahibi olabilirsiniz.
Gelin isterseniz, henz yukardaki kodlar anlayabilecek kadar snf bilgisine sahip olmasak
da, bu kodlar yle bir stnkr gzden geirerek, bu kodlarn programclk deneyimimiz
asndan bize ne gibi bir katk sunuyor olabileceini anlamaya alalm.
Yukardaki kodlarda dikkatimizi eken ilk ey, bu kodlarn son derece derli toplu grnyor
olmasdr. yle ki, HarfSayac adl snf iindeki fonksiyonlar sanki ipe dizilir gibi dizilmi.
HarfSayac adl snf ile bu snf yaps iinde yer alan fonksiyonlar arasndaki iliki gayet net
bir ekilde grnyor. Eer ileride bu sayaca yeni bir ilev eklemek istersek, neyi nereye
yerletirmemiz gerektii ok ak. Mesela ilerde bu kodlara sesli harerle birlikte bir de sessiz
harf denetim ilevi eklemek istersek, gerekli deiiklikleri kolayca yapabiliriz:
class HarfSayac:
def __init__(self):
self.sesli_harfler = 'aeiou'
self.sessiz_harfler = 'bcdfghjklmnprstvyz'
self.saya_sesli = 0
self.saya_sessiz = 0

def kelime_sor(self):
return input('Bir kelime girin: ')

def seslidir(self, harf):


return harf in self.sesli_harfler

def sessizdir(self, harf):


return harf in self.sessiz_harfler

def artr(self):
for harf in self.kelime:
if self.seslidir(harf):
self.saya_sesli += 1
if self.sessizdir(harf):
self.saya_sessiz += 1
return (self.saya_sesli, self.saya_sessiz)

def ekrana_bas(self):
sesli, sessiz = self.artr()
mesaj = "{} kelimesinde {} sesli {} sessiz harf var."
print(mesaj.format(self.kelime, sesli, sessiz))

def altr(self):
self.kelime = self.kelime_sor()
self.ekrana_bas()

38.3. Snar Ne e Yarar? 657


Python 3 iin Trke Klavuz, Srm 3

if __name__ == '__main__':
saya = HarfSayac()
saya.altr()

Ayrca sn kodlarda, farkl etki alanlar ile iletiim kurmak, snfsz kodlara kyasla daha
zahmetsizdir. Sn ve snfsz kodlarda fonksiyonlara verdiimiz parametreleri birbirleri ile
kyaslayarak bu durumu kendiniz de grebilirsiniz.
Sn yaplarn daha pek ok avantajl yn vardr. te biz bu blmde bunlar size tek tek
gstermeye alacaz.

38.4 Snf Tanmlamak

Nesne tabanl programlama yaklam, zellikle birtakm ortak niteliklere ve davran


ekillerine sahip gruplar tanmlamak gerektiinde son derece kullanldr. Mesela yle
bir rnek dnn: Diyelim ki altnz iyerinde, ie alnan kiilerin kaytlarn tutan bir
veritabannz var. Bir kii ie alndnda, o kiiye dair belli birtakm bilgileri bu veritabanna
iliyorsunuz. Mesela ie alnan kiinin ad, soyad, unvan, maa ve buna benzer baka
bilgiler...
almaya balayacak kiileri temsil eden bir alan grubunu, bu grubun nitelikleri ile
faaliyetlerini tutacak yapy ve bu grubun btn elerinin tayaca zellikleri nesne tabanl
programlama yaklam ile kolayca kodlayabilirsiniz.
Ayn ekilde, mesela yazdnz bir oyun program iin, bir Asker grubunu nesne tabanl
programlama mant iinde tanmlayarak, bu grubun her bir yesinin sahip olaca nitelikleri,
kabiliyetleri ve davran ekillerini kodlayabilir; mesela askerlerin saa sola nasl hareket
edeceklerini, hangi durumlarda puan/enerji/g kazanacaklarn veya kaybedeceklerini, bir
asker ilk kez oluturulduunda hangi zellikleri tayacan ve aklnza gelebilecek baka her
trl zellii tek tek belirleyebilirsiniz.
Amacnz ne olursa olsun, atmanz gereken ilk adm, ilgili snf tanmlamak olmaldr. Zira
fonksiyonlarda olduu gibi, bir snf kullanabilmek iin de ncelikle o snf tanmlamamz
gerekiyor. Mesela, yukarda bahsettiimiz ie uygun olarak, alan adl bir snf tanmlayalm:
class alan:
pass

Yukardaki, bo bir snf tanmdr. Hatrlarsanz fonksiyonlar tanmlamak iin def adl
bir ifadeden yararlanyorduk. te snar tanmlamak iin de class adl bir ifadeden
yararlanyoruz. Bu ifadenin ardndan gelen alan kelimesi ise bu snfn addr.
Eer arzu ederseniz, yukardaki snf u ekilde de tanmlayabilirsiniz:
class alan():
pass

Yani snf adndan sonra parantez kullanmayabileceiniz gibi, kullanabilirsiniz de. Her ikisi
de ayn kapya kar. Ayrca snf adlarnda, yukarda olduu gibi byk harf kullanmak ve
birden fazla kelimeden oluan snf adlarnn ilk harerini byk yazp bunlar birletirmek
adettendir. Yani:
class alanSnf():
pass

658 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

Veya parantezsiz olarak:


class alanSnf:
pass

Grdnz gibi snf tanmlamak fonksiyon tanmlamaya ok benziyor. Fonksiyonlar


tanmlarken nasl def deyimini kullanyorsak, snar tanmlamak iin de class deyimini
kullanyoruz.
rnek olmas asndan, yukarda bahsettiimiz Asker grubu iin de bir snf tanmlayalm:
class Asker:
pass

... veya:
class Asker():
pass

Pythonda snar nasl tanmlayacamz rendiimize gre, bu snar nasl


kullanacamz incelemeye geebiliriz.

38.5 Snf Nitelikleri

Yukarda, bo bir snf nasl tanmlayacamz rendik. Elbette tanmladmz snar


hep bo kalmayacak. Bu snara birtakm nitelikler ekleyerek bu snar kullanl hale
getirebiliriz. Mesela:
class alan():
kabiliyetleri = []
unvan = 'ii'

Burada unvan ve kabiliyetleri adl iki deiken tanmladk. Teknik dilde bu deikenlere snf
nitelii (class attribute ) ad verilir.
Biraz nce, snf tanmlamay renirken snf tanmlamann fonksiyon tanmlamaya ok
benzediini sylemitik. Gerekten de yledir. Ancak fonksiyonlarla snar arasnda (baka
farklarn dnda) ok nemli bir fark bulunur. Bildiiniz gibi, bir fonksiyonu tanmladktan
sonra, o fonksiyonun ilemeye balamas iin, o fonksiyonun mutlaka arlmas gerekir.
arlmayan fonksiyonlar almaz. Mesela yukardaki snfa benzeyen yle bir fonksiyon
tanmladmz dnn:
def alan():
kabiliyetleri = []
unvan = 'ii'

print(kabiliyetleri)
print(unvan)

Bu fonksiyonun almas iin, kodlarmzn herhangi bir yerinde bu fonksiyonu armamz


lazm:
alan()

Ancak snar farkldr. Bunu grmek iin yukardaki fonksiyonu bir snf haline getirelim:

38.5. Snf Nitelikleri 659


Python 3 iin Trke Klavuz, Srm 3

class alan():
kabiliyetleri = []
unvan = 'ii'

print(kabiliyetleri)
print(unvan)

Bu kodlar mesela deneme.py adl bir dosyaya kaydedip altrdnzda, unvan ve


kabiliyetleri deikenlerinin deerinin ekrana basldn greceksiniz.
Ayn ey, yukardaki kodlarn bir modl olarak ie aktarld durumlarda da geerlidir. Yani
yukardaki kodlarn deneme.py adl bir dosyada bulunduunu varsayarsak, bu modl u
komutla ie aktardmzda, snf kodlarmzn herhangi bir yerinde armam olmamza
ramen snf ierii almaya balayacaktr:
>>> import deneme

[]
ii

Eer snf niteliklerinin ne zaman alacan kendiniz kontrol etmek isterseniz, bu nitelikleri
snf dnda kullanabilirsiniz:
class alan():
kabiliyetleri = []
unvan = 'ii'

print(alan.kabiliyetleri)
print(alan.unvan)

Burada alan() adl snfn niteliklerine nasl eritiimize dikkat edin. Grdnz gibi,
snf niteliklerine erimek iin dorudan snfn adn parantezsiz bir ekilde kullanyoruz.
Eer snf adlarn parantezli bir ekilde yazarsak baka bir ey yapm oluruz. Bundan biraz
sonra bahsedeceiz. Biz imdilik, snf niteliklerine erimek iin snf adlarn parantezsiz
kullanmamz gerektiini bilelim yeter.
Hatrlarsanz, bu blme balarken, nesne tabanl programlama yaklamnn, zellikle
birtakm ortak niteliklere ve davran ekillerine sahip gruplar tanmlamak gerektiinde son
derece kullanl olduunu sylemitik. Gelin isterseniz yukardaki alan() snfna birka
nitelik daha ekleyerek bu iddiamz destekleyelim:
class alan():
kabiliyetleri = []
unvan = 'ii'
maa = 1500
memleketi = ''
doum_tarihi = ''

Burada belli kabiliyetleri, unvan, maa, memleketi ve doum_tarihi olan bir alan() snf
tanmladk. Yani alan adl bir grubun ortak niteliklerini belirledik. Elbette her alann
memleketi ve doum tarihi farkl olaca iin snf iinde bu deikenlere belli bir deer
atamadk. Bunlarn birer karakter dizisi olacan belirten bir iaret olmas iin yalnzca
memleketi ve doum_tarihi adl birer bo karakter dizisi tanmladk.
Yukarda tanmladmz snf niteliklerine, dorudan snf adn kullanarak eriebileceimizi
biliyorsunuz:

660 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

print(alan.maa)
print(alan.memleketi)
print(alan.doum_tarihi)

Eer isterseniz bu snfa yeni snf nitelikleri de ekleyebilirsiniz:


alan.isim = 'Ahmet'
alan.ya = 40

Gayet gzel...
Ancak burada yle bir sorun var: Biz yukardaki gibi dorudan snf adn kullanarak elere
eritiimizde kodlarmz tek kullanmlk olmu oluyor. Yani bu ekilde ancak tek bir alan()
nesnesi (nesne kavramna ilerde deineceiz), dolaysyla da tek bir alan oluturma imkan
elde edebiliyoruz. Ama biz, mantken, snf iinde belirtilen zellikleri tayan, Ahmet,
Mehmet, Veli, Selim, Selin ve buna benzer, istediimiz sayda alan oluturabilmeliyiz. Peki
ama nasl?

38.6 Snarn rneklenmesi

Biraz nce yle bir snf tanmlamtk:


class alan():
kabiliyetleri = []
unvan = 'ii'
maa = 1500
memleketi = ''
doum_tarihi = ''

Daha nce de sylediimiz gibi, snar belli birtakm ortak zelliklere sahip gruplar
tanmlamak iin biilmi kaftandr. Burada da, herbir alan iin ortak birtakm nitelikler
tanmlayan alan() adl bir snf oluturduk. Ancak elbette bu snfn bir ie yarayabilmesi
iin, biraz nce de deindiimiz gibi, bu snf temel alarak, bu snfta belirtilen nitelikleri
tayan birden fazla snf yesi meydana getirebilmemiz lazm.
imdi dikkatlice bakn:
class alan():
kabiliyetleri = []
unvan = 'ii'
maa = 1500
memleketi = ''
doum_tarihi = ''

ahmet = alan()

Burada snfmz ahmet adl bir deikene atadk.


te bu ileme teknik dilde rnekleme veya rneklendirme (instantiation ) ad verilir. Bu
ilemi fonksiyon arma ile kyaslayabiliriz: Python programlama dilinde bir fonksiyonu
kullanl hale getirme ilemine arma, bir snf kullanl hale getirme ilemine ise
rnekleme ad veriyoruz.
rnekleme kavramn daha iyi anlayabilmek iin baka bir snf daha oluturalm:

38.6. Snarn rneklenmesi 661


Python 3 iin Trke Klavuz, Srm 3

class Asker():
rtbesi = 'Er'
standart_tehizat = ['G3', 'kasatura', 'sng', 'el bombas']
gc = 60
birlii = ''

Burada da belli birtakm niteliklere sahip Asker() adl bir snf tanmladk. Bu snfn
niteliklerine dorudan snf adn kullanarak eriebileceimizi biliyorsunuz:
Asker.rtbesi
Asker.standart_tehizat
Asker.gc
Asker.birlii

Ama bu snfn bir ie yarayabilmesi iin, bu snfa bir referans oluturmamz lazm, ki daha
sonra bu snfa bu referans zerinden atfta bulunabilelim. Yani bu snf arrken buna bir
isim vermeliyiz, ki bu isim zerinden snfa ve niteliklerine eriebilelim.
Mesela bu snfa daha sonra atfta bulunabilmek amacyla, bu snf iin mehmet adl bir
referans noktas oluturalm:
mehmet = Asker()

te, teknik olarak ifade etmemiz gerekirse, snar bir isme atama ilemine rnekleme (veya
rneklendirme) ad veriyoruz.
Burada ahmet ve mehmet, ait olduklar snarn birer sureti veya baka bir deyile
rneidir (instance ). mehmet in, Asker() adl snfn bir rnei, ahmet inse alan() adl
snfn bir rnei olmas demek, mehmet in ve ahmet in, ilgili snarn btn zelliklerini
tayan birer yesi olmas demektir.

Uyar: Bu balamda rnek kelimesini misal anlamnda kullanmadmza zellikle


dikkatinizi ekmek isterim. Trkede rnek kelimesi ile karladmz instance kavram,
nesne tabanl programlamann nemli teknik kavramlarndan biridir.

Biz bir snf ardmzda (yani Asker() veya alan() komutunu verdiimizde), o snf
rneklemi oluyoruz. rneklediimiz snf bir deikene atadmzda ise o snfn bir rneini
karm, yani o snfn btn zelliklerini tayan bir ye meydana getirmi oluyoruz.
Bu arada, elbette bu teknik terimleri ezberlemek zorunda deilsiniz. Ancak nesne tabanl
programlamaya ilikin metinlerde bu terimlerle sk sk karlaacaksnz. Eer bu terimlerin
anlamn bilirseniz, okuduunuz ey zihninizde daha kolay yer edecek, aksi halde, srekli
ne demek olduunu bilmediiniz terimlerle karlamak renme motivasyonunuza zarar
verecektir.
Esasnda nesne tabanl programlamay rencilerin gznde zor klan ey, bu programlama
yaklamnn znden ziyade, ierdii terimlerdir. Gerekten de nesne tabanl programlama,
pek ok etrelli teknik kavram bnyesinde barndran bir sistemdir. Bu nedenle renciler
bu konuya ilikin bir eyler okurken, mulak kavramlarn arasnda kaybolup konunun
esasn gzden karabiliyor. Eer nesne tabanl programlamaya ilikin kavramlar hakkyla
anlarsanz, bu yaklama dair nemli bir engeli amsnz demektir.
te yandan, nesne tabanl programlamaya ilikin kavramlar anlamak sadece Trke okuyup
yazanlar iin deil, ayn zamanda ngilizce bilip ilgili makaleleri zgn dilinden okuyanlar iin
de zor olabilir. O yzden biz bu blmde, kavramlarn Trkeleri ile birlikte ngilizcelerini

662 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

de vererek, ngilizce bilenlerin zgn metinleri okurken konuyu daha iyi anlamalarn
salamaya alacaz. Dolaysyla, bir kavramdan bahsederken onun aslnn ne olduunu da
belirtmemiz, ngilizce bilip de konuyu daha ileri bir dzeyde aratrmak isteyenlere kolaylk
salayacaktr.
Ne diyorduk? Eer elimizde yle bir kod varsa:
class Sipari():
firma = ''
miktar = 0
sipari_tarihi = ''
teslim_tarihi = ''
stok_adedi = 0

jilet = Sipari()

Burada class, snf tanmlamamza yarayan bir edir. Tpk fonksiyonlardaki def gibi, snar
tanmlamak iin de class adl bir parac kullanyoruz.
Sipari ise, snfmzn ad oluyor. Biz snfmzn adn parantezli veya parantezsiz olarak
kullanma imkanna sahibiz.
Snfn gvdesinde tanmladmz u deikenler birer snf niteliidir (class atribute ):
firma = ''
miktar = 0
sipari_tarihi = ''
teslim_tarihi = ''
stok_adedi = 0

jilet = Sipari() komutunu verdiimizde ise, biraz nce tanmladmz snf rnekleyip
(instantiation ), bunu jilet adl bir rnee (instance ) atam oluyoruz. Yani jilet, Sipari() adl
snfn bir rnei olmu oluyor. Bir snftan istediimiz sayda rnek karabiliriz:
kalem = Sipari()
pergel = Sipari()
ikolata = Sipari()

Bu ekilde Sipari() snfn kez rneklemi, yani bu snfn btn zelliklerini tayan
farkl ye meydana getirmi oluyoruz.
Bu snf rneklerini kullanarak, ilgili snfn niteliklerine (attribute ) eriebiliriz:
kalem = Sipari()

kalem.firma
kalem.miktar
kalem.sipari_tarihi
kalem.teslim_tarihi
kalem.stok_adedi

Bildiiniz gibi, eritiimiz bu nitelikler birer snf nitelii olduu iin, snf hi rneklemeden,
bu niteliklere dorudan snf ad zerinden de eriebilirdik:
Sipari.firma
Sipari.miktar
Sipari.sipari_tarihi

38.6. Snarn rneklenmesi 663


Python 3 iin Trke Klavuz, Srm 3

Sipari.teslim_tarihi
Sipari.stok_adedi

zellikle, rneklenmesine gerek olmayan, yalnzca bir kez alacak snarda, snf
niteliklerine rnekler zerinden deil de dorudan snf ad zerinden erimek daha pratik
olabilir. Ancak yukarda olduu gibi, tek bir snftan, ortak niteliklere sahip birden fazla
ye oluturmamz gereken durumlarda snf bir rnee atayp, snf niteliklerine bu rnek
zerinden erimek ok daha akllca olacaktr. Ancak her koulda snarn niteliklerine
dorudan snf adlar zerinden erimek yerine rnekler zerinden erimeyi tercih etmenizin
de hibir sakncas olmadn bilin.
Gelin imdi yukarda rendiklerimizi kullanarak ufak tefek uygulama almalar yapalm.
Snfmz u olsun:
class Sipari():
firma = ''
miktar = 0
sipari_tarihi = ''
teslim_tarihi = ''
stok_adedi = 0

Bildiiniz gibi, ufak tefek kod almalar yapmak iin Pythonn etkileimli kabuu son derece
uygun bir ortamdr. O halde yukardaki snf sipari.py adl bir dosyaya kaydedelim, bu
dosyann bulunduu konumda bir etkileimli kabuk ortam aalm ve sipari.py dosyasn bir
modl olarak ie aktaralm:
>>> import sipari

Bylece sipari modl iindeki nitelik ve metotlara eriim saladk. Bunu teyit edelim:
>>> dir(sipari)

['Sipari', '__builtins__', '__cached__', '__doc__', '__file__',


'__loader__', '__name__', '__package__', '__spec__']

Sipari() adl snf listenin en banda grebilirsiniz. O halde gelin bu snf rnekleyerek
kullanlabilir hale getirelim:
>>> gofret = sipari.Sipari()

Elbette Sipari() adl snf sipari adl modl iinde bulunduundan, bu snfa sipari
nekiyle eriiyoruz. Tabii biz isteseydik modl u ekilde de ie aktarabilirdik:
>>> from sipari import Sipari

Bylece Sipari() snfna neksiz olarak eriebilirdik:


>>> gofret = Sipari()

Ancak mevcut isim alann kirletmemek ve bu alan nereden geldii belli olmayan birtakm
nitelik ve metotlarla doldurmamak iin biz import modl_ad biimini tercih ediyoruz. Aksi
halde, bu kodlar okuyanlar, Sipari() adl snfn sipari adl bir modle ait olduunu
anlamayacak, bu snf ilk olarak mevcut dosya iinde bulmaya alacaklardr. Ama biz modl
adn snf adna eklediimizde modln nereden geldii gayet ak bir ekilde anlalabiliyor.
Bylece hem kodlar okuyan bakalarnn iini hem de birka ay sonra kendi kodlarmza
tekrar bakmak istediimizde kendi iimizi kolaylatrm oluyoruz.

664 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

Neyse... Laf daha fazla dolandrmadan kaldmz yerden devam edelim...


Snfmz u ekilde ie aktarm ve rneklemitik:
>>> import sipari
>>> gofret = sipari.Sipari()

Gelin imdi bir de gofret rneinin (instance ) ieriini kontrol edelim:


>>> dir(gofret)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',


'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'firma',
'miktar', 'sipari_tarihi', 'stok_adedi', 'teslim_tarihi']

Grdnz gibi, snf iinde tanmladmz btn snf nitelikleri (rma, miktar,
sipari_tarihi, stok_adedi ve teslim_tarihi ) bu liste iinde var.
Bu snf niteliklerinden, ad rma olan kullanarak sipariin hangi rmadan yaplacan
belirleyebiliriz:

>>> gofret.firma = 'z stihza ve erikleri Gda, Ticaret Anonim irketi'

Bylece, snf iindeki bir nitelie yeni bir deer atam olduk. sterseniz ipari miktarn da
belirleyelim:
>>> gofret.miktar = 1000

teki snf niteliklerini de ihtiyacnza gre ayarlayabilir, hatta bu snfa yeni nitelikler de
ekleyebilirsiniz.
Gelin isterseniz pratik olmas bakmndan bir rnek daha verelim.
Elimizde yle bir snf olsun:
class alan():
kabiliyetleri = []
unvan = 'ii'
maa = 1500
memleketi = ''
doum_tarihi = ''

Burada kabiliyetleri, unvan, maa, memleketi ve doum_tarihi adl be adet deiken


tanmladk. Teknik dilde bu deikenlere snf nitelii (class attribute ) ad verildiini
biliyorsunuz.
alan() snf iindeki niteliklere erimek iin birka tane rnek karalm:
ahmet = alan()
mehmet = alan()
aye = alan()

Bu ekilde alan() snfnn farkl rneini oluturmu olduk. Bu snfn niteliklerine,


oluturduumuz bu rnekler zerinden eriebiliriz:

38.6. Snarn rneklenmesi 665


Python 3 iin Trke Klavuz, Srm 3

print(ahmet.kabiliyetleri)
print(ahmet.unvan)

print(mehmet.maa)
print(mehmet.memleketi)

print(aye.kabiliyetleri)
print(aye.doum_tarihi)

kardmz rnekler araclyla snf nitelikleri zerinde deiiklik de yapabiliyoruz:


ahmet.kabiliyetleri.append('prezantabl')

imdi burada bir duralm. nk burada ok sinsi bir sorunla kar karyayz. Dikkatlice
bakn.
alan() snf iin bir ahmet rnei oluturalm:
ahmet = alan()

Buna prezantabl kabiliyetini ekleyelim:


ahmet.kabiliyetleri.append('prezantabl')

Bu kabiliyetin eklendiini teyit edelim:


print(ahmet.kabiliyetleri)

imdi alan() snfnn bir baka rneini oluturalm:


selim = alan()

Bu rnein kabiliyetlerini kontrol edelim:


print(selim.kabiliyetleri)

Grdnz gibi, yalnzca ahmet rneine eklemek istediimiz prezantabl kabiliyeti selim
rneine de eklenmi. Ancak normal artlarda arzu edilen bir ey deildir bu. Zira bu durum
aslnda programmzdaki bir tasarm hatasna iaret eder. Peki ama bu durumun sebebi
nedir?
Hatrlarsanz, snf niteliklerinden bahsederken, bu niteliklerin nemli bir zelliinin, snf
arlmadan almaya balamalar olduunu sylemitik. Snf niteliklerinin bir baka nemli
zellii de, bu niteliklere atanan deerlerin ve eer yaplabiliyorsa bu deerler zerinde
sonradan yaplan deiikliklerin o snfn btn rneklerini etkiliyor olmasdr. Eer ilgili
snf nitelii; karakter dizisi, demet ve say gibi deitirilemeyen (immutable ) bir veri tipi
ise bu snf nitelii zerinde zaten deiiklik yapamazsnz. Yaptnz ey ancak ilgili snf
niteliini yeniden tanmlamak olacaktr. Ancak eer snf nitelii, liste, szlk ve kme gibi
deitirilebilir (mutable ) bir veri tipi ise bu nitelik zerinde yapacanz deiiklikler btn
snf rneklerine yansyacaktr. Yazdnz program asndan bu zellik arzu ettiiniz bir ey
olabilir veya olmayabilir. nemli olan, snf niteliklerinin bu zelliinin farknda olmanz
ve kodlarnz bu bilgi erevesinde yazmanzdr. Mesela yukardaki rnekte kabiliyetleri
listesine eklenen elerin btn rneklere yansmas istediimiz bir ey deil. Ama eer
snfmz yle olsayd:

666 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

class alan():
personel_listesi = []

Burada personel_listesi adl bir snf nitelii tanmladk. Eer bu listenin, personele eklenen
btn elemanlar barndrmasn planlyorsak bu listenin her rneklemede bymesi elbette
istediimiz bir ey olacaktr.
Peki o halde biz deerinin her rnekte ortak deil de her rnee zg olmasn istediimiz
nitelikleri nasl tanmlayacaz? Elbette snf nitelikleri yerine rnek nitelikleri denen baka bir
kavramdan yararlanarak...

38.7 rnek Nitelikleri

imdiye kadar rendiklerimiz, snarla faydal iler yapmamz iin pek yeterli deildi. Snar
konusunda ufkumuzun genileyebilmesi iin, snf niteliklerinin (class attributes ) yansra,
nesne tabanl programlamann nemli bir paras olan rnek niteliklerinden (instance
attributes ) de sz etmemiz gerekiyor. Hem rnek niteliklerini rendikten sonra, bunlarn
snf nitelikleri ile arasndaki farklar grnce snf niteliklerini de ok daha iyi anlam
olacaksnz.

38.8 __init__ Fonksiyonu ve self

Buraya gelene kadar, snar ile ilgili verdiimiz kod paralar yalnzca snf niteliklerini
ieriyordu. Mesela yukarda tanmladmz alan() snf iindeki unvan ve kabiliyetleri
adl deikenlerin birer snf nitelii olduunu biliyoruz.
Snf nitelikleri dnda, Pythonda bir de rnek nitelikleri bulunur.
Bildiiniz gibi, Pythonda snf niteliklerini tanmlamak iin yapmamz gereken tek ey, snf
tanmnn hemen altna bunlar alelade birer deiken gibi yazmaktan ibarettir:
class Snf():
snf_nitelii1 = 0
snf_nitelii2 = 1

rnek niteliklerini tanmlamak iin ise iki yardmc araca ihtiyacmz var: __init__()
fonksiyonu ve self.
Bu iki arac u ekilde kullanyoruz:
class alan():
def __init__(self):
self.kabiliyetleri = []

Bu arada, __init__() fonksiyonunun nasl yazldna dikkat ediyoruz. init kelimesinin


sanda ve solunda ikier adet alt izgi (_) bulunduunu gzden karmyoruz. Ayrca,
__init__() fonksiyonunu def ifadesine bitiik yazmamaya da bilhassa zen gsteriyoruz.
init kelimesinin solunda ve sanda bulunan alt izgiler sizi sakn rktmesin. Aslnda
__init__(), alelade bir fonksiyondan baka bir ey deildir. Bu fonksiyonun teki
fonksiyonlardan tek fark, snar asndan biraz zel bir anlam tayor olmasdr. Bu zel
fonksiyonun grevi, snfmz rneklediimiz srada, yani mesela ahmet = alan() gibi bir

38.7. rnek Nitelikleri 667


Python 3 iin Trke Klavuz, Srm 3

komut verdiimiz anda oluturulacak nitelikleri ve gerekletirilecek ilemleri tanmlamaktr.


Bu fonksiyonun ilk parametresi her zaman self olmak zorundadr. Bu aklama ilk anda
kulanza biraz anlalmaz gelmi olabilir. Ama hi endie etmeyin. Bu blmn sonuna
vardnzda bu iki eyi, adnz bilir gibi biliyor olacaksnz.
Hatrlarsanz, snf niteliklerini anlatrken bunlarn nemli bir zelliinin, snfn arlmasna
gerek olmadan almaya balamas olduunu sylemitik:
class alan():
selam = 'merhaba'
print(selam)

Bu kodlar altrdmz anda ekrana merhaba kts verilecektir. rnek nitelikleri ise
farkldr:
class alan():
def __init__(self):
self.kabiliyetleri = []
print(self.kabiliyetleri)

Bu kodlar altrdnzda herhangi bir kt almazsnz. Bu kodlarn kt verebilmesi iin


snfmz mutlaka rneklememiz lazm:
class alan():
def __init__(self):
self.kabiliyetleri = []
print(self.kabiliyetleri)

alan()

nk self.kabiliyetleri bir snf nitelii deil, bir rnek niteliidir. rnek niteliklerine
eriebilmek iin de ilgili snf mutlaka rneklememiz gerekir. Ayrca snf niteliklerinin
aksine, rnek niteliklerine snf adlar zerinden eriemeyiz. Yani self.kabiliyetleri adl rnek
niteliine erimeye ynelik yle bir giriim bizi hsrana uratacaktr:
alan.kabiliyetleri

Bu rnek niteliine erimek iin rneklendirme mekanizmasndan yararlanmamz lazm:


alan().kabiliyetleri #parantezlere dikkat!

Gelin isterseniz, rneklendirme ilemini daha kullanl bir hale getirmek iin,
rneklendirdiimiz snf bir rnee atayalm, yani bu snfn bir rneini karalm:
ahmet = alan()

ahmet = alan() kodu yardmyla, alan snfnn bir rneini kardk ve buna ahmet
adn verdik. te tam bu anda __init__() fonksiyonu almaya balad ve ahmet rnei
iin, kabiliyetleri adl bo bir rnek nitelii oluturdu.
Peki yukarda kodlarmz yazarken __init__() fonksiyonuna parametre olarak verdiimiz ve
kabiliyetleri listesinin banda kullandmz self kelimesi ne oluyor?
ncelikle bilmemiz gereken ey, self kelimesinin, Python programlama dilinin sz diziminin
gerektirdii bir e olduudur. Bu kelime, alan() adl snfn rneklerini temsil eder. Peki
self kelimesinin bir snfn rneklerini temsil ediyor olmas ne anlama geliyor?
Bildiiniz gibi, bir snfn rneini u ekilde karyoruz:

668 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

ahmet = alan()

Bu ahmet rneini kullanarak, alan() snfnn iindeki kabiliyetleri adl rnek niteliine
snf dndan eriebiliriz:
print(ahmet.kabiliyetleri)

te self kelimesi, yukardaki kodda yer alan ahmet kelimesini temsil ediyor. Yani
ahmet.kabiliyetleri eklinde bir kod yazabilmemizi salayan ey, __init__() fonksiyonu
iinde belirttiimiz self kelimesidir. Eer bu kelimeyi kullanmadan yle bir kod yazarsak:
class alan():
def __init__():
kabiliyetleri = []

...artk aadaki kodlar yardmyla kabiliyetleri niteliine eriemeyiz:


ahmet = alan()
print(ahmet.kabiliyetleri)

imdi ayn kodlar bir de yle yazalm:


class alan():
def __init__(self):
kabiliyetleri = []

ahmet = alan()
print(ahmet.kabiliyetleri)

Burada __init__() fonksiyonunda ilk parametre olarak self i belirttik. Ama kabiliyetleri
niteliinin bana self eklemedik. Dolaysyla yazdmz kodlar yine hata verdi. nk,
ahmet.kabiliyetleri eklinde ifade ettiimiz kodlardaki ahmet kelimesini karlayacak
herhangi bir e snf iinde bulunmuyor...
Bu arada, rnek isimlerini (mesela ahmet ) yalnzca rnek niteliklerine erimek iin
kullanmyoruz. Bunlar ayn zamanda snf niteliklerine erimek iin de kullanabiliyoruz.
Dolaysyla eer yukardaki snf tanm iinde, self.kabiliyetleri adl rnek nitelii nin yansra
personel adl bir snf nitelii de bulunsayd:
class alan():
personel = ['personel']

def __init__(self):
self.kabiliyetleri = []

u kodlar yazdmzda:
ahmet = alan()
print(ahmet.personel)

...o snf niteliine eriebilirdik. Ancak eer __init__() fonksiyonu altndaki kabiliyetleri
niteliine erimek istiyorsak, bu niteliin bana self kelimesini getirerek, bu nitelii bir rnek
nitelii haline getirmeli ve bylece, ahmet.kabiliyetleri kodundaki ahmet kelimesini temsil
edecek bir eyi snf iinde oluturmalyz.
Bu sre tam olarak yle iler:

38.8. __init__ Fonksiyonu ve self 669


Python 3 iin Trke Klavuz, Srm 3

Biz ahmet.kabiliyetleri eklinde bir komut verdiimizde, Python ilk olarak ilgili snfn
__init__() fonksiyonu iinde kabiliyetleri adl bir rnek nitelii arar. Elbette Pythonn
bu rnek niteliini bulabilmesi iin, __init__() fonksiyonu iinde, bu fonksiyonun ilk
parametresi ile ayn neki tayan bir niteliin yer almas gerekir. Yani eer __init__()
fonksiyonunun ilk parametresi self ise, Python bu fonksiyon iinde self.kabiliyetleri adl bir
rnek nitelii bulmaya alr. Eer bulamazsa, Python bu kez kabiliyetleri adl bir snf nitelii
arar. Eer onu da bulamazsa tabii ki hata verir...
Gelin isterseniz bu mekanizmay teyit edelim:
class alan():
kabiliyetleri = ['snf nitelii']

def __init__(self):
self.kabiliyetleri = ['rnek nitelii']

Grdnz gibi, burada ayn ad tayan bir snf nitelii ile bir rnek niteliimiz var.
Pythonda hem snf niteliklerine, hem de rnek niteliklerine rnek isimleri zerinden
eriebileceimizi sylemitik. Yani eer rneimizin ismi ahmet ise, hem kabiliyetleri adl
snf niteliine hem de self.kabiliyetleri adl rnek niteliine ayn ekilde eriiyoruz:
ahmet = alan()
print(ahmet.kabiliyetleri)

Peki ama acaba yukardaki kodlar bize rnek niteliini mi verir, yoksa snf niteliini mi?
Byle bir durumda, yukarda bahsettiimiz mekanizma nedeniyle, self.kabiliyetleri
eklinde ifade ettiimiz rnek nitelii, kabiliyetleri adl snf niteliini glgeler. Bu yzden de
print(ahmet.kabiliyetleri) komutu, rnek niteliini, yani self.kabiliyetleri listesini verir.
Yukardaki kodlar altrarak siz de bu durumu teyit edebilirsiniz. Zira bu kodlar bize,
self.kabiliyetleri listesinin deeri olan rnek nitelii ktsn verecektir...
Peki ya siz snf nitelii olan kabiliyetleri listesine erimek isterseniz ne olacak?
te bunun iin, snf rneini deil de, snf adn kullanacaksnz:
class alan():
kabiliyetleri = ['snf nitelii']

def __init__(self):
self.kabiliyetleri = ['rnek nitelii']

#snf niteliine erimek iin


#snf adn kullanyoruz
print(alan.kabiliyetleri)

#rnek niteliine erimek iin


#rnek adn kullanyoruz
ahmet = alan()
print(ahmet.kabiliyetleri)

Ancak elbette, ayn ad tayan bir snf nitelii ile bir rnek niteliini ayn snf iinde
tanmlamak daha batan iyi bir kir deildir, ama yazdnz bir snf yanllkla ayn ada
sahip snf ve rnek nitelikleri tanmlamanz nedeniyle beklenmedik bir kt veriyorsa, siz
Pythonn bu zelliinden haberdar olduunuz iin, hatann nereden kaynaklandn kolayca
kestirebilirsiniz.
Szn ksas, Pythonn sz dizimi kurallar asndan, eer bir rnek nitelii tanmlyorsak, bu

670 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

niteliin bana bir self getirmemiz gerekir. Ayrca bu self kelimesini de, rnek niteliinin
bulunduu fonksiyonun parametre listesinde ilk sraya yerletirmi olmalyz. Unutmayn,
rnek nitelikleri sadece fonksiyonlar iinde tanmlanabilir. Fonksiyon dnda rnek nitelii
tanmlayamazsnz. Yani yle bir ey yazamazsnz:
class alan():
self.n = 0

def __init__(self):
self.kabiliyetleri = []

nk self kelimesi ancak ve ancak, iinde getii fonksiyonun parametre listesinde ilk srada
kullanldnda anlam kazanr.
Bu noktada size ok nemli bir bilgi verelim: Python snarnda rnek niteliklerini temsil
etmesi iin kullanacanz kelimenin self olmas art deildir. Bunun yerine istediiniz baka
bir kelimeyi kullanabilirsiniz. Mesela:
class alan():
def __init__(falanca):
falanca.kabiliyetleri = []

Dediimiz gibi, self kelimesi, bir snfn rneklerini temsil ediyor. Siz snf rneklerini
hangi kelimenin temsil edeceini kendiniz de belirleyebilirsiniz. Mesela yukardaki rnekte,
__init__() fonksiyonunun ilk parametresini falanca olarak belirleyerek, rnek niteliklerinin
falanca kelimesi ile temsil edilmesini salam olduk. Pythonda bu konuya ilikin kural udur:
Snf iindeki bir fonksiyonun ilk parametresi ne ise, o fonksiyon iindeki rnek niteliklerini
temsil eden kelime de odur. rnein, eer yle bir snf tanmlamsak:
class XY():
def __init__(a, b, c):
a.rnek_nitelii = []

Burada __init__() fonksiyonunun ilk parametresi a olduu iin, rnek niteliini temsil eden
kelime de a olur. Dolaysyla rnek_nitelii adl rnek niteliimizin bana da nek olarak bu
a kelimesini getiriyoruz.
__init__() fonksiyonunun ilk parametresi a olarak belirlendikten sonra, bu fonksiyon
iindeki btn rnek nitelikleri, nek olarak a kelimesini alacaktr:
class XY():
def __init__(a, b, c):
a.rnek_nitelii1 = []
a.rnek_nitelii2 = 23
a.rnek_nitelii3 = 'istihza'

ANCAK! Her ne sebeple olursa olsun, rnek niteliklerini temsil etmek iin self dnda bir
kelime kullanmayn. Python bu kelimeyi bize dayatmasa da, self kullanm Python topluluu
iinde ok gl ve sk skya yerlemi bir gelenektir. Bu gelenei kimse bozmaz. Siz de
bozmayn.
Szn z, tek bana self kelimesinin hibir anlamnn olmadn asla aklnzdan karmayn.
Bu kelimenin Python asndan bir anlam kazanabilmesi iin, ilgili fonksiyonun parametre
listesinde ilk srada belirtiliyor olmas lazm. Zaten bu yzden, dediimiz gibi, self kelimesinin
Python asndan bir zellii yoktur. Yani yle bir kod yazmamzn, Python sz dizimi
asndan hibir sakncas bulunmaz:

38.8. __init__ Fonksiyonu ve self 671


Python 3 iin Trke Klavuz, Srm 3

class alan():
def __init__(osman):
osman.kabiliyetleri = []

nk Python, rnek niteliklerini temsil eden kelimenin ne olduuyla asla ilgilenmez. Python
iin nemli olan tek ey, temsil ii iin herhangi bir kelimenin belirlenmi olmasdr. Tabii,
biz, daha nce de srarla sylediimiz gibi, rnek niteliklerini self dnda bir kelime ile temsil
etmeye teebbs etmeyeceiz ve kodlarmz u ekilde yazmaktan amayacaz:
class alan():
def __init__(self):
self.kabiliyetleri = []

te yukardaki kodda grdmz self parametresi ve self neki, birbirlerine baml


kavramlardr. Fonksiyonun ilk parametresi ne ise, rnek niteliklerinin neki de o olacaktr.
Bu arada, rnek niteliklerini anlatmaya balamadan nce snf niteliklerine ilikin sinsi bir
durumdan sz etmitik hatrlarsanz. Buna gre, eer elimizde yle bir kod varsa:
class alan():
kabiliyetleri = []

Biz bu snf iindeki kabiliyetleri listesine ekleme yaptmzda, bu durum o snfn btn
rneklerini etkiliyordu.
Yukardaki kodlar deneme.py adl bir dosyaya kaydettiimizi varsayarsak:
>>> import deneme
>>> ahmet = deneme.alan()
>>> ahmet.kabiliyetleri.append('konukan')
>>> ahmet.kabiliyetleri

['konukan']

>>> mehmet = deneme.alan()


>>> print(mehmet.kabiliyetleri)

['konukan']

te bu durumu nlemek iin rnek metotlarndan yararlanabiliyoruz:


class alan():
def __init__(self):
self.kabiliyetleri = []

Yukardaki kodlar yine deneme.py adl bir dosyaya kaydettiimizi varsayarsak:


>>> import deneme
>>> ahmet = deneme.alan()
>>> ahmet.kabiliyetleri.append('konukan')
>>> ahmet.kabiliyetleri

['konukan']

>>> mehmet = deneme.alan()


>>> print(mehmet.kabiliyetleri)

[]

672 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, ahmet rneine eklediimiz konukan esi, olmas gerektii gibi, mehmet
rneinde bulunmuyor. Birazdan bu konu zerine birka kelam daha edeceiz.

38.9 rnek Metotlar

Buraya kadar snar, rnekler, snf nitelikleri ve rnek nitelikleri konusunda epey bilgi
edindik. Gelin imdi isterseniz bu rendiklerimizi kullanarak az ok anlaml bir eyler
yazmaya alalm. Bylece hem imdiye kadar rendiklerimizi gzden geirmi ve
pekitirmi oluruz, hem de bu blmde ele alacamz rnek metotlar (instance methods )
kavramn anlamamz kolaylar:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

def personeli_grntle(self):
print('Personel listesi:')
for kii in self.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Snfmz tanmladk. Gelin isterseniz bu kodlar aklamaya balamadan nce nasl


kullanacamz grelim.
Bildiiniz gibi, Python kodlarn test etmenin en iyi yolu, bunlar etkileimli kabuk zerinde
altrmaktr. zellikle bir program yazarken, tasarladnz snarn, fonksiyonlarn
ve teki elerin dzgn alp almadn test etmek iin etkileimli kabuu sklkla
kullanacaksnz.
O halde, yukardaki kodlar barndran dosyann bulunduu dizin altnda bir etkileimli kabuk
oturumu balatalm ve dosya adnn alan.py olduunu varsayarak kodlarmz bir modl
eklinde ie aktaralm:
>>> import alan

Daha sonra snfmzn iki farkl rneini karalm:


>>> 1 = alan.alan('Ahmet')

Ahmet adl kii personele eklendi

38.9. rnek Metotlar 673


Python 3 iin Trke Klavuz, Srm 3

>>> 2 = alan.alan('Mehmet')

Mehmet adl kii personele eklendi

Bu ekilde alan adl modl iindeki alan() adl snf srasyla Ahmet ve Mehmet
parametreleri ile ararak 1 ve 2 adl iki farkl snf rnei oluturmu olduk. Bu arada,
snfmz rneklediimiz anda __init__() fonksiyonunun devreye girdiine dikkat ediyoruz.
personele_ekle() adl fonksiyonu self.personele_ekle() eklinde __init__() fonksiyonu
iinden ardmz iin, snfmz rneklediimiz anda hem personelin kendisi personel
listesine eklendi, hem de bu kiinin personele eklendiine dair bir mesaj gsterildi.
Tanmladmz snfn niteliklerine, kardmz rnekler zerinden eriebiliriz:
>>> 1.isim

'Ahmet'

>>> 2.isim

'Mehmet'

Yine bu rnekler zerinden, bu nitelikleri deitirebiliriz de:


>>> 1.isim = 'Mahmut'
>>> 1.personel[0] = 'Mahmut'

Bylece ilk alann ismini Mahmut olarak deitirdik:


>>> 1.isim

'Mahmut'

>>> 1.personel

['Mahmut', 'Mehmet']

Tanmladmz snf iindeki fonksiyonlar kullanarak, alanlarmza birka kabiliyet


ekleyelim:
>>> 1.kabiliyet_ekle('prezantabl')
>>> 1.kabiliyet_ekle('konukan')

1 rneinin kabiliyetlerini grntleyelim:


>>> 1.kabiliyetleri_grntle()

Mahmut adl kiinin kabiliyetleri:


prezantabl
konukan

imdi de 2 rneine bir kabiliyet ekleyelim ve eklediimiz kabiliyeti grntleyelim:


>>> 2.kabiliyet_ekle('giriken')
>>> 2.kabiliyetleri_grntle()

Mehmet adl kiinin kabiliyetleri:


giriken

674 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, bir snf rneine eklediimiz kabiliyet teki snf rneklerine karmyor. Bu,
rnek niteliklerinin snf niteliklerinden nemli bir farkdr. Zira snf nitelikleri bir snfn btn
rnekleri tarafndan paylalr. Ama rnek nitelikleri her bir rnee zgdr. Bu zellikten
biraz sonra daha ayrntl olarak sz edeceiz. Biz imdilik okumaya devam edelim.
Snf rneklerimizin herhangi biri zerinden personel listesine de ulaabileceimizi biliyoruz:
>>> 1.personeli_grntle()

Personel listesi:
Mahmut
Mehmet

Gayet gzel...
Yukarda anlattklarmz snar hakknda size epey kir vermi olmal. Konuyu daha da
derinlemesine anlayabilmek iin, artk bu snf incelemeye geebiliriz.
Snfmz nmze alalm:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

def personeli_grntle(self):
print('Personel listesi:')
for kii in self.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Burada ncelikle her zamanki gibi snfmz tanmlyoruz:


class alan():
...

Daha sonra bu snfa personel adl bir snf nitelii ekliyoruz:


class alan():
personel = []

Snf niteliklerinin zellii, o snfn btn rnekleri tarafndan paylalyor olmasdr. Yani
herhangi bir rnein bu nitelik zerinde yapt deiiklik, teki rneklere de yansyacaktr.
Hele bir de bu snf nitelii, listeler gibi deitirilebilir (mutable ) bir veri tipi ise, bu durum
hi de istemediiniz sonular dourabilir. Bununla ilgili bir rnei yukarda vermitik.

38.9. rnek Metotlar 675


Python 3 iin Trke Klavuz, Srm 3

Hatrlarsanz, kabiliyetleri adl, liste veri tipinde bir snf nitelii oluturduumuzda, bu listeye
eklediimiz eler, hi istemediimiz halde br rneklere de sirayet ediyordu. Elbette,
snf niteliklerinin bu zellii, o anda yapmaya altnz ey asndan gerekli bir durum
da olabilir. Mesela yukardaki kodlarda, listelerin ve snf niteliklerinin bu zellii bizim
amacmza hizmet ediyor. Yukardaki snf altrdmzda, eklenen her bir kiiyi bu personel
listesine ilave edeceiz. Dolaysyla bu nitelik zerinde yaplan deiikliklerin btn rneklere
yansmas bizim istediimiz bir ey.
Neyse... Laf daha fazla uzatmadan, kodlarmz aklamaya kaldmz yerden devam edelim...
Snfmz ve snf niteliimizi tanmladktan sonra __init__() adl zel fonksiyonumuzu
oluturuyoruz:
def __init__(self, isim):
self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

Bu fonksiyonun zellii, snfn rneklenmesi ile birlikte otomatik olarak altrlacak


olmasdr. Biz burada, self.isim ve self.kabiliyetleri adl iki adet rnek nitelii tanmladk.
Bu rnek niteliklerine snfmzn her tarafndan eriebileceiz.
Yukarda, tanmladmz snf nasl kullanacamz gsterirken, alan() snfn u ekilde
rneklediimizi hatrlyorsunuz:
>>> 1 = alan.alan('Ahmet')

Burada snfmz Ahmet adl bir argmanla rneklediimize dikkatinizi ekmek isterim.
te bu argman, biraz nce __init__() fonksiyonunu tanmlarken belirttiimiz isim
parametresine karlk geliyor. Dolaysyla, bir snf arrken/rneklerken kullanacamz
argmanlar, bu __init__() fonksiyonunun parametreleri olarak tanmlyoruz.
Daha sonra bu isim parametresini, __init__() fonksiyonunun gvdesi iinde bir rnek
nitelii haline getiriyoruz:
self.isim = isim

Bunu yapmamzn gerekesi, isim parametresini snfmzn baka blgelerinde de


kullanabilmek. self kelimesini parametremizin bana yerletirerek, bu parametreyi snfn
baka yerlerinden de eriilebilir hale getiriyoruz.
isim parametresini, self.isim kodu yardmyla bir rnek niteliine dntrdkten sonra
self.kabiliyetleri adl bir baka rnek nitelii daha tanmlyoruz. Bu liste, snf rneklerine
eklediimiz kabiliyetleri tutacak.
Bunun ardndan yle bir kod gryoruz:
self.personele_ekle()

Burada, personele_ekle() adl bir rnek metoduna (instance method ) atfta bulunuyoruz.
rnek metotlar, bir snfn rnekleri vastasyla arlabilen fonksiyonlardr. Bu
fonksiyonlarn ilk parametresi her zaman self kelimesidir. Ayrca bu fonksiyonlara snf iinde
atfta bulunurken de yine self kelimesini kullanyoruz. Tpk yukardaki rnekte olduu gibi...
Bir rnek metodu olduunu sylediimiz personele_ekle() fonksiyonunu u ekilde
tanmladk:

676 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

Burada, bir snf nitelii olan personel deikenine nasl eritiimize ok dikkat etmenizi
istiyorum. Daha nce de sylediimiz gibi, snf niteliklerine snf dndayken rnekler
zerinden eriebiliyoruz. self kelimesi, bir snfn rneklerini temsil ettii iin, bir rnek
niteliine snf iinden erimemiz gerektiinde self kelimesini kullanabiliriz.
Snf niteliklerine, rnekler dnda, snf adyla da eriebileceinizi biliyorsunuz. Dolaysyla
isterseniz yukardaki kodlar yle de yazabilirdiniz:
def personele_ekle(self):
alan.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

Bir ncekinden farkl olarak, bu defa snf niteliine dorudan snf adn (alan ) kullanarak
eritik.
Ayrca bu fonksiyonda, bir rnek nitelii olan self.isim deikenine de eriebiliyor
olduumuza dikkat edin. Unutmayn, self snarn ok nemli bir esidir. Bu eyi
kullanarak hem rnek niteliklerine, hem snf niteliklerine, hem de rnek metotlarna
ulaabiliyoruz. Tanmladmz bu personele_ekle() adl rnek metodunu __init__()
fonksiyonu iinden self.personele_ekle() kodu ile (yani yine self kelimesini kullanarak)
ardmz hatrlyorsunuz.
personele_ekle() fonksiyonunun ardndan arka arkaya fonksiyon daha tanmladk:
def personeli_grntle(self):
print('Personel listesi:')
for kii in self.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Bu fonksiyonlar da, tpk personele_ekle() gibi, birer rnek metodudur. Bu rnek


metotlarnn da ilk parametrelerinin hep self olduuna dikkat ediyoruz. rnek metotlarna
snf dndan rnek isimleri (ahmet, mehmet gibi) araclyla, snf iinden ise, rnek
isimlerini temsil eden self kelimesi araclyla eritiimizi biliyorsunuz.
imdi bir duralm...
Bu noktaya kadar epey konutuk, epey rnek verdik. Snar hakknda yeterince bilgi sahibi
olduumuza gre, nihayet en bata verdiimiz harf sayac kodlarn rahatlkla anlayabilecek
dzeye eritik:
class HarfSayac:
def __init__(self):
self.sesli_harfler = 'aeiou'
self.sessiz_harfler = 'bcdfghjklmnprstvyz'
self.saya_sesli = 0

38.9. rnek Metotlar 677


Python 3 iin Trke Klavuz, Srm 3

self.saya_sessiz = 0

def kelime_sor(self):
return input('Bir kelime girin: ')

def seslidir(self, harf):


return harf in self.sesli_harfler

def sessizdir(self, harf):


return harf in self.sessiz_harfler

def artr(self):
for harf in self.kelime:
if self.seslidir(harf):
self.saya_sesli += 1
if self.sessizdir(harf):
self.saya_sessiz += 1
return (self.saya_sesli, self.saya_sessiz)

def ekrana_bas(self):
sesli, sessiz = self.artr()
mesaj = "{} kelimesinde {} sesli {} sessiz harf var."
print(mesaj.format(self.kelime, sesli, sessiz))

def altr(self):
self.kelime = self.kelime_sor()
self.ekrana_bas()

if __name__ == '__main__':
saya = HarfSayac()
saya.altr()

Gelin isterseniz bu kodlara da yle bir bakalm...


Burada snfmz u ekilde tanmladk:
class HarfSayac:
...

Snf adn parantezli bir ekilde yazabileceimizi de biliyorsunuz:


class HarfSayac():
...

Daha sonra, __init__() fonksiyonu iinde drt adet rnek nitelii tanmladk:
self.sesli_harfler = 'aeiou'
self.sessiz_harfler = 'bcdfghjklmnprstvyz'
self.saya_sesli = 0
self.saya_sessiz = 0

Bunlarn birer rnek nitelii olduunu, balarna getirdiimiz self kelimesinden anlyoruz.
nk bildiiniz gibi, self kelimesi, ilgili snfn rneklerini temsil ediyor. Bir snf iinde rnek
niteliklerine ve rnek metotlarna hep bu self kelimesi araclyla eriiyoruz.
Bu snf iinde, ilk parametreleri self olan u rnek metotlarn gryoruz:

678 Blm 38. Nesne Tabanl Programlama (OOP)


Python 3 iin Trke Klavuz, Srm 3

def kelime_sor(self):
...

def seslidir(self, harf):


...

def sessizdir(self, harf):


...

def artr(self):
...

def ekrana_bas(self):
...

def altr(self):
...

Sna birlikte btn rnek deikenlerini ve rnek metotlarn tanmladktan sonra


programmz altrma aamasna geliyoruz:
if __name__ == '__main__':
saya = HarfSayac()
saya.altr()

Buna gre, eer programmz bamsz olarak altrlyorsa ncelikle HarfSayac() adl snf
rneklendiriyoruz:
saya = HarfSayac()

Daha sonra da saya rnei zerinden HarfSayac() adl snfn altr() metoduna
erierek programmz balatyoruz.
Bylece, Pythonda nesne tabanl programlama ve snara dair renmemiz gereken btn
temel bilgileri edinmi olduk. u ana kadar rendikleriniz sayesinde, etrafta greceiniz
sn kodlarn byk blmn anlayabilecek durumdasnz. Bir sonraki blmde, nesne
tabanl programlamann ayrntlarna inmeye balayacaz.

38.9. rnek Metotlar 679


BLM 39

Nesne Tabanl Programlama (Devam)

Geen blmde Pythonda nesne tabanl programlama konusunun temellerinden sz


etmitik. Bu blmde ise nesne tabanl programlamann ayrntlarna inmeye balayacaz.

39.1 Snf Metotlar

Nesne tabanl programlamaya giri yaptmz geen blmde unlara deindik:


1. Snar (classes )
2. rnekler (instances )
3. Snf nitelikleri (class attributes )
4. rnek nitelikleri (instance attributes )
5. rnek metotlar (instance methods )
Bunlar nesne tabanl programlamann en temel kavramlardr. Bunlar iyice rendiyseniz,
etrafta grdnz kodlarn byk blmn anlayabilecek kvama gelmisiniz demektir.
Ama elbette nesne tabanl programlama yalnzca bu temel kavramlardan ibaret deil.
Nesne tabanl programlamann derinlerine indike, bunlarn dnda baka pek ok kavramla
daha karlaacaz. Mesela snf metotlar (class methods ) bu kavramlardan biridir. te
bu blmde, nesne tabanl programlamann ileri dzey kavramlarnn ilki olan bu snf
metotlarndan (class methods ) sz edeceiz.
Dilerseniz ne ile kar karya olduumuzu anlayabilmek iin basit bir rnek zerinden
ilerleyelim.
Hatrlarsanz bir nceki blmde yle bir kod paras vermitik:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

680
Python 3 iin Trke Klavuz, Srm 3

def personeli_grntle(self):
print('Personel listesi:')
for kii in self.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Bu kodlarda, bir personel listesi oluturmamz, personele ekleme yapmamz, personeli


grntlememizi, personele yeni kabiliyet eklememizi ve eklediimiz kabiliyetleri
grntleyebilmemizi salayan rnek metotlar var. Gelin bu kodlara bir de personel
saysn grntlememizi salayacak bir baka rnek metodu daha ekleyelim:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

def personel_saysn_grntle(self):
print(len(self.personel))

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

def personeli_grntle(self):
print('Personel listesi:')
for kii in self.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Burada yeni olarak personel_saysn_grntle() adl bir rnek metodu tanmladk. Bu


metot, bir snf nitelii olan personel e erierek bunun uzunluunu ekrana basyor. Bylece
personelin ka kiiden olutuunu renmi oluyoruz.
Bu yeni rnek metodunu aadaki ekilde kullanabiliriz.
ncelikle kodlarmz barndran modl ie aktaralm:
>>> import alan

Daha sonra personel listesine birka alan ekleyelim:

39.1. Snf Metotlar 681


Python 3 iin Trke Klavuz, Srm 3

>>> ahmet = alan.alan('Ahmet')

Ahmet adl kii personele eklendi

>>> mehmet = alan.alan('Mehmet')

Mehmet adl kii personele eklendi

>>> aye = alan.alan('Aye')

Aye adl kii personele eklendi

Artk herhangi bir rnek deikeni zerinden personel saysna eriebiliriz:


>>> aye.personel_saysn_grntle()

Ancak kodlarn alma mant asndan burada bir tutarszlktan sz edebiliriz. Genel
olarak btn personele dair bilgi veren bir fonksiyona ahmet, mehmet, aye gibi bireysel
rnek deikenleri zerinden erimek kulaa sizce de biraz tuhaf gelmiyor mu? Neticede
bu fonksiyon, aslnda snfn herhangi bir rnei ile zellikle veya dorudan ilikili deil.
Yani bu fonksiyon tek tek snf rneklerini deil, genel olarak snfn btnn ilgilendiriyor.
Bu bakmdan, personel_saysn_grntle() fonksiyonunun rnek deikenlerinden
bamsz bir biimde kullanlabilmesi ok daha mantkl olacaktr.
Ayrca, bir rnek metodu olan personel_saysn_grntle() fonksiyonunu rneklerden
bamsz olarak kullanamadmz iin, bu metot yardmyla personel saysnn 0 olduu
bir durumu grntlememiz de mmkn olmuyor. nk bu fonksiyona eriebilmek iin
ncelikle snf en az bir kez rneklemi, yani snfn en az bir adet rneini karm olmamz
gerekiyor. Bu durum da kodlarmzn mant asndan son derece ciddi bir kstlamadr.
Yukarda sralanan gerekeler dorultusunda kodlar hem daha tutarl bir hale getirmek hem
de personel saysnn 0 olduu durumu gstermemizi engelleyen kstlamay aabilmek iin
yle bir ey deneyebilirsiniz:
def personel_saysn_grntle():
print(len(alan.personel))

class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

def personeli_grntle(self):
print('Personel listesi:')
for kii in self.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):

682 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Burada personel saysn grntleyen fonksiyonu snftan ayrdk. Bylece u ekilde bir
kullanm mmkn olabildi:
>>> import alan
>>> alan.personel_saysn_grntle()

personel_saysn_grntle() adl fonksiyonu snftan ayrp modl dzeyinde alan bir


fonksiyon (veya bir baka deyile global dzeyde alan bir fonksiyon ) haline getirdiimiz
iin, artk bu fonksiyon alan() snfnn herhangi bir rneine baml deil. Dolaysyla bu
fonksiyonu, alan() snf iin bir rnek karmak zorunda kalmadan da kullanabiliyoruz.
Bu da bize personel saysnn 0 olduu durumu gsterebilme imkan tanyor.
Bu fonksiyonu bir de birka rnek kardktan sonra altralm...
nce snfmzn birka rneini karalm:
>>> ahmet = alan.alan('Ahmet')

Ahmet adl kii personele eklendi

>>> aye = alan.alan('Aye')

Aye adl kii personele eklendi

>>> mehmet = alan.alan('Mehmet')

Mehmet adl kii personele eklendi

imdi de personelin u anda ka kiiden olutuunu sorgulayalm:


>>> alan.personel_saysn_grntle()

Grdnz gibi, bu ekilde kodlarmz biraz daha tutarl bir grnme kavutu. Ancak bu
ekilde, bariz bir biimde alan() snf ile ilikili olan personel_saysn_grntle()
fonksiyonunu snftan ayrm ve kod btnln bozmu olduk. nk, her ne
kadar personel_saysn_grntle() fonksiyonu alan() snfnn herhangi bir rnei
ile ilikili olmasa da, anlam asndan bu fonksiyonun alan() snfna ait olduu
besbelli. Ayrca, yukardaki kodlar barndran modln tamamn deil de, from
alan import alan gibi bir komutla yalnzca alan() snfn ie aktarrsak,
personel_saysn_grntle() fonksiyonu darda kalacaktr:
>>> from alan import alan
>>> dir()

Grdnz gibi, personel_saysn_grntle() fonksiyonu listede yok. Dolaysyla, sna


sk skya ilikili olan bu fonksiyonu snftan kopardmz iin, semeli ie aktarmalarda bu

39.1. Snf Metotlar 683


Python 3 iin Trke Klavuz, Srm 3

fonksiyon geride kalyor ve bylece bu fonksiyonu kullanamaz hale geliyoruz.


Semeli ie aktarmalarda bu fonksiyon aktarm ilemiyle birlikte gelmedii iin, ilgili
fonksiyonu zel olarak ie aktarmamz gerekir:
>>> from alan import personel_saysn_grntle

Bu ekilde alan modl iinden personel_saysn_grntle() adl fonksiyonu zel


olarak elle ie aktarm olduk. Artk bu fonksiyonu yle kullanabiliriz:
>>> personel_saysn_grntle()

Ancak bu da, her zaman tercih etmeyeceiniz bir kstlama olabilir. O halde bu kstlamay
amak iin gelin, ilgili fonksiyonu tekrar snf iine alalm:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

def personel_saysn_grntle(self):
print(len(self.personel))

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

def personeli_grntle(self):
print('Personel listesi:')
for kii in self.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Yukardaki kodlarda ilgili fonksiyona bir rnek adyla deil de, snf adyla erimek iin ilk
etapta u kodu denemek aklnza gelmi olabilir:
>>> from alan import alan
>>> alan.personel_saysn_grntle()

Ancak bu kod size yle bir hata mesaj verir:


Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: personel_saysn_grntle() missing
1 required positional argument: 'self'

nk burada siz alan.personel_saysn_grntle() komutunu vererek aslnda


snfn bir metoduna (class method ) erimeye alyorsunuz. Ancak kodlarmzn

684 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

iinde bir snf metodu yok. Zira, yukarda snf adyla erimeye altmz
personel_saysn_grntle() fonksiyonu bir snf metodu deil, bir rnek metodudur.
rnek metotlarna da snf adlaryla erimemizin mmkn olmadn, bu tr metotlara
eriebilmek iin snf en az bir kez rneklemi olmamz gerektiini biliyorsunuz.
Burada, __init__() ve personel_saysn_grntle() dnda u rnek metotlar
var: personel_saysn_grntle(), personele_ekle(), personeli_grntle(),
kabiliyet_ekle(), kabiliyetlerleri_grntle(). Bunlar birer rnek metodu yapan
eyin, self kelimesi olduunu biliyoruz...
Daha nce de sylediimiz gibi, her ne kadar Pythonda snf niteliklerine hem rnekler hem
de dorudan snf adlar zerinden eriebilsek de rnek niteliklerine ve rnek metotlarna
yalnzca rnekler zerinden eriebiliriz. Bir metoda, snf ad ile eriebilmek iin, ilgili metodu
bir snf metodu olarak tanmlam olmamz gerekir. Peki ama nasl?

39.2 @classmethod Bezeyicisi ve cls

Bildiiniz gibi, rnek metotlarn oluturmak iin self adl bir kelimeden yararlanyorduk.
Tanmladmz rnek metotlarnn parametre listesinde ilk sraya yerletirdiimiz bu kelimeyi
kullanarak, snf iinde rnek metotlarna eriebiliyoruz. te snf metotlar iin de benzer bir
ilem yapacaz.
ok basit bir rnek verelim:
class Snf():
snf_nitelii = 0

def __init__(self, param1, param2):


self.param1 = param1
self.param2 = param2
self.rnek_nitelii = 0

def rnek_metodu(self):
self.rnek_nitelii += 1
return self.rnek_nitelii

def snf_metodu(cls):
cls.snf_nitelii += 1
return cls.snf_nitelii

Burada rnek_metodu() ile snf_metodu() arasndaki fark, ilkinde self, ikincisinde ise
cls kullanmamz. Ancak hatrlarsanz, self kelimesinin Python asndan bir zorunluluk
olmadn sylemitik. Tpk self gibi, aslnda cls kelimesi de Python asndan bir zorunluluk
deildir. Yani cls yerine de istediimiz kelimeyi kullanabilirdik. Bu metotlarda nemli olan,
parametre listesinin ilk srasn igal eden kelimenin ne olduudur. Dolaysyla yukardaki
rnekte Python asndan rnek_metodu() ile snf_metodu() arasnda hibir fark bulunmaz.
Python her iki metodu da birer rnek metodu olarak deerlendirir. Bu iki rnek metodu
arasndaki fark, ilkinde snf rneklerini temsil edecek kelimenin self, ikincisinde ise cls olarak
belirlenmi olmasdr. Python self veya cls kelimelerine zel bir nem atfetmez. Ama Python
topluluu iinde, rnek metotlar iin self, snf metotlar iin ise cls kullanmak ok gl bir
gelenektir.
Szn z, snf_metodu() fonksiyonunun ilk parametresini cls yapm olmamz bu
metodun bir snf metodu olabilmesi iin gereklidir, ama yeterli deildir. Pythonda bir snf

39.2. @classmethod Bezeyicisi ve cls 685


Python 3 iin Trke Klavuz, Srm 3

metodu oluturabilmek iin bir paraya daha ihtiyacmz var:


class Snf():
snf_nitelii = 0

def __init__(self, param1, param2):


self.param1 = param1
self.param2 = param2
self.rnek_nitelii = 0

def rnek_metodu(self):
self.rnek_nitelii += 1
return self.rnek_nitelii

@classmethod
def snf_metodu(cls):
cls.snf_nitelii += 1
return cls.snf_nitelii

te Pythonda bir snf metodunu rnek metodundan ayran asl e, yukardaki rnekte
grdmz @classmethod ifadesidir. Pythonda isminin nnde @ iareti olan bu
tr elere bezeyici (decorator ) ad verilir. Grdnz gibi, @classmethod bezeyicisi,
yukardaki rnekte bir fonksiyonu snf metoduna dntrme ilevi gryor. lerleyen
derslerimizde bezeyicilerin baka zelliklerinden de sz edeceiz. Gelin isterseniz imdi
yukarda rendiimiz zellii alan() adl snfa uygulayalm:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

@classmethod
def personel_saysn_grntle(cls):
print(len(cls.personel))

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Yukarda personel_saysn_grntle() adl fonksiyonun yansra,

686 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

personeli_grntle() adl fonksiyonu da bir snf metodu haline getirdik. nk


tpk personel_saysn_grntle() fonksiyonu gibi, personeli_grntle() fonksiyonu
da aslnda tek tek rneklerden ziyade snfn genelini ilgilendiriyor. Dolaysyla bu fonksiyona
da snf ad zerinden eriebilmek gayet makul ve mantkl bir itir.
Snf metotlarmz baaryla tanmladmza gre artk yukardaki snf u ekilde
kullanabiliriz:
>>> from alan import alan
>>> alan.personel_saysn_grntle()

Bir snf metodu olarak tanmladmz personel_saysn_grntle() fonksiyonu artk


ilgili snfn herhangi bir rneine baml olmad iin, snf rneklemek zorunda kalmadan,
yalnzca snf adn kullanarak personel_saysn_grntle() fonksiyonuna eriebiliyoruz.
Bu da bize personel saysnn 0 olduu durumu grntleyebilme imkan veriyor...
Ayrca, personel_saysn_grntle() adl snf metodumuz, ziksel olarak da snfn
iinde yer ald iin, semeli ie aktarmalarda snfn teki eleriyle birlikte bu metot da
aktarlacaktr:
>>> from alan import alan
>>> dir(alan)

Listede snf metodumuzun da olduunu gryorsunuz.


Personele ye ekledikten sonra bu metodu nasl kullanacamz biliyorsunuz:
>>> ahmet = alan('Ahmet')

Ahmet adl kii personele eklendi

>>> mehmet = alan('Mehmet')

Mehmet adl kii personele eklendi

>>> aye = alan('Aye')

Aye adl kii personele eklendi

>>> alan.personel_saysn_grntle()

Grdnz gibi, snf metodumuza dorudan snf adn kullanarak eriebiliyoruz. Elbette bu
durum, snf metoduna rnek adlar zerinden de erimemize engel deil. Eer arzu edersek
personel_saysn_grntle() adl snf metodunu u ekilde de arabiliriz:
>>> aye.personel_saysn_grntle()

>>> ahmet.personel_saysn_grntle()

>>> mehmet.personel_saysn_grntle()

39.2. @classmethod Bezeyicisi ve cls 687


Python 3 iin Trke Klavuz, Srm 3

Ancak rnek metotlarna ve rnek niteliklerine atfta bulunmak iin rnek adlarn kullanmak,
snf metotlar ve snf niteliklerine atfta bulunmak iin ise snf adlarn tercih etmek daha
akllca olabilir.
personel_saysn_grntle() fonksiyonu iin sylediimiz bu szler,
personeli_grntle() fonksiyonu iin de aynen geerlidir.
Szn z, snfn herhangi bir rneine bal olmayan bir ilem yapan, ama anlamsal olarak
da sna ilikili olduu iin snf dnda brakmak istemediiniz fonksiyonlar birer snf
metodu olarak tanmlayabilirsiniz.

39.3 Alternatif naclar

Snf metotlarnn, iimize yarayabilecek bir baka zellii ise, bunlarn bir alternatif
inac (alternative constructor ) olarak kullanlabilecek olmasdr. Alternatif neyci? diye
sorduunuzu rahatlkla duyabiliyorum...
Gelin isterseniz alternatif inac kavramn bir dizi rnek zerinde kabataslak da olsa
aklamaya alalm.
imdi elinizde yle bir kitap listesi olduunu dnn:
liste = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]

Bu liste, her bir kitap iin, srasyla o kitabn ISBN numarasn, yazarn, ismini ve yaynevini
gsteren birer demetten oluuyor. Amacmz, bu listeden eitli ltlere gre sorgulama
yapabilen bir program yazmak. Yazdmz program; isbn, isim, eser ve yaynevi ltlerine
gre bu listeden veri alabilmemizi salayacak.
lk denememizi yapalm:
liste = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]

def sorgula(lt=None, deer=None):


for li in liste:
if not lt and not deer:
print(*li, sep=', ')

elif lt == 'isbn':
if deer == li[0]:
print(*li, sep=', ')

elif lt == 'yazar':
if deer == li[1]:
print(*li, sep=', ')

elif lt == 'eser':
if deer == li[2]:
print(*li, sep=', ')

688 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

elif lt == 'yaynevi':
if deer == li[3]:
print(*li, sep=', ')

Burada ncelikle kitap listemizi tanmladk. Daha sonra da sorgulama ilemini


gerekletirecek sorgula() adl bir fonksiyon yazdk.
Bu fonksiyon toplam iki parametre alyor: lt ve deer. Bu parametrelerin ntanml
deerlerini None olarak belirledik. Bylece bu fonksiyonu herhangi bir argman vermeden
de altrabileceiz.
Fonksiyon gvdesinde ilk yaptmz i, fonksiyon argmansz altrldnda, yani lt ve
deer iin herhangi bir deer belirlenmediinde ne olacan ayarlamak:
for li in liste:
if not lt and not deer:
print(*li, sep=', ')

Eer lt ve deer parametreleri iin herhangi bir deer belirtilmemise, yani bunlar None
olarak braklmsa, kitap listesinin tamamn, her bir e arasna birer virgl yerletirerek
ekrana basyoruz.
Eer sorgula() fonksiyonu arlrken lt parametresine isbn argman, deer
parametresine ise bir ISBN deeri verilmise u ilemi yapyoruz:
elif lt == 'isbn':
if deer == li[0]:
print(*li, sep=', ')

Burada yaptmz ey u: Eer lt isbn ise, fonksiyona verilen deer argmann, kitap
listesi iindeki her bir demetin ilk srasnda aryoruz. nk ISBN bilgileri demetlerin ilk
srasnda yer alyor. Eer bu koul salanrsa listenin ilgili ksmn ekrana basyoruz:
if deer == li[0]:
print(*li, sep=', ')

Bu mant kullanarak teki ltler iin de birer sorgu kodu yazyoruz:


elif lt == 'yazar':
if deer == li[1]:
print(*li, sep=', ')

elif lt == 'eser':
if deer == li[2]:
print(*li, sep=', ')

elif lt == 'yaynevi':
if deer == li[3]:
print(*li, sep=', ')

Her bir deer i, listenin ilgili srasnda aradmza dikkat edin. Yazar bilgisi demetlerin
ikinci srasnda yer ald iin li[1] i, ayn gerekeyle eser iin li[2] yi, yaynevi iin ise li[3]
sorguluyoruz.
Gelelim bu fonksiyonu nasl kullanacamza...
Her zaman sylediimiz gibi, Pythonn etkileimli kabuu mkemmel bir test ortamdr. O
halde imdi bu kodlar klist.py adl bir dosyaya kaydedelim ve dosyann bulunduu dizinde

39.3. Alternatif naclar 689


Python 3 iin Trke Klavuz, Srm 3

bir etkileimli kabuk oturumu balatarak modlmz ie aktaralm:


>>> import klist

nce klist modl iindeki sorgula() fonksiyonunu argmansz olarak aralm:


>>> klist.sorgula()

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis


975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem

Tam da beklediimiz gibi, fonksiyon argmansz arldnda btn kitap listesini, her bir e
arasnda bir virgl olacak ekilde ekrana basyor.
imdi de mesela ISBN numarasna gre birka sorgu ilemi gerekletirelim:
>>> klist.sorgula('isbn', '9789754060409')

9789754060409, Nietzsche, Byle Buyurdu Zerdt , Cem

>>> klist.sorgula('isbn', '975872519X')

975872519X, Evren, Postmodern Bir Kz Sevdim, thaki

>>> klist.sorgula('isbn', '9789753424080')

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis

Burada, sorgula() fonksiyonunun ilk parametresine argman olarak isbn deerini verdik.
Bylece programmz ISBN numarasna gre sorgu yapmak istediimizi anlad. Daha sonra
da ikinci argman olarak istediimiz bir ISBN numarasn yazdk ve sorgu ilemini tamamladk.
Bir de yaynevine gre sorgulama yapalm:
>>> klist.sorgula('yaynevi', 'Metis')

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis

>>> klist.sorgula('yaynevi', 'thaki')

975872519X, Evren, Postmodern Bir Kz Sevdim, thaki

>>> klist.sorgula('yaynevi', 'Cem')

9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem

Grdnz gibi, fonksiyonumuz gayet gzel alyor...


Yukarda verdiimiz kodlar, bahsettiimiz ama iin yazlabilecek tek alternatif deildir
elbette. Mesela yukardaki if-else yapsn bir szlk iine yerletirerek ok daha sade bir
program elde edebiliriz.
Dikkatlice inceleyin:
liste = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]

690 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

def sorgula(lt=None, deer=None):


d = {'isbn' : [li for li in liste if deer == li[0]],
'yazar' : [li for li in liste if deer == li[1]],
'eser' : [li for li in liste if deer == li[2]],
'yaynevi' : [li for li in liste if deer == li[3]]}

for e in d.get(lt, liste):


print(*e, sep = ', ')

Burada btn if-else cmleciklerini birer liste retecine dntrp, d adl szln
anahtarlar olarak belirledik. Artk sorgulama ilemlerini bir if-else yaps iinde deil de,
bir szlk iinden gerekletireceiz.
Hangi parametrenin hangi listeyi aracan belirleyen szlmz yazdktan sonra,
szlklerin get() metodunu kullanarak, lt argmannn deerine gre szlkten veri
ekiyoruz. Eer szlkte bulunmayan bir lt deeri verilirse tm listeyi ekrana basyoruz.
Bu arada, eer d szl iindeki liste retelerinin birbirini tekrar eder bir yapda olmas sizi
rahatsz ediyorsa, bu ksm bir yardmc fonksiyon araclyla sadeletirebilirsiniz:
liste = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]

def bul(deer, sra):


return [li for li in liste if deer == li[sra]]

def sorgula(lt=None, deer=None):


d = {'isbn' : bul(deer, 0),
'yazar' : bul(deer, 1),
'eser' : bul(deer, 2),
'yaynevi' : bul(deer, 3)}

for e in d.get(lt, liste):


print(*e, sep = ', ')

Burada btn liste retelerini tek bir bul() fonksiyonu iinde oluturarak, sorgula()
fonksiyonu iindeki d szlne gnderdik.
Bu kodlar da ayn ilk program rneinde olduu gibi kullanyoruz:
>>> import klist
>>> klist.sorgula()

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis


975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem

>>> klist.sorgula('yazar', 'Nietzsche')

9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem

>>> klist.sorgula('eser', 'Sana Gl Bahesi Vadetmedim')

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis

Yukardaki kodlar yazmann daha baka alternatieri de var. Mesela, eer arzu ederseniz,

39.3. Alternatif naclar 691


Python 3 iin Trke Klavuz, Srm 3

yukardaki kodlar bir snf yaps iinde de ifade edebilirsiniz:


class Sorgu():
def __init__(self):
self.liste = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]

def bul(self, deer, sra):


return [li for li in self.liste if deer == li[sra]]

def sorgula(self, lt=None, deer=None):


d = {'isbn' : self.bul(deer, 0),
'yazar' : self.bul(deer, 1),
'eser' : self.bul(deer, 2),
'yaynevi' : self.bul(deer, 3)}

for e in d.get(lt, self.liste):


print(*e, sep = ', ')

Burada kitap listesini bir rnek nitelii olarak tanmlamak suretiyle snfn her yerinden
kullanlabilir hale getirdik.
Ardndan da bul() ve sorgula() adl fonksiyonlar, birer rnek metodu biiminde snf iine
yerletirdik.
Bu snf da u ekilde kullanabiliriz:
>>> import klist
>>> sorgu = klist.Sorgu()
>>> sorgu.sorgula()

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis


975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem

>>> sorgu.sorgula('yazar', 'Evren')

975872519X, Evren, Postmodern Bir Kz Sevdim, thaki

Elbette, bu rnekte, ilk yazdmz kodlar bir snf yaps iinde tarif etmenin bize pek bir
katks yok. Burada yaptmz ey esasnda btn kodlar Sorgu adl bir etki alan iine
tamaktan fazlas deil. Ama byle bir imkannzn da olduunu bilmeniz her halkarda sizin
iin faydal olacaktr.
Gelelim yukardaki kodlar yazmann son alternatine:
class Sorgu():
def __init__(self, deer=None, sra=None):
self.liste = [('9789753424080', 'Greenberg', 'Sana Gl Bahesi Vadetmedim', 'Metis'),
('975872519X', 'Evren', 'Postmodern Bir Kz Sevdim', 'thaki'),
('9789754060409', 'Nietzsche', 'Byle Buyurdu Zerdt', 'Cem')]

if not deer and not sra:


l = self.liste
else:
l = [li for li in self.liste if deer == li[sra]]

for i in l:

692 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

print(*i, sep=', ')

@classmethod
def isbnden(cls, isbn):
cls(isbn, 0)

@classmethod
def yazardan(cls, yazar):
cls(yazar, 1)

@classmethod
def eserden(cls, eser):
cls(eser, 2)

@classmethod
def yaynevinden(cls, yaynevi):
cls(yaynevi, 3)

Burada da, her bir lt ayr birer snf metodu olarak tanmladk. Bylece bu ltleri
yapsal olarak birbirinden ayrm olduk. Yukardaki snf u ekilde kullanabiliriz:
nce modlmz ie aktaralm:
>>> from klist import Sorgu

ISBN numarasna gre bir sorgu gerekletirelim:


>>> Sorgu.isbnden("9789753424080")

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis

Grdnz gibi, snf metodu yaklam, gayet temiz bir sorgu kodu retmemize imkan
tanyor.
Bir de yazara ve esere gre sorgulayalm:
>>> Sorgu.yazardan("Greenberg")

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis

>>> Sorgu.eserden("Postmodern Bir Kz Sevdim")

975872519X, Evren, Postmodern Bir Kz Sevdim, thaki

Bunlar da gayet gzel grnyor.


imdi bir de btn listeyi alalm:
>>> hepsi = Sorgu()

9789753424080, Greenberg, Sana Gl Bahesi Vadetmedim, Metis


975872519X, Evren, Postmodern Bir Kz Sevdim, thaki
9789754060409, Nietzsche, Byle Buyurdu Zerdt, Cem

Grdnz gibi, snf parametresiz olarak rneklediimizde btn listeyi elde ediyoruz.
te alternatif ina denen ilem tam olarak budur. Yukardaki rnekte isbnden(),
yazardan(), eserden() ve yaynevinden() adl snf metotlar, Sorgu() adl snf alternatif

39.3. Alternatif naclar 693


Python 3 iin Trke Klavuz, Srm 3

ekillerde ina etmemizi salyor 1 .


Normal artlarda, bir snf, __init__() fonksiyonuna verdiimiz parametreler araclyla
ina ediyoruz (birka sayfa sonra ina kavramndan daha ayrntl olarak bahsedeceiz).
Mesela:
class Giri():
def __init__(self, mesaj='Mteri numaranz: '):
cevap = input(mesaj)
print('Hogeldiniz!')

Burada tanmladmz Giri() snf, bir mteri numaras araclyla sisteme giri imkan
salyor:
>>> from sistem import Giri #kodlarmz sistem.py dosyas iinde
>>> Giri()

Eer biz ayn zamanda bir parola ve TC Kimlik Numaras ile de giri imkan salamak istersek,
baka yntemlerin yansra, snf metotlarndan da yararlanabiliriz:
class Giri():
def __init__(self, mesaj='Mteri numaranz: '):
cevap = input(mesaj)
print('Hogeldiniz!')

@classmethod
def paroladan(cls):
mesaj = 'Ltfen parolanz giriniz: '
cls(mesaj)

@classmethod
def tcknden(cls):
mesaj = 'Ltfen TC kimlik numaranz giriniz: '
cls(mesaj)

Bu ekilde yukardaki snf aadaki gibi de ina etme imkanna kavuuyoruz:


>>> Giri.paroladan()

veya:
>>> Giri.tcknden()

Snf metotlar iinde kullandmz cls(mesaj) satrlar, Giri() adl snf farkl bir parametre
ile armamz salyor. Grdnz gibi, bu snfn mesaj parametresinin ntanml deeri
Mteri numaranz: . Snfmz farkl bir ekilde arabilmek iin, cls(mesaj) kodlar
yardmyla snfn mesaj parametresini Ltfen parolanz giriniz: ve Ltfen TC kimlik
numaranz giriniz: deerleri ile yeniden altryoruz.
Daha nce de birka kez vurguladmz gibi, cls kelimesi Python asndan bir zorunluluk
deildir. Yani yukardaki snf mesela yle de yazabilirdik:
class Giri():
def __init__(self, mesaj='Mteri numaranz: '):
cevap = input(mesaj)
1
Aslnda burada ina edilen ey snftan ziyade nesnedir. Bu durumu ve nesne kavramn bir sonraki blmde
ayrntl olarak ele alacaz.

694 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

print('Hogeldiniz!')

@classmethod
def paroladan(snf):
mesaj = 'Ltfen parolanz giriniz: '
snf(mesaj)

@classmethod
def tcknden(snf):
mesaj = 'Ltfen TC kimlik numaranz giriniz: '
snf(mesaj)

Ancak, tpk self kelimesinde olduu gibi, cls de Python topluluu iinde son derece yerleik
bir gelenektir. Bu gelenei bozmak isteyeceinizi zannetmiyorum.
lk bakta snf metotlar size pek gerekli deilmi gibi gelebilir. Ama eer bu metotlarn
gerek dnyadaki kullanmna ilikin bir rnek verirsek belki kriniz deiir.
Snf metotlarnn kullanmna ilikin gzel bir rnei datetime modlnde grebilirsiniz.
Ayrca bkz.:
Aadaki rnei daha iyi anlayabilmek iin datetime Modl ve time Modl belgelerine
baknz.
Bir standart ktphane modl olan datetime n kaynak dosyasn aarsanz (kaynak
dosyann nerede olduunu nasl renebilirim diye soran arkadalara teesserimi
iletiyorum...), orada date snfnn yle yazldn greceksiniz:
class date:
__slots__ = '_year', '_month', '_day'

def __new__(cls, year, month=None, day=None):


if (isinstance(year, bytes) and len(year) == 4 and
1 <= year[2] <= 12 and month is None): # Month is sane
# Pickle support
self = object.__new__(cls)
self.__setstate(year)
return self
_check_date_fields(year, month, day)
self = object.__new__(cls)
self._year = year
self._month = month
self._day = day
return self

@classmethod
def fromtimestamp(cls, t):
y, m, d, hh, mm, ss, weekday, jday, dst = _time.localtime(t)
return cls(y, m, d)

@classmethod
def today(cls):
t = _time.time()
return cls.fromtimestamp(t)

@classmethod
def fromordinal(cls, n):

39.3. Alternatif naclar 695


Python 3 iin Trke Klavuz, Srm 3

y, m, d = _ord2ymd(n)
return cls(y, m, d)

Grdnz gibi, burada tane snf metodu var:


@classmethod
def fromtimestamp(cls, t):
...

@classmethod
def today(cls):
...

@classmethod
def fromordinal(cls, n):
...

Normal artlarda datetime modl iindeki date snfn u ekilde kullanyoruz:


>>> import datetime
>>> bugn = datetime.date(2015, 6, 16)

Bu ekilde, date snfna srasyla yl, ay ve gn bilgisi girerek bugn adl bir tarih nesnesi
oluturmu oluyoruz. Bu ekilde herhangi bir tarihi elle oluturabilirsiniz.
Eer amacnz bugnn tarihini oluturmaksa, yl, ay ve gn bilgilerini yukardaki gibi date
snfna elle girebileceiniz gibi, today() adl snf metodunu da kullanabilirsiniz:
>>> bugn = datetime.date.today()

te bylece, date snfnn size sunduu bir alternatif inac (today()) vastasyla bugnn
tarihini otomatik olarak elde etmi oldunuz.
Ayn ekilde, eer elinizde bir zaman damgas varsa ve siz bu zaman damgasndan bir
tarih elde etmek istiyorsanz yine date snfnn sunduu bir baka alternatif inacdan
yararlanabilirsiniz:
>>> import time
>>> zaman_damgas = time.time()
>>> bugn = datetime.date.fromtimestamp(zaman_damgas)

Eer elinizde tam say biimli bir Gregoryen tarih verisi varsa bu veriyi kullanarak da bir tarih
nesnesi elde edebilirsiniz:
>>> gregoryen = 735765
>>> bugn = datetime.date.fromordinal(gregoryen)

datetime.date(2015, 6, 16)

Uzun lafn ksas, alternatif inaclar, bir snftan nesne oluturmak iin bize alternatif yollar
sunan son derece faydal aralardr. Bu arada, eer bu blmde deindiimiz baz kavramlar
anlamakta zorlandysanz hi cannz skmayn. Bir sonraki blm iledikten sonra, burada
anlatlanlar kafanza ok daha salam bir ekilde yerlemi olacak.

696 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

39.4 Statik Metotlar

Pythonda rnek metotlar ve snf metotlar dnda bir de statik metotlar bulunur. Bildiiniz
gibi, rnek nitelikleri zerinde ilem yapacamz zaman rnek metotlarn kullanyoruz.
Ayn ekilde snf nitelikleri zerinde ilem yapacamz zaman ise snf metotlarndan
faydalanyoruz. rnek metotlar iinde herhangi bir rnek niteliine erimek istediimizde
self kelimesini kullanyoruz. Snf metotlar iinde bir snf niteliine erimek iin ise cls
kelimesini kullanyoruz. te eer bir snf iindeki herhangi bir fonksiyonda rnek veya snf
niteliklerinin hibirine erimeniz gerekmiyorsa, statik metotlar kullanabilirsiniz.

39.5 @staticmethod Bezeyicisi

Buraya gelene kadar rendiimiz rnek ve snf metotlarn nasl kullanacamz


biliyorsunuz:
class Snf():
snf_nitelii = 0

def __init__(self, veri):


self.veri = veri

def rnek_metodu(self):
return self.veri

@classmethod
def snf_metodu(cls):
return cls.snf_nitelii

Burada rnek_metodu(), self yardmyla rnek niteliklerine eriiyor. snf_metodu() ise cls
yardmyla snf niteliklerine eriiyor. Snf metodu tanmlamak iin ayrca @classmethod
bezeyicisini de kullanyoruz. te eer snf iinde tanmlayacanz fonksiyon herhangi bir
rnek ya da snf nitelii zerinde herhangi bir ilem yapmayacaksa yle bir ey yazabilirsiniz:
class Snf():
snf_nitelii = 0

def __init__(self, veri):


self.veri = veri

def rnek_metodu(self):
return self.veri

@classmethod
def snf_metodu(cls):
return cls.snf_nitelii

@staticmethod
def statik_metot():
print('merhaba statik metot!')

Grdnz gibi, statik metotlar tanmlamak iin @staticmethod bezeyicisini kullanyoruz.


Statik metotlar, ilk parametre olarak self veya cls benzeri kelimeler almaz. nk bu tr
snarn rnek veya snf nitelikleri ile herhangi bir ii yoktur.

39.4. Statik Metotlar 697


Python 3 iin Trke Klavuz, Srm 3

Peki statik metotlar ne ie yarar?


Bu metotlar snf metotlarna ok benzer. Tpk snf metotlarnda olduu gibi, anlamsal olarak
sna ilgili olan, ancak snf metotlarnn aksine bu snfn herhangi bir niteliine erimesine
gerek olmayan fonksiyonlar, snf dna atmak yerine, birer statik metot olarak snf iine
yerletirebiliriz.
Basit bir rnek verelim:
class Mat():
'''Matematik ilemleri yapmamz salayan
bir snf.'''

@staticmethod
def pi():
return 22/7

@staticmethod
def karekk(say):
return say ** 0.5

Burada Mat() adl bir snf tanmladk. Bu snf iinde iki adet statik metodumuz var: pi() ve
karekk(). Grdnz gibi, bu iki fonksiyon, rnek ve snf metotlarnn aksine ilk parametre
olarak self veya cls almyor. nk bu iki snfn da snf veya rnek nitelikleriyle herhangi bir
ii yok.
Statik metotlar hem rnekler hem de snf adlar zerinden kullanabiliriz.
Yukardaki kodlarn mat.py adl bir dosyada yer aldn varsayarsak:
>>> from mat import Mat
>>> m = Mat()
>>> m.pi() #rnek zerinden

3.142857142857143

>>> m.karekk(144) #rnek zerinden

12.0

>>> Mat.pi() #snf zerinden


3.142857142857143

>>> Mat.karekk(144) #snf zerinden

12.0

Statik metotlarn zellikle snf adlar zerinden kullanlabilmesi, bu tr metotlar epey


kullanl hale getirir. Bylece snf rneklemek zorunda kalmadan, snf iindeki statik
metotlara ulaabiliriz.
Elbette eer isteseydik biz bu fonksiyonlar yle de tanmlayabilirdik:
class Mat():
'''Matematik ilemleri yapmamz salayan
bir snf.'''

def pi(self):
return 22/7

698 Blm 39. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

def karekk(self, say):


return say ** 0.5

Burada bu iki fonksiyonu birer rnek metodu olarak tanmladk. Bu fonksiyonlar bu ekilde
tanmladmzda, bunlara rnekler zerinden eriebiliriz:
>>> from mat import Mat
>>> m = Mat()
>>> m.pi()

3.142857142857143

>>> m.karekk(144)

12.0

Ancak bildiiniz gibi, rnek metotlarna snf adlar zerinden eriemeyiz:


>>> Mat.pi()

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: pi() missing 1 required positional argument: 'self'

Ayn ekilde bunlar snf metodu olarak da tanmlayabilirdik:


class Mat():
'''Matematik ilemleri yapmamz salayan
bir snf.'''

@classmethod
def pi(cls):
return 22/7

@classmethod
def karekk(cls, say):
return say ** 0.5

Bu metotlar byle tanmladmzda, bu metotlara hem rnekler zerinden hem de snf ad


zerinden eriebiliriz:
>>> from mat import Mat
>>> m = Mat()
>>> m.pi() #rnek zerinden

3.142857142857143

>>> m.karekk(144) #rnek zerinden

12.0

>>> Mat.pi() #snf zerinden


3.142857142857143

>>> Mat.karekk(144) #snf zerinden

12.0

39.5. @staticmethod Bezeyicisi 699


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, kullanm asndan snf metotlar ile statik metotlar ayn. Ancak Mat()
snf iindeki fonksiyonlar birer snf metodu olarak tanmladmzda gereksiz yere cls
parametresi kullanm oluyoruz. Fonksiyon iinde herhangi bir yerde kullanlmad iin,
yukardaki rnekte cls parametresinin hibir amaca hizmet etmediine dikkat edin.
Statik metotlarn ok sk kullanlan aralar olmadn da belirterek yolumuza devam edelim.

Dipnotlar:

700 Blm 39. Nesne Tabanl Programlama (Devam)


BLM 40

Nesne Tabanl Programlama (Devam)

Bu blmde de, temellerini geen derslerimizde attmz nesne tabanl programlama


konusunu incelemeye devam edeceiz. Bu blmde uygulamaya ynelik baz rnekler
yapmann yansra, nesne tabanl programlamaya ilikin baz teorik bilgiler de vereceiz.

40.1 Nesneler

Geen blmlerden birinde snar tanmlarken, bunlarn, nesne retmemizi salayan bir
veri tipi olduuna dair mulak bir laf etmitik. te bu balk altnda, o tanm iinde geen ve
nesne tabanl programlamann temelini oluturan nesne kavram zerine eileceiz.

40.2 Nesne Nedir?

Programlamaya ilikin kavramlar iinde, zellikle programlamaya yeni balayanlarn kafasn


en fazla kartran kavram nedir diye sorsak, herhalde alacamz cevap nesne olur.
Hakikaten, sada solda srekli duyduumuz bu nesne denen ey, teden beri yazlm
gelitirici adaylarnn zihnini kartrr durur.
Aslnda nesne (object ) dedikleri, ilk bakta uyandrd izlenimin aksine, anlamas zor,
gizemli bir kavram deildir. Dolaysyla, nesne kavramna ilikin olarak renmemiz gereken
ilk ey, bunun abartlacak veya korkulacak bir ey olmaddr. Peki ama tam olarak nedir bu
nesne dedikleri?
Kabaca, Pythonda belli birtakm metotlara ve/veya niteliklere sahip olan elere nesne ad
verilir. Yani nesne kelimesi, iinde birtakm metot ve/veya nitelikler barndran eleri
tanmlamak iin kullanlan bir tabirden, basit bir isimlendirmeden ibarettir.
Peki bir nesne oluturmak iin acaba ne yapmamz gerekiyor?
Hatrlarsanz, geen blmde, snarn nesne retmemizi salayan veri tipleri olduunu
sylemitik. O halde gelin minik bir nesne retelim:
class Snf():
pass

snf = Snf()

te bu kodlardaki snf = Snf() komutu ile bir nesne retmi olduk. Nesnemizin ad
da snf. Teknik olarak ifade edersek, snf rnei, Snf() adl snfn btn nitelik ve

701
Python 3 iin Trke Klavuz, Srm 3

metotlarn bnyesinde barndran bir nesnedir. Mesela yukardaki kodlarn snf.py adl bir
dosyada bulunduunu varsayarak yle bir deneme yapalm:
>>> import snf
>>> snf = snf.Snf()

Bu ekilde, kodlar ieren modl ie aktarm ve modl iindeki Snf() adl snf snf ad ile
rneklemi olduk. Yani yukardaki kodlar yardmyla snf adl bir nesne oluturduk. Bakalm
bu nesne hangi nitelik ve/veya metotlara sahipmi:
>>> dir(snf)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',


'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__']

Grdnz gibi, biz bo bir snf tanmlam olsak da, snf nesnesi ntanml olarak yine de
baz nitelik ve metotlara sahip. te Pythonda, yukardaki gibi birtakm nitelik ve metotlara
sahip olan bu tr elere nesne ad veriyoruz.
Bir de isterseniz yukardaki gibi bo bir snf tanmlamak yerine, snfmz iinde kendimiz
birtakm nitelik ve metotlar tanmlamay da deneyelim:
class Snf():
snf_nitelii = 'snf nitelii'

def __init__(self):
self.rnek_nitelii = 'rnek nitelii'

def rnek_metodu(self):
print('rnek metodu')

@classmethod
def snf_metodu(cls):
print('snf metodu')

@staticmethod
def statik_metot():
print('statik metot')

imdi nesne ieriini tekrar kontrol edelim:


>>> import snf
>>> snf = snf.Snf()
>>> dir(snf)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',


'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'statik_metot', 'snf_metodu', 'snf_nitelii',
'rnek_metodu', 'rnek_nitelii']

Grdnz gibi, kendi tanmladmz nitelik ve metotlar da snf adl nesne iine eklenmi...

702 Blm 40. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

te snf adl snf rneinin, yukarda gsterilen birtakm durum ve davranlara sahip
olmasndan yola karak, snf rneinin bir nesne olduunu sylyoruz.
Yukardaki aklamalarn, nesne kavram hakknda en azndan bir kir sahibi olmanz
saladn zannediyorum. Grdnz gibi, nesne denen ey aslnda basit bir
isimlendirmeden ibarettir: Pythonda belli bir durumu/nitelii/metodu/davran olan
elemanlara/elere nesne (object ) ad veriyoruz. Peki o zaman, nesne denen ey basit bir
adlandrmadan ibaretse nesne tabanl programlamann etrafnda koparlan bunca yaygarann
sebebi nedir?
Nesne tabanl programlamay bu kadar zel ve nemli klan eyin ne olduunu anlamak iin
gelin nesnelere biraz daha yakndan bakalm.

40.3 Basit Bir Oyun

Gelin isterseniz nesne denen kavram daha iyi anlayabilmek, bir nesneyi nesne yapan metot
ve nitelikler arasndaki ilikiyi daha net bir ekilde kavrayabilmek iin, komut satr zerinde
alan ok basit bir oyun tasarlayalm. Bu ekilde hem eski bilgilerimizi tekrar etmi oluruz,
hem teorik bilgilerimizi uygulama sahasna dkm oluruz, hem de yeni eyler renmi
oluruz.
Oyunumuzun kodlar yle:
import time
import random
import sys

class Oyuncu():
def __init__(self, isim, can=5, enerji=100):
self.isim = isim
self.darbe = 0
self.can = can
self.enerji = enerji

def mevcut_durumu_grntle(self):
print('darbe: ', self.darbe)
print('can: ', self.can)
print('enerji: ', self.enerji)

def saldr(self, rakip):


print('Bir saldr gerekletirdiniz.')
print('Saldr sryor. Bekleyiniz.')

for i in range(10):
time.sleep(.3)
print('.', end='', flush=True)

sonu = self.saldr_sonucunu_hesapla()

if sonu == 0:
print('\nSONU: kazanan taraf yok')

if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
self.darbele(rakip)

40.3. Basit Bir Oyun 703


Python 3 iin Trke Klavuz, Srm 3

if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
self.darbele(self)

def saldr_sonucunu_hesapla(self):
return random.randint(0, 2)

def ka(self):
print('Kalyor...')
for i in range(10):
time.sleep(.3)
print('\n', flush=True)

print('Rakibiniz sizi yakalad')

def darbele(self, darbelenen):


darbelenen.darbe += 1
darbelenen.enerji -= 1
if (darbelenen.darbe % 5) == 0:
darbelenen.can -= 1
if darbelenen.can < 1:
darbelenen.enerji = 0
print('Oyunu {} kazand!'.format(self.isim))
self.oyundan_k()

def oyundan_k(self):
print('klyor...')
sys.exit()

##################################

# Oyuncular
siz = Oyuncu('Ahmet')
rakip = Oyuncu('Mehmet')

# Oyun balangc
while True:
print('u anda rakibinizle kar karyasnz.',
'Yapmak istediiniz hamle: ',
'Saldr: s',
'Ka: k',
'k: q', sep='\n')

hamle = input('\n> ')


if hamle == 's':
siz.saldr(rakip)

print('Rakibinizin durumu')
rakip.mevcut_durumu_grntle()

print('Sizin durumunuz')
siz.mevcut_durumu_grntle()

if hamle == 'k':
siz.ka()

if hamle == 'q':

704 Blm 40. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

siz.oyundan_k()

Komut satr zerinde alan basit bir oyundur bu. Dilerseniz bu kodlar incelemeye
balamadan nce, bir dosyaya kaydedip altrn. Karnza yle bir ekran gelecek:
u anda rakibinizle kar karyasnz.
Yapmak istediiniz hamle:
Saldr: s
Ka: k
k: q

>

Programmz bize burada farkl seenek sunuyor. Eer rakibimize saldrmak istiyorsak
klavyedeki s tuuna; rakibimizden kamak istiyorsak klavyedeki k tuuna; yok eer oyundan
kmak istiyorsak da klavyedeki q tuuna basacaz. Tercihinizi belirleyip neler olduunu
inceleyin ve oyunu iyice tanmaya aln.
Oyunu iyice anlayp tandktan sonra oyun kodlarn incelemeye geebiliriz.
Yukarda ilk olarak Oyuncu adl bir snf tanmladk:
class Oyuncu():
def __init__(self, isim, can=5, enerji=100):
self.isim = isim
self.darbe = 0
self.can = can
self.enerji = enerji

class kelimesinin snf tanmlamamz salayan bir ara, Oyuncu kelimesinin ise
tanmladmz snfn ad olduunu biliyoruz. Bu satrn hemen ardndan gelen __init__()
fonksiyonu, snfmz rneklendiinde neler olacan tanmladmz yerdir. Bu snfn,
rnekleme srasnda hangi parametreleri alacan da __init__() fonksiyonu iinde
belirliyoruz. Parametre listesinde grdmz ilk e, yani self, snfn o anki rneini
temsil ediyor. Pythonn szdizimi kurallar gereince bu kelimeyi oraya yazmamz gerektiini
biliyoruz.
Yukardaki fonksiyon, self dnda toplam parametre alyor: isim, can ve enerji. Bunlardan
ilki, yani isim parametresinin ntanml bir deeri yok. Dolaysyla snf arrken (yani
rneklerken) bu parametrenin deerini belirtmemiz gerekecek. teki iki parametre olan
can ve enerji ise birtakm ntanml deerlere sahip. Dolaysyla snf rneklendirirken
bu parametrelere farkl bir deer atamadmz srece, bu parametreler, listede belirtilen
deerleri tayacak.
Parametre olarak belirlediimiz deerleri snf iinde kullanabilmek iin, bunlar __init__()
fonksiyonunun gvdesinde birer rnek niteliine dntryoruz:
self.isim = isim
self.darbe = 0
self.can = can
self.enerji = enerji

Burada ilave olarak bir de deeri 0 olan self.darbe adl bir deiken tanmladk. Bu da
snfmzn rnek niteliklerinden biri olup, ilgili oyuncu (yani snfn o anki rnei) darbe aldka
bunun deeri ykselecektir.
Gelin isterseniz bu aamada snfmz rnekleyerek neler olup bittiini daha net anlamaya

40.3. Basit Bir Oyun 705


Python 3 iin Trke Klavuz, Srm 3

alalm:
class Oyuncu():
def __init__(self, isim, can=5, enerji=100):
self.isim = isim
self.darbe = 0
self.can = can
self.enerji = enerji

#Snfmz rnekliyoruz
oyuncu = Oyuncu('Ahmet')

Burada oyuncu = Oyuncu(Ahmet) komutunu verdiimiz anda __init__() fonksiyonu


almaya balyor ve oyuncu adl nesne iin srasyla u deikenleri oluturuyor:
isim = 'Ahmet'
darbe = 0
can = 5
enerji = 100

Bu rnek niteliklerine nasl ulaabileceinizi biliyorsunuz:


print('sim: ', oyuncu.isim)
print('Darbe: ', oyuncu.darbe)
print('Can: ', oyuncu.can)
print('Enerji: ', oyuncu.enerji)

Bata da sylediimiz gibi, Oyuncu() snfn rnekleyerek meydana getireceiniz btn snf
rnekleri, yani nesneler, __init__() fonksiyonu iinde tanmladnz rnek niteliklerini
tayacaktr:
class Oyuncu():
def __init__(self, isim, can=5, enerji=100):
self.isim = isim
self.darbe = 0
self.can = can
self.enerji = enerji

oyuncu1 = Oyuncu('Ahmet')
oyuncu2 = Oyuncu('Mehmet')
oyuncu3 = Oyuncu('Veli')
oyuncu4 = Oyuncu('Aye')

Burada oyuncu1, oyuncu2, oyuncu3 ve oyuncu4 olmak zere drt farkl nesne oluturduk.
Bu nesnelerin hangi niteliklere sahip olacan ise Oyuncu() snfnn tanm iinde belirttik.
Yani snfmz tpk bir fabrika gibi alarak, bizim iin, ayn nitelikleri tayan drt farkl nesne
retti.
te nesne tabanl programlamann zn oluturan nesne budur. Bir nesnenin hangi
niteliklere sahip olacan belirleyen veri tipine snf (class ) derken, o snfn ortaya kard
rne ise nesne (object ) ad veriyoruz. Bunu una benzetebilirsiniz: Eer nsan bir snfsa,
Mahmut bu snfn bir rneidir. Dolaysyla Mahmut, nsan snfndan tremi bir nesnedir.
Ayn ekilde eer Kpek bir snfsa, Karaba da bu snfn bir rneidir. Yani Karaba,
Kpek snfndan tremi bir nesnedir. Mahmutun hangi zelliklere sahip olacan nsan
snfnn nasl tanmland, Karaban hangi zelliklere sahip olacan ise Kpek snfnn
nasl tanmland belirler. te ayn bunun gibi, Oyuncu() snfndan treyen nesnelerin hangi
zelliklere sahip olacan da Oyuncu() snfnn nasl tanmland belirler.

706 Blm 40. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

Kodlarmz incelemeye devam edelim...


def mevcut_durumu_grntle(self):
print('darbe: ', self.darbe)
print('can: ', self.can)
print('enerji: ', self.enerji)

Burada mevcut_durumu_grntle() adl bir rnek metodu tanmladk. rnek metotlarnn


ilk parametresinin her zaman self olmas gerektiini biliyoruz.
Tanmladmz rnek metodunun grevi, Oyuncu() snfndan oluturduumuz nesnelerin
(yani rneklerin) o anki darbe, can ve enerji durumlarn grntlemek. Birer rnek nitelii
olan darbe, can ve enerji deikenlerine self araclyla eritiimize zellikle dikkat ediyoruz.
Gelelim snfmzn nemli rnek metotlarndan biri olan saldr() fonksiyonunu incelemeye:
def saldr(self, rakip):
print('Bir saldr gerekletirdiniz.')
print('Saldr sryor. Bekleyiniz.')

for i in range(10):
time.sleep(.3)
print('.', end='', flush=True)

sonu = self.saldr_sonucunu_hesapla()

if sonu == 0:
print('\nSONU: kazanan taraf yok')

if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
self.darbele(rakip)

if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
self.darbele(self)

Bu fonksiyon, self dnda tek bir parametre alyor. Fonksiyonu altrrken kullanacamz
rakip parametresi, saldrnn kime kar (yani snf rneklerinden hangisine kar)
dzenleneceini belirleyecek.
Fonksiyon gvdesinde ilk olarak yle bir ksm gryoruz:
print('Bir saldr gerekletirdiniz.')
print('Saldr sryor. Bekleyiniz.')

for i in range(10):
time.sleep(.3)
print('.', end='', flush=True)

Burada saldrnn gerekletiine dair kullancy bilgilendirdikten sonra yle bir kod paras
yazdk:
for i in range(10):
time.sleep(.3)
print('.', end='', flush=True)

Bu kodlarda time adl bir standart ktphane modlnn sleep() adl bir metodundan
yararlandmz gryorsunuz. Elbette bu modl kullanabilmek iin ncelikle bu modl

40.3. Basit Bir Oyun 707


Python 3 iin Trke Klavuz, Srm 3

ie aktarm olmamz gerekiyor. Bu ilemi dosyann en banda import time satr yardmyla
gerekletirdiimizi grebilirsiniz.
Yukardaki satrlar, 300er milisaniye aralklarla, yan yana nokta iaretleri yerletirecektir.
Dilerseniz etkileimli kabukta bu kodlar u ekilde test edebilirsiniz:
>>> import time
>>> for i in range(10):
... time.sleep(.3)
... print('.', end='', flush=True)

print() fonksiyonu iinde kullandmz end ve ush parametrelerinin ne olduunu ve ne ie


yaradn ilk derslerimizden hatrlyor olmalsnz. Eer hatrlamyorsanz, bu parametreleri
tek tek kodlardan karp, bu kodlar bir de yle altrn. Sonucun ne olduunu takip ederek,
end ve ush parametrelerinin grevini daha iyi anlayabilirsiniz.
Bu kodlarn ardndan yle bir satr yazdk:
sonu = self.saldr_sonucunu_hesapla()

Burada, saldr_sonucunu_hesapla() adl bir rnek metodunu ardmz gryorsunuz:


def saldr_sonucunu_hesapla(self):
return random.randint(0, 2)

Biraz nce time adl bir standart ktphane modln kullanmtk. imdi ise random adl
baka bir standart ktphane modln kullanyoruz. Elbette bu modl de kullanabilmek
iin ncelikle bu modl import random komutuyla ie aktarm olmamz gerekiyor. Bu
zorunluluu da, tpk time modlnde olduu gibi, dosyann en banda yerine getirmitik.
Yukarda random modln, 0 ile 2 aras rastgele saylar retmek iin kullandk.
random.randint(0, 2) komutu her alnda 0, 1 ve 2 saylarndan birini rastgele
retecektir. Buradan elde ettiimiz sonucu sonu adl bir deikene atayarak saldr()
fonksiyonu iinde u ekilde kullanyoruz:
sonu = self.saldr_sonucunu_hesapla()

if sonu == 0:
print('\nSONU: kazanan taraf yok')

if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
self.darbele(rakip)

if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
self.darbele(self)

Eer randint() metodu 0 saysn retirse, rakibimize kar gerekletirdiimiz saldrnn


sonusuz kaldna hkmediyoruz:
if sonu == 0:
print('\nSONU: kazanan taraf yok')

Eer randint() metodu 1 saysn retirse, rakibimizi baaryla darbelediimize, 2 saysn


retirse de rakibimiz tarafndan darbelendiimize hkmediyoruz:

708 Blm 40. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
self.darbele(rakip)

if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
self.darbele(self)

Saldr sonucunda rakibimizi darbelediimizde ve rakibimizden darbe yediimizde darbele()


adl bir baka rnek metodunu ardmz da gzden karmayn.
Bu arada, rnek metotlarna da self neki ile eritiimize dikkatinizi ekmek isterim. Ayrca
her ne kadar rnek metotlarn tanmlarken parantez listesi iinde self kelimesini belirtsek
de, bu metotlar arrken bunlar argman olarak kullanmadmza da zellikle dikkat
etmelisiniz. Yani biz bu metotlar yle tanmlyoruz:
def saldr_sonucunu_hesapla(self):
return random.randint(0, 2)

Burada parametre listesinde self i gryoruz. Ama bu fonksiyonlar arrken parantez


iinde bu self i kullanmyoruz:
self.saldr_sonucunu_hesapla()

self i parantez iinde bir argman olarak kullanmak yerine, bu kelimeyi fonksiyon adnn
bana bir nek olarak takyoruz.
Ne diyorduk? Evet, saldr() fonksiyonu iinde darbele() adl bir fonksiyona atfta bulunduk.
Yani saldr sonucunda rakibimizi darbelediimizde ve rakibimizden darbe yediimizde
darbele() adl bir baka rnek metodunu ardk:
def darbele(self, darbelenen):
darbelenen.darbe += 1
darbelenen.enerji -= 1
if (darbelenen.darbe % 5) == 0:
darbelenen.can -= 1
if darbelenen.can < 1:
darbelenen.enerji = 0
print('Oyunu {} kazand!'.format(self.isim))
self.oyundan_k()

Bu fonksiyon iinde, herhangi bir darbe alma durumunda oyuncunun darbe, can ve enerji
miktarlarnda meydana gelecek deiiklikleri tanmlyoruz.
Buna gre herhangi bir darbe alma durumunda aadaki ilemler gerekletirilecek:
Darbelenen oyuncunun darbe deeri 1 birim artacak:
darbelenen.darbe += 1

enerji deeri 1 birim azalacak:


darbelenen.enerji -= 1

Darbelenen oyuncu her 5 darbede 1 can kaybedecek:


if (darbelenen.darbe % 5) == 0:
darbelenen.can -= 1

40.3. Basit Bir Oyun 709


Python 3 iin Trke Klavuz, Srm 3

Burada her 5 darbede 1 can kaybetme kriterini nasl belirlediimize dikkat edin. Bildiiniz
gibi, oyuncu darbe yedike darbe deikeninin deeri artyor. Bu deer 5 saysna ulatnda,
5 % 5 ileminin sonucu 0 olacaktr. Yani bu say 5e blndnde blme ileminden kalan
deer 0 olacaktr. 5in tm katlar iin (5, 10, 15, 20 gibi...) bu durum geerlidir. Eer darbe
deikenin ulat deer 5in kat deilse, bu say 5e tam blnmedii iin, blmeden kalan
deer 0 dnda bir say olur. Dolaysyla darbe deerinin ulat saynn 5e blnmesinden
kalan deerin 0 olup olmadn kontrol ederek oyuncunun 5 darbede 1 can kaybetmesini
salayabiliyoruz.
Oyuncunun can deeri 1in altna dtnde ise enerji deeri 0a inecek ve oyunu kimin
kazand ilan edildikten sonra oyun kapatlacak:
if darbelenen.can < 1:
darbelenen.enerji = 0
print('Oyunu {} kazand!'.format(self.isim))
self.oyundan_k()

Burada oyundan_k() adl bir rnek metoduna daha atfta bulunduk:


def oyundan_k(self):
print('klyor...')
sys.exit()

Gayet basit bir fonksiyon. Herhangi bir ekilde oyundan kmak gerektiinde sys modlnn
exit() fonksiyonunu kullanarak oyunu terk ediyoruz.
lerlemeden nce, darbele() fonksiyonunu kullandmz ksma tekrar bakalm:
sonu = self.saldr_sonucunu_hesapla()

if sonu == 0:
print('\nSONU: kazanan taraf yok')

if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
self.darbele(rakip)

if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
self.darbele(self)

Bildiiniz gibi, darbele() fonksiyonu, self dnda 1 adet parametre daha alyor. Bu
parametre, darbeyi hangi oyuncunun alacan gsteriyor. Yani darbeyi alan oyuncu biz
miyiz yoksa rakibimiz mi? te bunu tespit etmek iin darbelenen adl bir parametre
belirledik. Grdnz gibi, darbele() fonksiyonu saldr() adl baka bir fonksiyonun
iinden arlyor. saldr() fonksiyonu da rakip adl bir parametre alyor. te darbe alan
oyuncunun can ve enerji deerlerini yenilemek istediimizde bu parametreyi, darbele()
fonksiyonuna gnderiyoruz:
self.darbele(rakip)

Burada darbelenen oyuncu kar taraf. Yani rakibimiz darbe yemi. Eer darbelenen kii
kendimizsek, kendimize atfta bulunmak iin de self parametresini kullanyoruz:
self.darbele(self)

Pek ok kez sylediimiz gibi, self kelimesi mevcut snf rneini temsil eder. Dolaysyla

710 Blm 40. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

kendimize atfta bulunmak istediimiz durumlarda, yukarda olduu gibi self i kullanabiliriz.
Eer arzu ederseniz, darbele() fonksiyonunu yle de yazabilirsiniz:
def darbele(self):
self.darbe += 1
self.enerji -= 1
if (self.darbe % 5) == 0:
self.can -= 1
if self.can < 1:
self.enerji = 0
print('Oyunu {} kazand!'.format(self.isim))
self.oyundan_k()

Burada darbelenen parametresini iptal ettik. Kimin durumunun yenileceini self in kim
olduu belirleyecek:
if sonu == 1:
print('\nSONU: rakibinizi darbelediniz')
rakip.darbele()

if sonu == 2:
print('\nSONU: rakibinizden darbe aldnz')
self.darbele()

Grdnz gibi, eer rakibi darbeleyip onun can ve enerji durumunu yenilemek istiyorsak,
ilgili fonksiyonu rakip.darbele() eklinde aryoruz. Kendimizin durumunu yenilemek
istediimizde ise self.darbele() komutunu kullanyoruz.
Snfmz tanmladmza gre artk bu snf nasl kullanacamz incelemeye geebiliriz:
siz = Oyuncu('Ahmet')
rakip = Oyuncu('Mehmet')

Burada ncelikle Oyuncu() snf iin iki farkl nesne/rnek oluturuyoruz:


siz = Oyuncu('Ahmet')
rakip = Oyuncu('Mehmet')

Bu iki nesne, Oyuncu() snfnn btn niteliklerini tayor. Nesneleri olutururken, zorunlu
argman olan isim deerini mutlaka belirtmemiz gerektiini unutmuyoruz.
Daha sonra bir while dngs iinde, oyunumuzun kullanc tarafndan grntlenecek
ksmn kodluyoruz:
while True:
print('u anda rakibinizle kar karyasnz.',
'Yapmak istediiniz hamle: ',
'Saldr: s',
'Ka: k',
'k: q', sep='\n')

hamle = input('\n> ')


if hamle == 's':
siz.saldr(rakip)

print('Rakibinizin durumu')
rakip.mevcut_durumu_grntle()

40.3. Basit Bir Oyun 711


Python 3 iin Trke Klavuz, Srm 3

print('Sizin durumunuz')
siz.mevcut_durumu_grntle()

if hamle == 'k':
siz.ka()

if hamle == 'q':
siz.oyundan_k()

Oyunun nasl oynanaca konusunda kullanclarmz bilgilendiriyoruz:


print('u anda rakibinizle kar karyasnz.',
'Yapmak istediiniz hamle: ',
'Saldr: s',
'Ka: k',
'k: q', sep='\n')

Kullanclarmzn klavyede hangi tua bastn u ekilde alyoruz:


hamle = input('\n> ')

Eer kullanc s tuuna basarsa rakibimize saldryoruz:


if hamle == 's':
siz.saldr(rakip)

Saldrnn ardndan hem kendi durumumuzu hem de rakibimizin durumunu grntlyoruz:


print('Rakibinizin durumu')
rakip.mevcut_durumu_grntle()

print('Sizin durumunuz')
siz.mevcut_durumu_grntle()

Eer kullanc k tuuna basarsa:


if hamle == 'k':
...

...snf iinde tanmladmz ka() metodunu altryoruz:


def ka(self):
print('Kalyor...')
for i in range(10):
time.sleep(.3)
print('\n', flush=True)

print('Rakibiniz sizi yakalad')

Burada 300er milisaniyelik aralklarla \n ka dizisini kullanarak bir alt satra geiyoruz.
Kullancnn q tuuna basmas halinde ise oyundan derhal kyoruz:
if hamle == 'q':
siz.oyundan_k()

Bu rnek kodlar bize snar ve nesneler hakknda epey bilgi verdi. Ayrca bu kodlar sayesinde
nceki bilgilerimizi de pekitirmi olduk.

712 Blm 40. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

40.4 Her ey Bir Nesnedir

Belki sada solda u sz duymusunuzdur: Pythonda her ey bir nesnedir. Gerekten de (if,
def, and, or gibi deyim ve ileler hari) Pythonda her ey bir nesnedir. Peki her eyin nesne
olmas tam olarak ne anlama geliyor?
Hatrlarsanz nesnenin ne olduunu tanmlarken, belli bir durumda bulunan ve belli birtakm
davranlar olan elere nesne ad verildiini sylemitik. te Pythondaki her ey, bu tanm
dorultusunda bir nesnedir.
Mesela, aadaki komutu verdiimiz anda bir nesne oluturmu oluyoruz:
>>> 'istihza'

istihza karakter dizisi, str adl snfn...


>>> type('istihza')

<class 'str'>

...btn zelliklerini tayan bir nesnedir:


>>> dir('istihza')

['__add__', '__class__', '__contains__', '__delattr__',


'__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__getnewargs__',
'__gt__', '__hash__', '__init__', '__iter__', '__le__',
'__len__', '__lt__', '__mod__', '__mul__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__rmod__', '__rmul__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__', 'capitalize', 'casefold',
'center', 'count', 'encode', 'endswith', 'expandtabs',
'find', 'format', 'format_map', 'index', 'isalnum',
'isalpha', 'isdecimal', 'isdigit', 'isidentifier',
'islower', 'isnumeric', 'isprintable', 'isspace',
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip',
'maketrans', 'partition', 'replace', 'rfind', 'rindex',
'rjust', 'rpartition', 'rsplit', 'rstrip', 'split',
'splitlines', 'startswith', 'strip', 'swapcase',
'title', 'translate', 'upper', 'zfill']

Ayn ekilde, [elma, armut] listesi de, list adl snfn...


>>> type(['elma', 'armut'])

<class 'list'>

...btn zelliklerini tayan bir nesnedir:


>>> dir(['elma', 'armut'])

['__add__', '__class__', '__contains__', '__delattr__',


'__delitem__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__getitem__',
'__gt__', '__hash__', '__iadd__', '__imul__', '__init__',
'__iter__', '__le__', '__len__', '__lt__', '__mul__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__',

40.4. Her ey Bir Nesnedir 713


Python 3 iin Trke Klavuz, Srm 3

'__repr__', '__reversed__', '__rmul__', '__setattr__',


'__setitem__', '__sizeof__', '__str__', '__subclasshook__',
'append', 'clear', 'copy', 'count', 'extend', 'index',
'insert', 'pop', 'remove', 'reverse', 'sort']

Hatta mesela 1 gibi alelade bir say bile, d dnyayla iletiim kurmasn ve d dnyann
kendisiyle iletiim kurabilmesini salayan pek ok nitelik ve metoda sahip bir nesnedir:
>>> dir(1)

['__abs__', '__add__', '__and__', '__bool__', '__ceil__',


'__class__', '__delattr__', '__dir__', '__divmod__',
'__doc__', '__eq__', '__float__', '__floor__',
'__floordiv__', '__format__', '__ge__', '__getattribute__',
'__getnewargs__', '__gt__', '__hash__', '__index__',
'__init__', '__int__', '__invert__', '__le__', '__lshift__',
'__lt__', '__mod__', '__mul__', '__ne__', '__neg__',
'__new__', '__or__', '__pos__', '__pow__', '__radd__',
'__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__',
'__repr__', '__rfloordiv__', '__rlshift__', '__rmod__',
'__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__',
'__rshift__', '__rsub__', '__rtruediv__', '__rxor__',
'__setattr__', '__sizeof__', '__str__', '__sub__',
'__subclasshook__', '__truediv__', '__trunc__', '__xor__',
'bit_length', 'conjugate', 'denominator', 'from_bytes',
'imag', 'numerator', 'real', 'to_bytes']

te konuya bu noktadan baktmzda, Pythonda her ey bir nesnedir. Yani Pythondaki her
eyle, sahip olduklar metotlar ve nitelikler araclyla etkileebilirsiniz.
Pythonn bu zelliini bilmek, muhatap olduunuz programlama dilini ve onun kabiliyetlerini
tanmak asndan nemlidir. Pythonda her eyin bir nesne olduunu anladnz anda, {a:
0, b: 1} gibi bir kodla yalnzca basit bir szlk tanmlamadnz, bunun arkaplannda,
bu szlkle etkileim kurmanz salayacak koca bir mekanizma bulunduunu bilirsiniz.

40.5 Birinci Snf eler

Tpk her ey bir nesnedir sz gibi, yine sada solda sklkla duyabileceiniz bir sz de
Pythonda nesnelerin birinci snf eler olduudur. Peki burada birinci snf (rst class )
ifadesiyle kastedilen ey tam olarak nedir?
Programlama dillerinde herhangi bir enin birinci snf bir e olmas, o enin, dil iindeki
herhangi bir deer ile ayn kabiliyetlere sahip olmas anlamna gelir. Bunun birinci snf
olmakla ne alakas var? diye sorduunuzu duyar gibiyim...
yle bir cmle kurduunuzu dnn: Gelimi bir toplumda kadnlar birinci snf
vatandalardr. Bu cmleden, bir toplumun gelimi saylabilmesi iin kadnlarn erkeklerle
eit haklara sahip olmas gerektiini anlyoruz. Yani kadnlarn birinci snf vatandalar olmas,
erkeklerle eit haklara sahip olmas anlamna geliyor. te tpk bunun gibi, Pythondaki snf
yaplarnn birinci snf eler olmas, bu yaplarn, dil iindeki teki deerlerle ayn zelliklere
ve kabiliyetlere sahip olmas demektir. Yani Pythondaki snar u zelliklere sahiptir:
1. Baka bir fonksiyona veya snfa parametre olarak atanabilirler
2. Bir fonksiyondan dndrlebilirler

714 Blm 40. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

3. Bir deikene atanabilirler


Yani, bir enin birinci snf olmas demek, dil iindeki baka elerle yapabildiiniz her eyi
o eyle de yapabilmeniz demektir.
Durumu biraz daha netletirebilmek iin, konu hakknda Guido Van Rossumun ne dediine
bir bakalm:
Pythona ilikin hedeerimden bir tanesi de, bu dili, btn nesneler birinci snf
olacak ekilde tasarlamakt. Bununla kastettiim, dil iinde kendisine bir isim
verilebilen btn nesnelerin (rn. tam saylar, karakter dizileri, fonksiyonlar,
snar, modller, metotlar, vb.) eit statye sahip olmasdr. Yani, btn
nesnelerin deikenlere atanabilmesi, listelerin iine yerletirilebilmesi, szlkler
iinde depolanabilmesi, argman olarak atanabilmesi ve saire...
kaynak: http://python-history.blogspot.com.tr/2009/02/rst-class-everything.html
Gelin btn bu tanmlar somutlatran birka rnek verelim.
Mesela Deneme() adl basit bir snf tanmlayalm:
class Deneme():
def __init__(self):
self.deer = 0
def metot(self):
self.metot_deeri = 1

Yukardaki tanmlara gre, bu snfn birinci snf bir nesne olabilmesi iin baka bir fonksiyona
veya snfa parametre olarak atanabilmesi gerekiyor. Bakalm acaba gerekten yle mi?
print(Deneme())

Grdnz gibi, gerekten de snfmz print() fonksiyonuna parametre olarak atayabildik.


Yine yukardaki tanma gre birinci snf nesnelerin bir fonksiyondan dndrlebilmesi
gerekiyor:
def fonksiyon():
return Deneme()

print(fonksiyon())

Bu testi de baaryla getik.


Son olarak, bir nesnenin birinci snf olabilmesi iin bir deikene atanabilmesi gerekiyor:
deiken = Deneme()

Grdnz gibi, Python iin bu da olduka basit bir grev.


lk bakta bu zellikten pek etkilenmemi olabilirsiniz... yle bir dnnce, aslnda ok da
nemli bir zellik deilmi gibi gelebilir bu size. Ancak baka programlama dillerinin;
elerin kullanmna ilikin eitli kstlamalar koyduunu,
Yani eler arasnda ayrm yaptn,
Deikenlerle fonksiyonlarn ve fonksiyonlarla snarn ayn haklara sahip olmadn,
Mesela bir deikeni veya herhangi bir deeri kullanabildiiniz her yerde fonksiyon veya
snf kullanamadnz,

40.5. Birinci Snf eler 715


Python 3 iin Trke Klavuz, Srm 3

Yani fonksiyonlarn ve/veya snarn birinci snf eler olmadn


grdnzde Pythondaki bu esneklik daha bir anlam kazanacaktr.

716 Blm 40. Nesne Tabanl Programlama (Devam)


BLM 41

Nesne Tabanl Programlama (Devam)

Geen blmlerde, nesne tabanl programlamaya ilikin hem temel, hem orta, hem de ileri
dzey saylabilecek pek ok konuya deindik. imdiye kadar rendiklerimiz, nesne tabanl
programlama yaklam erevesinde yazlm retirken ynmz bulabilmemiz asndan
byk lde yeterlidir. Ancak daha nce de sylediimiz gibi, nesne tabanl programlama
ok geni kapsaml bir konudur ve iinde imdiye kadar adn bile anmadmz daha pek ok
kavram barndrr. te bu blmde, geen derslerimizde incelemeye frsat bulamadmz,
ancak nesne tabanl programlamay daha derinlemesine tanmak bakmndan bilmemizin iyi
olaca birtakm ileri dzey kavramlardan sz edeceiz.
Bu blmde inceleyeceimiz ilk konu snf yeleri.

41.1 Snf yeleri

Pythonda bir snf iinde bulunan nitelikler, deikenler, metotlar, fonksiyonlar ve buna
benzer baka veri tipleri, o snfn yelerini meydana getirir. Bir snfn yelerini genel olarak
e ayrarak inceleyebiliriz:
Aleni yeler (public members )
Gizli yeler (private members )
Yar-gizli yeler (semi-private members ).
Bu blmde bu ye trn ve bunlarn birbirinden farkn ele alacaz. ncelikle aleni
yelerden balayalm.

41.1.1 Aleni yeler

Eer bir snf yesi darya aksa, yani bu yeye snf dndan normal yntemlerle
eriilebiliyorsa bu tr yelere aleni yeler ad verilir. Programlama maceranz boyunca
karnza kacak veri yelerinin tamamna yakn alenidir. Biz de bu kitapta imdiye kadar
yalnzca aleni yeleri grdk.
Eer bildiiniz tek programlama dili Python ise, u anda tam olarak neden bahsediyor
olduumuza anlam verememi olabilirsiniz. Dilerseniz durumu zihninizde biraz olsun
netletirebilmek iin basit bir rnek verelim.
Diyelim ki elimizde yle bir snf var:

717
Python 3 iin Trke Klavuz, Srm 3

class Snf():
snf_nitelii = 'snf nitelii'

def rnek_metodu(self):
print('rnek metodu')

@classmethod
def snf_metodu(cls):
print('snf metodu')

@staticmethod
def statik_metot():
print('statik metot')

Bu kodlarn sinif.py adl bir dosya iinde yer aldn varsayarsak yle bir eyler yazabiliriz:
>>> import sinif
>>> s = sinif.Snf()
>>> dir(s)

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',


'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__module__',
'__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'statik_metot', 'snf_metodu', 'snf_nitelii', 'rnek_metodu']

Burada ncelikle kodlarmz barndran modl ie aktardk. Daha sonra, ie aktardmz


modln iindeki Snf() adl snfmz s rneine atadk ve ardndan dir() komutunu
kullanarak, ie aktardmz bu snfn ieriini sorguladk.
Grdnz gibi, ie aktardmz snfn btn eleri listede var. Yani biz bu snf iindeki
btn elere normal yollardan erime imkanna sahibiz:
>>> s.statik_metot()

'statik metot'

>>> s.rnek_metodu()

'rnek metodu'

>>> s.snf_metodu()

'snf metodu'

>>> s.snf_nitelii

'snf nitelii'

te dir() komutunun ktsnda grnen ve normal yollardan eriebildiimiz btn bu eler


birer aleni yedir.
Yukarda da ifade ettiimiz gibi, program yazarken ou zaman yalnzca aleni yelerle
muhatap olacaksnz. Ancak baz durumlarda, yazdnz bir snftaki btn snf yelerinin
darya ak olmasn istemeyebilirsiniz. Eer kodlarnzda, snfn yalnzca i ileyiini
ilgilendiren, bu yzden de dardan eriilmesine gerek olmadn veya eriilirse problem

718 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

kacan dndnz birtakm eler varsa bunlar darya kapatarak bir gizli ye haline
getirmek isteyebilirsiniz. Peki ama nasl?

41.1.2 Gizli yeler

Pythonda imdiye kadar grdmz ve yukarda andmz aleni yelerin dnda, bir de gizli
yeler bulunur. Aleni yelerin aksine gizli yeler darya ak deildir. Gizli yelere, normal
yntemleri kullanarak snf dndan eriemeyiz.
Konuyu akla kavuturmak iin, aleni yeleri anlatrken verdiimiz snf rneinde u
deiiklii yapalm:
class Snf():
__gizli = 'gizli'

def rnek_metodu(self):
print(self.__gizli)
print('rnek metodu')

@classmethod
def snf_metodu(cls):
print('snf metodu')

@staticmethod
def statik_metot():
print('statik metot')

Burada __gizli adl bir gizli snf nitelii tanmladk. Bu deikenin yalnzca ba tarafnda iki
adet alt izgi olduuna, ancak u tarafnda alt izgi bulunmadna dikkat edin. te Pythonda
ba tarafnda yukardaki gibi iki adet alt izgi olan, ancak u tarafnda alt izgi bulunmayan
(veya yalnzca tek bir alt izgi bulunan) btn eler birer gizli yedir. Darya kapal olan bu
gizli yelere, normal yntemleri kullanarak snf dndan eriemezsiniz.
sterseniz deneyelim:
>>> import sinif
>>> s = sinif.Snf()
>>> s.__gizli

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'Snf' object has no attribute '__gizli'

Grdnz gibi, rnek ad zerinden __gizli niteliine eriemiyoruz. Bir de snf ad


zerinden erimeyi deneyelim:
>>> sinif.Snf.__gizli

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: type object 'Snf' has no attribute '__gizli'

Bu ekilde de eriemedik. nk dediimiz gibi, banda ift alt izgi olan, ancak ucunda
herhangi bir izgi bulunmayan (veya tek bir alt izgi bulunan) bu gizli elere normal
yollardan eriemeyiz.
Dilerseniz gizli ye oluturma kurallarn yle bir netletirelim:

41.1. Snf yeleri 719


Python 3 iin Trke Klavuz, Srm 3

Bir yenin gizli olabilmesi iin banda en az iki adet, ucunda da en fazla bir adet alt izgi
bulunmaldr. Yani unlar birer gizli yedir:
>>> __gizli = 'gizli'
>>> __gizli_ = 'gizli'
>>> __gizli_ye = 'gizli'
>>> __gizli_ye_ = 'gizli'

Burada nemli bir noktaya dikkatinizi ekmek istiyorum: Gizli yeler yalnzca snf dna
kapaldr. Bu yelere snf iinden rahatlkla eriebiliriz. Mesela yukardaki rnekte bu
durumu gryorsunuz. __gizli adl deikene rnek_metodu() iinden normal bir ekilde
eriebiliyoruz:
def rnek_metodu(self):
print(self.__gizli)
print('rnek metodu')

Bu durumda snf dndan bu rnek_metodu()na eritiimizde gizli ye olan __gizli ye de


erimi oluyoruz:
>>> import sinif
>>> s = sinif.Snf()
>>> s.rnek_metodu()

'gizli'
'rnek metodu'

Burada rnek_metodu(), __gizli adl gizli yeye erimemiz iin bize araclk etmi oluyor.
Peki ama bir insan neden bu ekilde birtakm gizli yeler tanmlamak istiyor olabilir?
Hatrlarsanz geen blmde yle bir rnek vermitik:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

@classmethod
def personel_saysn_grntle(cls):
print(len(cls.personel))

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):

720 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

print('{} adl kiinin kabiliyetleri:'.format(self.isim))


for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Burada personel adl bir snf niteliimiz var. Bu nitelie snf iinde hem
personele_ekle() adl rnek metodundan hem de personel_saysn_grntle() ve
personeli_grntle() adl snf metotlarndan erimek suretiyle bu nitelik zerinde eitli
ilemler yapyoruz.
Esasnda yle bir dnnce, personel adl niteliin yalnzca snfn i ileyii asndan nem
tadn rahatlkla syleyebiliriz. Bu nitelie snf dndan dorudan eriilerek personel
zerinde ilem yaplmaya allmas ok mantksz. Yani snfmz kullanacak kiilerin u tr
bir kod yazmas biraz abes kaacaktr:
>>> from calisan import alan
>>> alan.personel.append('Ahmet')

Zira biz, kodlarmzn yaps gerei, personel zerindeki ilemlerin yalnzca eitli
fonksiyonlar/metotlar araclyla yaplmasn istiyoruz.
Personele eleman ekleyecek kiilerin dorudan personel listesine erimesi, kodlarmzn
kullanm kurallarnn bir bakma ihlal edilmesi anlamna geliyor. nk biz personele eleman
ekleme ilemleri iin halihazrda ayr bir metot tanmlam durumdayz. Eer personele
adam eklenecekse, bu ilem dorudan personel listesi zerinden deil, personele_ekle()
adl rnek metodu zerinden gerekletirilmeli. Yukardaki kodlarda bu personele_ekle()
metodu dorudan snfn kendi __init__() metodu tarafndan kullanlyor. Dolaysyla
yukardaki snf kullanmann doru yolu, ilgili snf rneklemektir:
>>> from calisan import alan
>>> ahmet = alan('Ahmet')

Ayn ekilde personel listesini grntlemek iin de dorudan personel listesine erimeye
almayacaz. Yani yle bir ey yazmayacaz:
>>> alan.personel

Bunun yerine, bu i iin zel olarak tasarladmz personeli_grntle() fonksiyonunu


kullanacaz:
>>> alan.personeli_grntle()

te yukardaki kodlarda yer alan personel listesinin usulsz bir ekilde kullanlmasn
nlemek amacyla bu listeyi bir gizli ye haline getirebilirsiniz:
class alan():
__personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.personele_ekle()

@classmethod
def personel_saysn_grntle(cls):
print(len(cls.__personel))

def personele_ekle(self):

41.1. Snf yeleri 721


Python 3 iin Trke Klavuz, Srm 3

self.__personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

def personeli_grntle(self):
print('Personel listesi:')
for kii in self.__personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Burada personel listesinin ba tarafna iki alt izgi ekleyerek bunu snf dndan, normal
yollarla eriilmez hale getirdik:
>>> alan.__personel

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: type object 'alan' has no attribute '__personel'

Grdnz gibi, aslnda snfmz iinde __personel adl bir nitelik olmasna ramen, Python
bu nitelie snf dndan eriilmesine izin vermiyor. Eer amacmz personel zerinde eitli
ilemler yapmaksa, bu i iin snfn bize sunduu metotlar kullanmamz gerekiyor:
>>> alan.personel_saysn_grntle()

Bu tip durumlarda gizli yeler epey iinize yarayabilir...


Bir rnek daha verelim.
Yukardaki kodlarda, tpk personel listesi gibi, aslnda personele_ekle() fonksiyonu da
dardan eriilmesine gerek olmayan, hatta dardan eriilirse kafa kartrc olabilecek bir
snf yesidir.
personele_ekle() adl rnek metodu, snfmz iinde __init__() fonksiyonu tarafndan
kullanlyor. Dolaysyla snfmz rneklendiinde personele_ekle() metodu devreye girerek
yeni eleman personel listesine ekliyor:
>>> aye = alan('Aye')

'Aye adl kii personele eklendi'

te yandan, bu fonksiyon aleni bir ye olduu iin, buna dardan erimemizin nnde
herhangi bir engel yok:
>>> aye.personele_ekle()

'Aye adl kii personele eklendi'

Bu fonksiyon snf dndan arldnda, kendisini aran rnek adn personel listesine
tekrar ekleyecektir:

722 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

>>> alan.personeli_grntle()

Aye
Aye

Yani yukardaki komut Aye adl kiiyi personel listesine tekrar ekler. Dolaysyla bu
fonksiyona snf dndan eriilmesi son derece mantksz, son derece yanl ve hatta son
derece kafa kartrcdr. O yzden, herhangi bir sknt yaanmasn engellemek amacyla
bu fonksiyonu da bir gizli ye olarak tanmlayabiliriz:
class alan():
__personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.__personele_ekle()

@classmethod
def personel_saysn_grntle(cls):
print(len(cls.__personel))

def __personele_ekle(self):
self.__personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.__personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Bu ekilde personele_ekle() fonksiyonunu da darya kapatm olduk. Artk bu fonksiyon


da, olmas gerektii gibi, yalnzca snf iinde kullanlabilecek.
Yukardaki rnekler, baz durumlarda veri gizlemenin epey iimize yarayabileceini bariz
bir biimde gsteriyor. Ama elbette, yukardaki ilemlerin hibiri zorunlu deildir. Yani
siz, yazdnz kodlarda hibir snf yesini gizlemek mecburiyetinde deilsiniz. Yukarda
gsterdiimiz kullanmlar tamamen tercih meselesidir. Zaten birka nadir durum dnda,
Pythonda verilerinizi gizlemek zorunda da kalmazsnz. Ama tabii kendiniz Pythonn bu
zelliinden yararlanmasanz da, srf bu zellikten yararlanan baka programclarn yazd
kodlar anlayabilmek iin bile olsa bu zellikten haberdar olmalsnz.

41.1.3 sim Bulandrma

Gelin isterseniz gizli yelere ilikin ilgin bir zellikten sz edelim.


Pythonda gizli olarak adlandrdmz eler aslnda o kadar da gizli deildir... nk

41.1. Snf yeleri 723


Python 3 iin Trke Klavuz, Srm 3

Pythonda gerek anlamda gizli ve darya tamamen kapal yeler bulunmaz. Peki bu ne
anlama geliyor?
Bu u anlama geliyor: Her ne kadar yukardaki rneklerde yeleri darya kapatmak iin
kullandmz alt izgi iaretleri ilgili deikeni gizlese de, bunu tamamen eriilmez hale
getirmez. Dediimiz gibi, Pythonda gerek anlamda da kapal snf yeleri bulunmad iin
biz bu yelere bir ekilde erime imkanna sahibiz. Peki ama nasl?
Python, kodlar iinde gizli bir ye ile karlatnda zel bir isim bulandrma (name
mangling ) ilemi gerekletirir ve ilgili gizli yenin grnn deitirir. Eer Pythonn
arkaplanda neler evirdiini bilirseniz, gizli yeye de eriebilirsiniz.
rnek snfmz yleydi:
class Snf():
__gizli = 'gizli'

def rnek_metodu(self):
print(self.__gizli)
print('rnek metodu')

@classmethod
def snf_metodu(cls):
print('snf metodu')

@staticmethod
def statik_metot():
print('statik metot')

imdi, bu snf iindeki gizli yeye erieceiz.


Dikkatlice bakn:
>>> import sinif
>>> s = sinif.Snf()
>>> s._Snf__gizli

'gizli'

Ne kadar da tuhaf, deil mi?


te Python, siz bir snf yesini __gizli eklinde tanmladnzda, bu e zerinde u ilemleri
gerekletirir:
ncelikle deikenin ba tarafna bir alt izgi ekler:
_

Daha sonra, bu alt izginin sa tarafna bu gizli yeyi barndran snfn adn ilitirir:
_Snf

Son olarak da gizli yeyi snf adnn sa tarafna yaptrr:


_Snf__gizli

Dolaysyla _Snf__gizli kodunu kullanarak, __gizli adl yeye snf dndan eriebilirsiniz.
Pratik olmas bakmndan bir rnek daha verelim. Mesela u rnei ele alalm:

724 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

class alan():
__personel = []

def __init__(self, isim):


self.isim = isim
self.kabiliyetleri = []
self.__personele_ekle()

@classmethod
def personel_saysn_grntle(cls):
print(len(cls.__personel))

def __personele_ekle(self):
self.__personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.__personel:
print(kii)

def kabiliyet_ekle(self, kabiliyet):


self.kabiliyetleri.append(kabiliyet)

def kabiliyetleri_grntle(self):
print('{} adl kiinin kabiliyetleri:'.format(self.isim))
for kabiliyet in self.kabiliyetleri:
print(kabiliyet)

Burada __personele_ekle() adl fonksiyon bir gizli yedir. Dolaysyla buna dardan normal
yntemlerle eriemeyiz.
Bunu test etmek iin nce gerekli verileri oluturalm:
>>> from calisan import alan
>>> ahmet = alan('Ahmet')

Ahmet adl kii personele eklendi.

imdi ahmet rnei zerinden bu gizli yeye erimeye alalm:


>>> ahmet.__personele_ekle()

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'alan' object has no attribute '__personele_ekle'

Grdnz gibi, Python bu yeye normal yollardan erimemize izin vermiyor. Ama biz
biliyoruz ki, Python bu yeyi gizlerken zel bir isim bulandrma ilemi gerekletiriyor. Bu
bulandrma ileminin nasl gerekletirildiini bildiimize gre gizli yeye eriebiliriz.
ncelikle rneimizin adn yazalm. Zira gizli yeye bu ad zerinden erieceiz:
>>> ahmet.

imdi bulandrma ilemini uygulamaya geebiliriz.


ncelikle bir alt izgi ekleyelim:

41.1. Snf yeleri 725


Python 3 iin Trke Klavuz, Srm 3

>>> ahmet._

Daha sonra snf adn ilitirelim:


>>> ahmet._alan

Son olarak da gizli yenin kendisini yazalm:


>>> ahmet._alan__personele_ekle()

Ahmet adl kii personele eklendi.

Gayet baarl...
Yalnz buraya yle bir not delim: Her ne kadar Python bize gizli yelere erime
imkan sunsa da, bakasnn yazd kodlar kullanrken, o kodlardaki gizli yelere erimeye
almamak ou zaman iyi bir kirdir. Nihayetinde eer bir programc, bir snf yesini
gizlemise bunun bir nedeni vardr. Eer erimenizin istenmedii bir yeye eriirseniz
ve bunun sonucunda birtakm sorunlarla karlarsanz bu durum o program yazan
programcnn deil, tamamen sizin kabahatinizdir. Python programclarnn da sk sk
syledii gibi: Neticede hepimiz, doruyu yanl bilen, yetikin insanlarz.

41.1.4 Yar-gizli yeler

Buraya kadar Pythona dair anlattmz eylerden, yerlemi adetlerin ve geleneklerin Python
asndan ne kadar nemli olduunu anlam olmalsnz. Daha nce verdiimiz rnekler, bu
dildeki pek ok meselenin uzlama esas zerinden zme kavuturulduunu bize ak ve
seik olarak gsterdi. Mesela geen blmlerde ele aldmz self ve cls kelimeleri tamamen
uzlamaya dayal kavramlardr. Python topluluu iinde, self kelimesinin rnek metotlar
iin, cls kelimesinin ise snf metotlar iin kullanlmas tamamen bir alkanlk, adet, gelenek
ve uzla meselesidir. Pythonn kendisi bize bu kelimeleri dayatmaz. Ancak topluluk iinde
sregelen kuvvetli gelenekler bizi baka kelimeleri deil de yukardaki kelimeleri kullanmaya
tevik eder. Ayn ekilde kod yazarken girinti saysnn drt boluk olarak belirlenmi olmas
da bir gelenekten ibarettir. Yazdnz kodlarda, ayn program iinde hep ayn sayda olmak
artyla, istediiniz sayda boluktan oluan girintiler kullanabilirsiniz. Ama Pythonn topluluk
ii gelenekleri bizi drt bolukluk bir girintileme sistemi kullanmaya yneltir.
te tpk yukardakiler gibi, Pythondaki snf yelerinin da ak veya da kapal olup
olmamas da hep belli birtakm gelenekler zerinden belirlenen bir durumdur.
Bunun bir rneini, yukarda gizli yeleri anlatrken vermitik. Bir snf iindeki herhangi bir
niteliin banda ift alt izgi grdmzde, o snf yazan kiinin, bu nitelie snf dndan
eriilmesini istemediini anlyoruz. Python her ne kadar nitelikleri gizlememiz iin bize zel
bir mekanizma sunmu olsa da bu nitelie erimemizi tamamen engellemiyor, ancak ilgili
snf yazan kiinin niyetine sayg gstereceimizi varsayyor.
Pythonda snf yelerinin gizlilii, yukarda da grdmz gibi, hem zel bir mekanizma ile
hem de topluluk ii gelenekler tarafndan korunur.
Pythonda bir de yalnzca topluluk ii gelenekler tarafndan korunan yar-gizli yeler
(semi-private members ) vardr. te bu blmde, bir gizli ye tr olan yar-gizli yelerden
sz edeceiz.
Yar-gizli yeler, herhangi bir zel mekanizma araclyla deil de yalnzca topluluk ii
gelenekler tarafndan korunan niteliklerdir. Herhangi bir yeyi yar-gizli olarak iaretlemek

726 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

iin yapmamz gereken tek ey bana bir adet alt izgi yerletirmektir. rnein:
class Falanca():
_yargizli = 'yargizli'

Buradaki _yargizli adl nitelie snf iinden veya dndan erimemizi engelleyen veya
zorlatran hibir mekanizma bulunmaz. Ama biz bir snf iinde tek alt izgi ile balayan
bir e grdmzde, bunun snfn i ileyiine ilikin bir ayrnt olduunu, snf dndan
bu eyi deitirmeye kalkmamamz gerektiini anlarz.

41.2 @property Bezeyicisi

Yukarda aleni, gizli ve yar-gizli snf yelerinden sz ettik. sterseniz zellikle yar-gizli
elerin kullanld bir kod rnei vererek yukarda anlattklarmz somut bir rnek
zerinden netletirmeye alalm.
Diyelim ki yle bir kod yazdk:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.personele_ekle()

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.personel:
print(kii)

Burada personel veritabanna kii eklememizi ve veritabanndaki kiileri grntlememizi


salayan birtakm metotlar var.
Bu metotlar yle kullanyoruz:
>>> from calisan import alan
>>> 1 = alan('Ahmet')

Ahmet adl kii personele eklendi

>>> 2 = alan('Mehmet')

Mehmet adl kii personele eklendi

>>> alan.personeli_grntle()

Personel listesi:
Ahmet
Mehmet

41.2. @property Bezeyicisi 727


Python 3 iin Trke Klavuz, Srm 3

Peki eer kodlarmz kullananlar personel listesindeki bir kiinin ismini sonradan deitirmek
isterse ne yapacak?
Kodlarmz iinde, isim deiiklii yaplmasn salayan zel bir metot yok. Dolaysyla
kodlarmz kullananlar, dorudan isim adl rnek deikenine erierek isim deiikliini u
ekilde yapabilir:
>>> 1.isim = 'Selim'

Bu ekilde Ahmet adl kiinin ismini deitirdik. Bunu teyit edelim:


>>> print(1.isim)

Selim

Ancak burada yle bir sorun var. Bu isim deiiklii personel listesine yansmad. Kontrol
edelim:
>>> alan.personeli_grntle()

Personel listesi:
Ahmet
Mehmet

Grdnz gibi, Ahmet ismi hl orada duruyor. Bu sorunu gidermek iin, personel
listesine de mdahale edilmesi gerekir:
>>> kii = alan.personel.index('Ahmet')
>>> alan.personel[kii] = 'Selim'

Burada ncelikle listelerin index() metodunu kullanarak, deitirmek istediimiz kiinin


personel listesindeki srasn bulduk. Daha sonra da bu bilgiyi kullanarak listede gerekli
deiiklii yaptk.
Personel listesini tekrar kontrol ettiimizde her eyin yolunda olduunu grebiliriz:
>>> alan.personeli_grntle()

Personel listesi:
Selim
Mehmet

Ancak bunun hi kullanl bir yntem olmad ok ak. Basit bir isim deiiklii
iin, kullanclarmz bir sr kod yazmak zorunda kalyor. Kullanclarmzn hayatn
kolaylatrmak iin onlara pratik bir metot sunabiliriz:
class alan():
personel = []

def __init__(self, isim):


self.isim = isim
self.personele_ekle()

def personele_ekle(self):
self.personel.append(self.isim)
print('{} adl kii personele eklendi'.format(self.isim))

@classmethod
def personeli_grntle(cls):

728 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

print('Personel listesi:')
for kii in cls.personel:
print(kii)

def isim_deitir(self, yeni_isim):


kii = self.personel.index(self.isim)
self.personel[kii] = yeni_isim
print('yeni isim:', yeni_isim)

Burada isim_deitir() adl yeni bir fonksiyon tanmladk. Artk kodlarmzdan istifade
edenler yalnzca bu yeni fonksiyonu kullanarak, personele nceden ekledikleri kiilerin ismini
kolayca deitirebilir:
>>> from calisan import alan
>>> 1 = alan('Ahmet')
>>> 2 = alan('Mehmet')
>>> 3 = alan('Selim')
>>> alan.personeli_grntle()

Personel listesi:
Ahmet
Mehmet
Selim

>>> 1.isim_deitir('Emre')

yeni isim: Emre

>>> alan.personeli_grntle()

Personel listesi:

Emre
Mehmet
Selim

Grdnz gibi, kodlarmz gayet gzel alyor. Bu noktadan sonra, eer arzu ederseniz,
kullanclarnzn personel ve self.isim adl deikenlere dorudan erimesini engellemek iin
bunlar tek alt izgi veya ift alt izgi kullanarak gizleyebilirsiniz.
ift alt izgi ile:
class alan():
__personel = []

def __init__(self, isim):


self.__isim = isim
self.personele_ekle()

def personele_ekle(self):
self.__personel.append(self.__isim)
print('{} adl kii personele eklendi'.format(self.__isim))

@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls.__personel:
print(kii)

41.2. @property Bezeyicisi 729


Python 3 iin Trke Klavuz, Srm 3

def isim_deitir(self, yeni_isim):


kii = self.__personel.index(self.__isim)
self.__personel[kii] = yeni_isim
print('yeni isim: ', yeni_isim)

Tek alt izgi ile:


class alan():
_personel = []

def __init__(self, isim):


self._isim = isim
self.personele_ekle()

def personele_ekle(self):
self._personel.append(self._isim)
print('{} adl kii personele eklendi'.format(self._isim))

@classmethod
def personeli_grntle(cls):
print('Personel listesi:')
for kii in cls._personel:
print(kii)

def isim_deitir(self, yeni_isim):


kii = self._personel.index(self._isim)
self._personel[kii] = yeni_isim
print('yeni isim: ', yeni_isim)

personel ve self.isim adl nitelikleri ift alt izgi ile gizlediimizde Pythonn isim
bulandrma mekanizmasn ileteceini, tek alt izgi ile gizlediimizde ise bu mekanizmann
iletilmeyeceini biliyorsunuz.
Peki size yle bir soru soraym:
Acaba, personel listesindeki bir ismi, mesela yalnzca yle bir komut vererek deitiremez
miyiz?
>>> 1.isim = 'Emre'

Elbette deitirebiliriz. Ancak bunun iin zel bir aratan yararlanmamz gerekir. Bu i iin
@property adl zel bir bezeyiciyi kullanacaz.
Dikkatlice bakn:
class alan():
_personel = []

def __init__(self, isim):


self._isim = isim
self.personele_ekle()

def personele_ekle(self):
self._personel.append(self._isim)
print('{} adl kii personele eklendi'.format(self._isim))

@classmethod
def personeli_grntle(cls):

730 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

print('Personel listesi:')
for kii in cls._personel:
print(kii)

@property
def isim(self):
return self._isim

@isim.setter
def isim(self, yeni_isim):
kii = self._personel.index(self.isim)
self._personel[kii] = yeni_isim
print('yeni isim: ', yeni_isim)

Bu kodlar altrdnzda, tpk yukarda bahsettiimiz gibi, herhangi bir alann ismini
yalnzca u ekilde deitirebildiinizi greceksiniz:
>>> 1.isim = 'Emre'

stelik bu kod, isim deiikliinin personel listesine de yansmasn salyor:


>>> alan.personeli_grntle()

Emre

Birazdan bu kodlar derinlemesine inceleyeceiz. Ama isterseniz ncelikle u @property


bezeyicisinden biraz sz edelim. Bylelikle yukardaki kodlar anlamamz kolaylar.

41.2.1 Metottan Nitelie

imdiye kadar verdiimiz rneklerden anlam olabileceiniz gibi, bir snf iinde salt verileri
tutan deikenlere nitelik ad veriyoruz. Mesela:
class Falanca():
nitelik = 'nitelik'

def __init__(self):
self.nitelik = 'nitelik'

Burada nitelik bir snf nitelii, self.nitelik ise bir rnek niteliidir.
Buna karlk, bir snf iinde fonksiyon biiminde yer alan ve bir ilemi veya prosedr yerine
getiren elere ise metot ad veriyoruz. Mesela:
class Falanca():
def __init__(self):
pass

def rnek_fonk(self):
pass

@classmethod
def snf_fonk(cls):
pass

@staticmethod

41.2. @property Bezeyicisi 731


Python 3 iin Trke Klavuz, Srm 3

def statik_fonk():
pass

Burada rnek_fonk() adl fonksiyon bir rnek metodu, snf_fonk() adl fonksiyon bir
snf metodu, statik_fonk() adl fonksiyon ise bir statik metottur. Metotlar ile niteliklerin
gerekletirebilecekleri ilemlerin karmaklnn birbirinden farkl olmasnn yansra, bunlar
arasnda kullanm asndan da farkllk vardr. Mesela Falanca() snf iindeki nitelik adl
snf niteliini u ekilde kullanyoruz:
>>> Falanca.nitelik
>>> Falanca.nitelik = 'yeni deer'

Ayn snf iindeki snf_fonk() adl snf metoduna ise yle eriiyoruz:
>>> Falanca.snf_fonk()

Niteliklerin aksine, metotlarda atama yoluyla deer deitirme gibi bir ey sz konusu
deildir. Yani una benzer bir ey yazamayz:
>>> Falanca.snf_fonk() = 'yeni deer'

Eer metot bir parametre alyorsa (yukardaki rneklerde metotlar parametre almyor), bu
parametreyi kullanarak metotla iletiim kurabiliriz. Mesela:
>>> Falanca.snf_fonk(yeni_deer)

Property kelimesi (attribute kelimesine benzer bir ekilde) ngilizcede zellik, nitelik gibi
anlamlara gelir. Kelime anlamna uygun olarak, @property bezeyicisinin yapt en temel
i, bir metodu, nitelik gibi kullanlabilecek hale getirmektir. ok basit bir rnek verelim:
class Program():
def __init__(self):
pass

def versiyon(self):
return '0.1'

Burada versiyon() adl bir rnek metodu tanmladk. Bu program yle kullanyoruz:
>>> program = Program()
>>> program.versiyon()

'0.1'

imdi programmzda u deiiklii yapalm:


class Program():
def __init__(self):
pass

@property
def versiyon(self):
return '0.1'

Burada versiyon() adl metodu @property bezeyicisi ile bezedik. Bylece bu metodu bir
nitelik haline getirmi olduk. Artk bunu yle kullanabiliriz:

732 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

>>> program = Program()


>>> program.versiyon

'0.1'

versiyon() fonksiyonunu, @property bezeyicisi yardmyla bir nitelie dntrdmz


iin, artk bu fonksiyonu parantezsiz kullandmza dikkat edin.
Grdnz gibi, @property bezeyicisinin ilk grevi bir metodu nitelie dntrmek. Peki
acaba neden bir metodu nitelie dntrmek istiyor olabiliriz?
yle bir program yazdnz dnn:
class Program():
def __init__(self):
self.data = 0

Yazdnz bu program kullananlar, snf iindeki data niteliine u ekilde eriiyor:


>>> p = Program()
>>> p.data

Hatta duruma gre bu nitelii u ekilde deiiklie de uratyor:


>>> p.data = 1

Gnn birinde, data kelimesi yerine veri kelimesinin daha uygun olduunu dnerek,
data kelimesini veri olarak deitirmek istediinizi varsayalm. Bunun iin kodlarnzda u
deiiklii yapabilirsiniz:
class Program():
def __init__(self):
self.veri = 0

Ancak bu ekilde, programnz eskiden beri kullananlarn, sizin yazdnz bu program temel
alarak oluturduklar programlar bozmu oldunuz... nk eer bu programdan faydalanan
birisi, yazd kodda eski self.data deikenini kullanmsa, yukardaki isim deiiklii
yznden program kullanlamaz hale gelecektir. te bunu nlemek iin @property
bezeyicisini kullanabilirsiniz.
Dikkatlice bakn:
class Program():
def __init__(self):
self.veri = 0

@property
def data(self):
return self.veri

Bu ekilde, self.data niteliine yaplan btn arlar data() adl metot vastasyla self.veri
niteliine ynlendirilecek. Bylece bakalarnn bu program kullanarak yazd eski kodlar
bozmadan, programmzda istediimiz deiiklii yapm olduk. Yani programmzda geriye
dnk uyumluluu (backwards compatibility ) salam olduk.
Yukardaki kodlarda @property bezeyicisini kullanarak data() metodunu bir nitelie
dntrdmz iin artk yle bir kullanm mmkn:

41.2. @property Bezeyicisi 733


Python 3 iin Trke Klavuz, Srm 3

>>> p = Program()
>>> p.data

>>> p.veri

Bu yapda, self.veri zerindeki deiiklikler self.data niteliine de yansyacaktr:


>>> p.veri = 5
>>> p.data

41.2.2 Salt Okunur Nitelikler

@property bezeyicisinin bir baka kabiliyeti de salt okunur nitelikler oluturabilmesidir.


Mesela yukardaki program temel alarak yle bir ey deneyelim:
>>> p = Program()
>>> p.data = 5

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: can't set attribute

Grdnz gibi, data nitelii zerinde deiiklik yapamyoruz. Dolaysyla, kodlarnz


kullananlarn deitirmesini istemediiniz, salt okunur nitelikler oluturmak iin @property
bezeyicisinden yararlanabilirsiniz.

41.2.3 Veri Dorulamas

@property bezeyicisinin nemli ilevi bulunur:


Deer dndrmek
Deer atamak
Deer silmek
Yukardaki rneklerde bu bezeyicinin deer dndrme ilevini grmtk. imdi ise bu
bezeyicinin deer atama ilevini anlamaya alalm.
Bildiiniz gibi, @property bezeyicisinin deer dndrme ilevini kullanarak, bir nitelie
eriimi kstlayabiliyoruz. rnein, zamannda yle bir kod yazdmz varsayalm:
class Program():
def __init__(self):
self.say = 0

Daha sonra herhangi bir sebepten tr buradaki self.say niteliine eriimi kstlayp
bu nitelii zerinde deiiklik yaplamaz hale getirmek istersek @property bezeyicisinden
yararlanabiliriz:

734 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

class Program():
def __init__(self):
self._say = 0

@property
def say(self):
return self._say

Grdnz gibi, ncelikle self.say adl nitelii, bana bir alt izgi getirerek normal eriime
kapatmak istediimizi belirttik. Bu kodlar grenler, say niteliinin yar-gizli bir ye olduunu
anlayp ona gre davranacak. Ayrca biraz sonra tanmlayacamz say() fonksiyonuyla
bu deikenin adnn birbirine karmamas iin de bir nlem alm olacaz. Pythonda bir
deikenin adn deitirmeden o deikene eriimi kontrol altna almak istediimizde tek alt
izgi kullanmak tercih edilen bir yntemdir.
Daha sonra da say() fonksiyonumuzu tanmlyoruz:
@property
def say(self):
return self._say

Bu say() fonksiyonunu @property ile bezediimiz iin, fonksiyon bir nitelie dnt ve
say deikenini salt okunur hale getirdi. Eer amacnz deikeni salt okunur hale getirmek
deilse @property ile bezediimiz fonksiyon iin bir setter parametresi tanmlayabilirsiniz.
Nasl m? Dikkatlice inceleyin:
class Program():
def __init__(self):
self._say = 0

@property
def say(self):
return self._say

@say.setter
def say(self, yeni_deer):
self._say = yeni_deer
return self._say

@property ile bezeyerek bir nitelik haline getirdiiniz fonksiyonu yazlabilir hale getirmek ve
bu yazma ileminin nasl olacan belirlemek iin zel bir .setter bezeyicisi ile bezenmi yeni
bir fonksiyon tanmlayabilirsiniz.
Biz yukarda, yine say adn tayan, .setter ile bezenmi bir fonksiyon daha tanmladk:
@say.setter
def say(self, yeni_deer):
self._say = yeni_deer
return self._say

Yukardaki kodlar altrdmzda, _say deikenine say ad ile normal bir ekilde eriip
istediimiz deiiklii yapabiliyoruz:
>>> p = Program()
>>> p.say

41.2. @property Bezeyicisi 735


Python 3 iin Trke Klavuz, Srm 3

>>> p.say = 5
>>> p.say

Grdnz gibi, artk say deikeni, kendisi iin bir .setter bezeyicisi tanmlam olmamz
sayesinde deiiklik kabul ediyor.
.setter bezeyicisini, bir nitelii yazlabilir hale getirmenin yansra, dorulama ilemleri iin de
kullanabilirsiniz.
Basit bir rnek verelim:
class Program():
def __init__(self):
self._say = 0

@property
def say(self):
return self._say

@say.setter
def say(self, yeni_deer):
if yeni_deer % 2 == 0:
self._say = yeni_deer
else:
print('ift deil!')

return self.say

Burada, self.say niteliinin deerini ift saylarla snrlandrdk. Veri dorulama/kstlama


ilemini .setter bezeyicisi iinden gerekletirdiimize dikkatinizi ekmek isterim. Buna gre,
eer self.say deikenine girilen deer bir ift say ise bu deiiklii kabul ediyoruz. Aksi
halde ift deil! uyars gsteriyoruz:
>>> p = Program()
>>> p.say = 2
>>> p.say = 5

'ift deil!'

Bu arada, .setter dnda .deleter adl zel bir @property bezeyicisi daha bulunur. Bunu da
bir deeri silmek iin kullanyoruz:
class Program():
def __init__(self):
self._say = 0

@property
def say(self):
return self._say

@say.setter
def say(self, yeni_deer):
if yeni_deer % 2 == 0:
self._say = yeni_deer
else:

736 Blm 41. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

print('ift deil!')

return self.say

@say.deleter
def say(self):
del self._say

Grdnz gibi, @property bezeyicisini kullanrken ayr metot tanmlyoruz:


lgili nitelie nasl ulaacamz gsteren bir metot: Bu metodu @property ile
beziyoruz.
lgili nitelii nasl ayarlayacamz gsteren bir metot: Bu metodu @metot_ad.setter
eklinde beziyoruz.
lgili nitelii nasl sileceimizi gsteren bir metot: Bu metodu @metot_ad.deleter
eklinde beziyoruz.
Bu blmde nesne tabanl programlamann orta-ileri dzey saylabilecek ynlerine temas
ettik. Artk nesne tabanl programlamann temellerinden biraz daha fazlasn bildiinizi
rahatlkla iddia edebilirsiniz.

41.2. @property Bezeyicisi 737


BLM 42

Nesne Tabanl Programlama (Devam)

Nesne tabanl programlamaya giri yaparken, bu programlama yaklamnn olduka geni


kapsaml bir konu olduunu sylemitik. Bu blmde de bu geni kapsaml konunun ileri
dzey ynlerini ele almaya devam edeceiz.
Ayrca bu blm bitirdikten sonra, nesne tabanl programlamann youn bir ekilde
kullanld grak arayz tasarlama konusundan da sz edebileceiz. Bylece, bu zamana
kadar grdmz komut satr uygulamalarndan sonra, bu blmle birlikte ilk kez
dmeli-menl modern arayzleri tanmaya da balayacaz. stelik grak arayzl
programlar zerinde almak, nesne tabanl programlamann zellikle karmak ynlerini
ok daha kolay ve net bir ekilde anlamamz da salayacak.

42.1 Miras Alma

Bu blmde, yine nesne tabanl programlamaya ait bir kavram olan miras almadan sz
edeceiz. Btn ayrntlaryla ele alacamz miras alma, nesne tabanl programlamann en
nemli konularndan birisidir. Hatta nesne tabanl programlamay faydal bir programlama
yaklam haline getiren zelliklerin banda miras alma gelir dersek ok da abartm
olmayz. Ayrca miras alma konusu, komut satrnda alan programlarn yansra
grak arayzl programlar da yazabilmemizin nndeki son engel olacak. Bu blm
tamamladktan sonra, grak arayzl programlar yazmamz salayacak zel modllerin
belgelerinden yararlanabilmeye ve grak arayzl programlarn kodlarn okuyup anlamaya
balayabileceiz.
Daha nce de sylediimiz gibi, Python programlama dilinin temel felsefesi, bir kez yazlan
kodlar en verimli ekilde tekrar tekrar kullanabilmeye dayanr. Genel olarak baktmzda
dilin hemen hemen btn eleri bu amaca hizmet edecek ekilde tasarlanmtr. te bu
balk altnda ele alacamz miras alma kavram da kodlarn tekrar tekrar kullanlabilmesi
felsefesine katk sunan bir zelliktir.
sterseniz miras alma konusunu anlatmaya basit bir rnekle balayalm.
Diyelim ki bir oyun yazyorsunuz. Bu oyun iinde askerler, iiler, yneticiler, krallar,
kralieler ve bunun gibi oyuncu trleri olacak. Bu oyuncular ve kabiliyetlerini mesela yle
tanmlayabilirsiniz:
class Asker():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe

738
Python 3 iin Trke Klavuz, Srm 3

self.g = 100

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class i():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 70

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Ynetici():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 20

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

Burada asker, ii ve yneticinin her biri iin ayr bir snf tanmladk. Her snfn bir ismi,
rtbesi ve gc var. Ayrca her snf; hareket etme, puan kazanma ve puan kaybetme gibi
kabiliyetlere sahip.
Bu kodlarn oyuncular.py adl bir dosyada bulunduunu varsayarsak, mesela bir asker
oluturmak iin yukardaki kodlar yle kullanabiliriz:
>>> import oyuncular
>>> asker1 = oyuncular.Asker('Mehmet', 'er')

Asker() snfnn isim ve rtbe parametrelerini belirtmek suretiyle bir asker nesnesi
oluturduk. Tpk Pythonda grdmz baka nesneler gibi, bu nesne de eitli nitelik ve
metotlardan oluuyor:
>>> dir(asker1)

42.1. Miras Alma 739


Python 3 iin Trke Klavuz, Srm 3

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',


'__eq__', '__format__', '__ge__', '__getattribute__', '__gt__',
'__hash__', '__init__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'g',
'hareket_et', 'isim', 'puan_kaybet', 'puan_kazan', 'rtbe']

Bu nitelik ve metotlar asker nesnesi zerine nasl uygulayacamz biliyorsunuz:


>>> asker1.isim

'Mehmet'

>>> asker1.rtbe

'er'

>>> asker1.g

100

>>> asker1.hareket_et()

'hareket ediliyor...'

>>> asker1.puan_kazan()

'puan kazanld'

>>> asker1.puan_kaybet()

'puan kaybedildi'

Ayn ekilde teki i() ve Ynetici() snarn da rnekleyip kullanabiliriz. Bu konuda bir
problem yok. Ancak yukardaki kodlar incelediinizde, ayn kodlarn srekli tekrarlandn
greceksiniz. Grdnz gibi, ayn nitelik ve metotlar her snf iin yeniden tanmlyoruz.
Bu durumun Pythonn mantalitesine aykr olduunu tahmin etmek hi zor deil. Peki acaba
yukardaki kodlar nasl daha Pythonvari hale getirebiliriz?
Bu noktada ilk olarak taban snardan sz etmemiz gerekiyor.

42.2 Taban Snar

Taban snar (base classes ) miras alma konusunun nemli kavramlarndan biridir. Dilerseniz
taban snfn ne olduu anlayabilmek iin, yukarda verdiimiz rnei temel alarak ok basit
bir uygulama yapalm.
ncelikle yukarda verdiimiz rnei tekrar nmze alalm:
class Asker():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 100

740 Blm 42. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class i():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 70

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Ynetici():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 20

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

Bu rnekte, Asker(), i() ve Ynetici() adl snarn ieriine baktmzda pek ok metot
ve niteliin aslnda birbiriyle ayn olduunu gryoruz. Gelin isterseniz btn snarda ortak
olan bu nitelik ve metotlar tek bir snf altnda toplayalm.
Asker(), i() ve Ynetici() snarnn, yazdmz programdaki oyuncular temsil ettiini
dnrsek, ortak nitelik ve metotlar barndran snfmz da Oyuncu() olarak adlandrmamz
mantksz olmayacaktr:
class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):

42.2. Taban Snar 741


Python 3 iin Trke Klavuz, Srm 3

print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

te burada Oyuncu() adl snf, bir taban snf olarak adlandrlr. Taban snf denen ey,
birka farkl snfta ortak olan nitelik ve metotlar barndran bir snf trdr. ngilizcede
base class olarak adlandrlan taban snar, ayrca st snf (super class ) veya ebeveyn snf
(parent class ) olarak da adlandrlr. Biz bu makalede taban snf ismini tercih edeceiz.
Yukardaki Oyuncu() adl taban snf da, i(), Asker(), Ynetici() gibi snarn hepsinde
ortak olarak bulunacak nitelik ve metotlar barndracak. teki btn snar, ortak nitelik ve
metotlarn her defasnda tek tek yeniden tanmlamak yerine, Oyuncu() adl bu taban snftan
devralacak. Peki ama nasl? te bunu anlamak iin de alt snf adl bir kavrama deinmemiz
gerekiyor.

42.3 Alt Snar

Bir taban snftan treyen btn snar, o taban snfn alt snardr. (subclass ). Alt snar,
kendilerinden tredikleri taban snarn metot ve niteliklerini miras yoluyla devralr.
Anlattmz bu soyut eyleri anlamann en kolay yolu somut bir rnek zerinden ilerlemektir.
Mesela, biraz nce tanmladmz Oyuncu() adl taban snftan bir alt snf tretelim:
class Asker(Oyuncu):
pass

Kodlarmz tam olarak yle grnyor:


class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Asker(Oyuncu):
pass

Burada Asker() snfn tanmlarken, bu snfn parantezleri iine Oyuncu() snfnn adn
yazdmza dikkat edin. te bu ekilde bir snfn parantezleri iinde baka bir snfn adn
belirtirsek, o snf, parantez iinde belirttiimiz snfn bir alt snf olmu olur. Yani mesela
yukardaki gibi Asker() snfnn parantezleri arasna Oyuncu() snfnn adn yazdmzda,
Asker() adl snf;
1. Oyuncu() adl snf miras alm,

742 Blm 42. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

2. Oyuncu() adl snfn btn metot ve niteliklerini devralm,


3. Oyuncu() adl snftan tremi oluyor.
Bu sayede Oyuncu() snfnda tanmlanan btn nitelik ve metotlara Asker() snfndan da
eriebiliyoruz:
>>> import oyuncular
>>> asker1 = oyuncular.Asker('Ahmet', 'Er')
>>> asker1.isim

'Ahmet'

>>> asker1.rtbe

'Er'

>>> asker1.g

>>> asker1.puan_kazan()

'puan kazanld'

rnek olmas asndan, Oyuncu() snfndan treyen (miras alan) birka alt snf daha
tanmlayalm:
class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Asker(Oyuncu):
pass

class i(Oyuncu):
pass

class Ynetici(Oyuncu):
pass

Tanmladmz bu i() ve Ynetici() snar da tpk Asker() snf gibi Oyuncu() adl
snftan miras ald iin, Oyuncu() snfnn sahip olduu tm nitelik ve metotlara sahiptirler.
Buraya kadar anlattklarmz zetleyecek olursak, u snf bir taban snftr:
class Oyuncu():
def __init__(self, isim, rtbe):

42.3. Alt Snar 743


Python 3 iin Trke Klavuz, Srm 3

self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

Bu taban snf, kendisinden treyecek alt snarn ortak nitelik ve metotlarn tanmlar.
u snar ise, yukardaki taban snftan treyen birer alt snftr:
class Asker(Oyuncu):
pass

class i(Oyuncu):
pass

class Ynetici(Oyuncu):
pass

Bu alt snar, Oyuncu() adl taban snfn btn nitelik ve metotlarn miras yoluyla devralr.
Yani Oyuncu() adl taban/ebeveyn/st snfn nitelik ve metotlarna, Asker(), i() ve
Ynetici() adl alt snardan eriebiliriz:
>>> asker1 = Asker('Ahmet', 'stihkamc')
>>> ii1 = i('Mehmet', 'Usta')
>>> ynetici1 = Ynetici('Selim', 'Mdr')
>>> asker1.hareket_et()

'hareket ediliyor...'

>>> ii1.puan_kaybet()

'puan kaybedildi'

>>> ynetici1.puan_kazan()

'puan kazanld'

te bu mekanizmaya miras alma (inheritance ) ad verilir. Miras alma mekanizmas, bir kez
yazlan kodlarn farkl yerlerde kullanlabilmesini salayan, bu bakmdan da programcy kod
tekrarna dmekten kurtaran olduka faydal bir aratr. lerleyen sayfalarda miras alma
mekanizmasnn baka faydalarn da greceiz.

42.4 Miras Alma Trleri

Tahmin edebileceiniz gibi, miras alma yalnzca bir snfn parantezleri arasna baka bir snf
yazarak ilgili snfn btn nitelik ve metotlarn kaytsz artsz devralmaktan ibaret deildir.
Bir snf, muhtemelen, miras ald nitelik ve metotlar zerinde birtakm deiiklikler de

744 Blm 42. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

yapmak isteyecektir. Esasnda miras alma mekanizmasnn ileyii bakmndan kabaca


ihtimalden sz edebiliriz:
1. Miras alnan snfn btn nitelik ve metotlar alt snfa olduu gibi devredilir.
2. Miras alnan snfn baz nitelik ve metotlar alt snfta yeniden tanmlanr.
3. Miras alnan snfn baz nitelik ve metotlar alt snfta deiiklie uratlr.
Bu ihtimallerden ilkini zaten grmtk. Bir snfn parantezleri arasna baka bir snfn adn
yazdktan sonra eer alt snfta herhangi bir deiiklik yapmazsak, taban snftaki nitelik ve
metotlar olduu gibi alt snara aktarlacaktr.
Mesela:
class Asker(Oyuncu):
pass

Burada Asker() snf, miras ald Oyuncu() snfnn sanki bir kopyas gibidir. Dolaysyla
Oyuncu() snfnn btn nitelik ve metotlarna Asker() snf altndan da aynen eriebiliriz.
Yani yukardaki kod, Oyuncu() adl snfn btn nitelik ve metotlarnn Asker() snf
tarafndan miras alnmasn salar. Bu ekilde, Oyuncu() snf iinde hangi metot veya nitelik
nasl tanmlanmsa, Asker() snfna da o ekilde devredilir.
Taban snfmzn u ekilde tanmlandn biliyoruz:
class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

Dolaysyla bu taban snfta hangi nitelik ve metotlar hangi deerlere sahipse aadaki
Asker(), i() ve Ynetici() snar da o deerlere sahip olacaktr:
class Asker(Oyuncu):
pass

class i(Oyuncu):
pass

class Ynetici(Oyuncu):
pass

Ancak, dediimiz gibi, miras almada tek seenek btn metot ve nitelikleri olduu gibi alt
snara aktarmak deildir. Zaten yle olsayd miras alma mekanizmasnn pek bir anlam
olmazd. Biz miras aldmz snar zerinde, iinde bulunduumuz durumun gerektirdii
birtakm deiiklikleri yapabilmeliyiz ki bu mekanizmann ilgi ekici bir yan olsun.

42.4. Miras Alma Trleri 745


Python 3 iin Trke Klavuz, Srm 3

Ayrca eer bir taban snf alt snara olduu gibi aktaracaksanz, taban snftan gelen
metot ve nitelikler zerinde herhangi bir deiiklik yapmayacaksanz ve alt snara da
herhangi bir nitelik ilave etmeyecekseniz, alt snar tanmlamak yerine dorudan taban
snfn rneklerinden yararlanmak daha akllca ve pratik bir tercih olabilir:
>>> asker = Oyuncu('Ahmet', 'Er')
>>> ii = Oyuncu('Mehmet', 'Usta')
>>> ynetici = Oyuncu('Selim', 'Mdr')

Burada asker, ii ve ynetici iin ayr ayr alt snar tanmlamak yerine, her biri iin dorudan
Oyuncu() snfn farkl isim ve rtbe deerleriyle rnekleyerek istediimiz eyi elde ettik.
lerleyen derslerde miras alma alternatierinden daha ayrntl bir ekilde sz edeceiz, ama
dilerseniz imdi konuyu daha fazla datmadan miras alnan metot ve niteliklerin alt snar
iinde nasl yeniden tanmlanacan, nasl deiiklie uratlacan ve alt snara nasl yeni
nitelik ve metotlar ekleneceini incelemeye geelim ve ilk rneklerimizi vermeye balayalm.
Hatrlarsanz bir nceki balkta yle bir kod yazmtk:
class Asker(Oyuncu):
pass

Burada Oyuncu() snfn btnyle alt snfa aktardk. Peki ya biz bir taban snf olduu
gibi miras almak yerine, baz nitelikleri zerinde deiiklik yaparak miras almak istersek ne
olacak? Mesela taban snf iinde self.g deeri 0. Biz bu deerin Asker(), i() ve
Ynetici() rnekleri iin birbirinden farkl olmasn isteyebiliriz. Veya taban snf olduu gibi
miras almakla birlikte, alt snardan herhangi birine ilave nitelik veya nitelikler eklemek de
isteyebiliriz. Diyelim ki biz Asker() snf iin, teki snardan farkl olarak, bir de memleket
nitelii tanmlamak istiyoruz. Peki bu durumda ne yapacaz?
te bunun iin Asker() snfn u ekilde yazabiliriz:
class Asker(Oyuncu):
memleket = 'Arpabahi'

Burada Asker() snfna memleket adl bir snf nitelii eklemi olduk. Dolaysyla Asker()
snf, Oyuncu() adl taban snftan miras alnan btn nitelik ve metotlarla birlikte bir de
memleket niteliine sahip olmu oldu:
>>> asker = Asker('Ahmet', 'binba')
>>> asker.isim

'Ahmet'

>>> asker.memleket

'Arpabahi'

Elbette, bu nitelii br alt snarda tanmlamadmz iin bu nitelik yalnzca Asker() snfna
zgdr.
Ayn ekilde, bir taban snftan treyen bir alt snfa yeni bir snf metodu, rnek metodu veya
statik metot da ekleyebiliriz:
class Asker(Oyuncu):
memleket = 'Arpabahi'

746 Blm 42. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

def rnek_metodu(self):
pass

@classmethod
def snf_metodu(cls):
pass

@staticmethod
def statik_metot():
pass

Kural u: Eer alt snfa eklenen herhangi bir nitelik veya metot taban snfta zaten varsa, alt
snfa eklenen nitelik ve metotlar taban snftaki metot ve niteliklerin yerine geecektir. Yani
diyelim ki taban snfmz u:
class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

Bu snfn nitelik ve metotlarn miras yoluyla devralan Asker() snfmz ise u:


class Asker(Oyuncu):
pass

imdi bu snf iinde hareket_et() adl bir rnek metodu tanmlayalm:


class Asker(Oyuncu):
def hareket_et(self):
print('yeni hareket_et() metodu')

Eer taban snfta hareket_et() adl bir snf olmasayd, Asker() adl alt snf, taban snftan
miras alnan teki metot ve niteliklerle birlikte bir de hareket_et() adl yeni bir rnek
metoduna sahip olmu olacakt. Ancak taban snfta zaten hareket_et() adl bir rnek
metodu olduu iin, alt snfta tanmladmz ayn adl rnek metodu, taban snftaki metodun
yerine geip zerine yazyor.
Buraya kadar her ey tamam. Artk bir taban snfa ait metodu alt snfa miras yoluyla
aktarrken nasl yeniden tanmlayacamz rendik. Ayrca alt snara nasl yeni metot
ve nitelik ekleyeceimizi de biliyoruz. Ama mesela, self.isim ve self.rtbe deikenlerini
korurken, taban snf iinde 0 deeri ile gsterilen self.g deikenini Asker(), i() ve
Ynetici() snarnn her biri iinde nasl farkl bir deerle gstereceimizi bilmiyoruz. Yani
self.g deerini Asker() snf iinde 100, i() snf iinde 70, Ynetici() snf iinde
ise 50 ile gstermek istesek nasl bir yol takip etmemiz gerektii konusunda bir krimiz yok.
sterseniz u ana kadar bildiimiz yntemleri kullanarak bu amacmz gerekletirmeyi bir
deneyelim:

42.4. Miras Alma Trleri 747


Python 3 iin Trke Klavuz, Srm 3

class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Asker(Oyuncu):
def __init__(self, isim, rtbe):
self.g = 100

class i(Oyuncu):
def __init__(self, isim, rtbe):
self.g = 70

class Ynetici(Oyuncu):
def __init__(self, isim, rtbe):
self.g = 50

Burada taban snfn __init__() metodunu alt snarda yeniden tanmladk. Bu kodlar bu
ekilde yazp altrdmzda self.g deerinin herbir alt snf iin istediimiz deere sahip
olduunu grrz. Ancak burada yle bir sorun var. Bu kodlar bu ekilde yazarak self.isim
ve self.rtbe deikenlerinin deerini maalesef kaybettik...
__init__() metodunun parametre listesine isim ve rtbe parametrelerini yazdmz halde
bunlar kodlarmz iinde herhangi bir ekilde kullanmadmz iin, bu parametrelerin listede
grnyor olmas bir ey ifade etmiyor. Yani alt snarda tanmladmz __init__() metodu
bizden isim ve rtbe adl iki parametre bekliyor olsa da, bu parametrelerin deerini kodlar
iinde kullanmadmz iin bu parametrelere deer atamamz herhangi bir amaca hizmet
etmiyor.
Gelin bu sylediklerimizi kantlayalm:
>>> import oyuncular
>>> asker = oyuncular.Asker('Ahmet', 'Er')
>>> asker.rtbe

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'Asker' object has no attribute 'rtbe'

>>> asker.isim

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'Asker' object has no attribute 'isim'

Bu sorunu zmek iin alt snarmz u ekilde yazabiliriz:

748 Blm 42. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

class Asker(Oyuncu):
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 100

class i(Oyuncu):
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 70

class Ynetici(Oyuncu):
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 50

Burada self.isim ve self.rtbe deikenlerini herbir alt snf iin tekrar tanmladk. Bu kk
rnekte pek sorun olmayabilir, ama taban snfn __init__() metodunun iinde ok daha
karmak ilemlerin yapld durumlarda yukardaki yaklam hi de pratik olmayacaktr.
Ayrca eer miras alma ilemini, ieriini bilmediiniz veya baka bir dosyada bulunan bir
snftan yapyorsanz yukardaki yntem tamamen kullansz olacaktr. Ayrca ayn eyleri
tekrar tekrar yazmak miras alma mekanizmasnn ruhuna tamamen aykrdr. nk biz miras
alma ilemini zaten ayn eyleri tekrar tekrar yazmaktan kurtulmak iin yapyoruz.
Bu arada, yukarda yapmak istediimiz eyi ununla kartrmayn: Biz elbette taban snftaki
bir nitelii, rnekleme srasnda deitirme imkanna her koulda sahibiz. Yani taban ve alt
snarn yle tanmlanm olduunu varsayarsak:
class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Asker(Oyuncu):
pass

class i(Oyuncu):
pass

class Ynetici(Oyuncu):
pass

Herbir alt snfn g deikenini u ekilde deitirebiliriz:

42.4. Miras Alma Trleri 749


Python 3 iin Trke Klavuz, Srm 3

>>> import oyuncular


>>> asker = oyuncular.Asker('Ahmet', 'Er')
>>> asker.g

Grdnz gibi u anda askerin gc 0. Bunu 100 yapalm:


>>> asker.g = 100
>>> asker.g

100

Ayn eyi teki i() ve Ynetici() snarnn rnekleri zerinde de yapabiliriz. Ama
bizim istediimiz bu deil. Biz, Asker() snfn rneklediimiz anda gc 100, i() snfn
rneklediimiz anda gc 70, Ynetici() snfn rneklediimiz anda ise gc 50 olsun
istiyoruz.
te tam bu noktada imdadmza yepyeni bir fonksiyon yetiecek. Bu yeni fonksiyonun ad
super().

42.5 super()

Hatrlarsanz, taban snardan ilk kez bahsederken, bunlara st snf da dendiini sylemitik.
st snf kavramnn ngilizcesi super class tr. te bu blmde inceleyeceimiz super()
fonksiyonunun ad da buradaki super, yani st kelimesinden gelir. Miras alnan st snfa
atfta bulunan super() fonksiyonu, miras aldmz bir st snfn nitelik ve metotlar zerinde
deiiklik yaparken, mevcut zellikleri de muhafaza edebilmemizi salar.
Bir nceki balkta verdiimiz rnek zerinden super() fonksiyonunu aklamaya alalm:
class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Asker(Oyuncu):
def __init__(self, isim, rtbe):
self.g = 100

Bu kodlarda, Oyuncu() adl taban snf miras alan Asker() snf, __init__() metodu iinde
self.g deerini yeniden tanmlyor. Ancak bu ekilde taban snfn __init__() metodu
silindii iin, self.isim ve self.rtbe deikenlerini kaybediyoruz. te bu sorunu, st snfa
atfta bulunan super() fonksiyonu ile zebiliriz.
Dikkatlice bakn:

750 Blm 42. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

class Asker(Oyuncu):
def __init__(self, isim, rtbe):
super().__init__(isim, rtbe)
self.g = 100

Burada __init__() metodu iinde yle bir satr kullandmz gryorsunuz:


super().__init__(isim, rtbe)

te bu satrda super() fonksiyonu, tam da adnn anlamna uygun olarak, miras alnan st
snfn __init__() metodu iindeki kodlarn, miras alan alt snfn __init__() metodu iine
aktarlmasn salyor. Bylece hem taban snfn __init__() metodu iindeki self.isim ve
self.rtbe niteliklerini korumu, hem de self.g adl yeni bir nitelik ekleme imkan elde etmi
oluyoruz:
>>> asker = oyuncular.Asker('Ahmet', 'Er')
>>> asker.isim

'Ahmet'

>>> asker.rtbe

'Er'

>>> asker.g

100

Bu bilgiyi teki alt snara da uygulayalm:


class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Asker(Oyuncu):
def __init__(self, isim, rtbe):
super().__init__(isim, rtbe)
self.g = 100

class i(Oyuncu):
def __init__(self, isim, rtbe):
super().__init__(isim, rtbe)
self.g = 70

class Ynetici(Oyuncu):
def __init__(self, isim, rtbe):

42.5. super() 751


Python 3 iin Trke Klavuz, Srm 3

super().__init__(isim, rtbe)
self.g = 20

Grdnz gibi, super() fonksiyonu sayesinde taban snfn deitirmek istediimiz


niteliklerine yeni deerler atarken, deitirmek istemediimiz nitelikleri ise ayn ekilde
muhafaza ettik.
Bu arada eer taban snfn __init__() metodundaki parametre listesini alt snfta da tek tek
tekrar etmek sizi rahatsz ediyorsa yukardaki kodlar yle de yazabilirsiniz:
class Asker(Oyuncu):
def __init__(self, *arglar):
super().__init__(*arglar)
self.g = 100

class i(Oyuncu):
def __init__(self, *arglar):
super().__init__(*arglar)
self.g = 70

class Ynetici(Oyuncu):
def __init__(self, *arglar):
super().__init__(*arglar)
self.g = 20

Yldzl parametreleri nceki derslerimizden hatrlyor olmalsnz. Bildiiniz gibi, tek yldzl
parametreler bir fonksiyonun btn konumlu (positional ) argmanlarn, parametrelerin
parantez iinde getii sray dikkate alarak bir demet iinde toplar. te yukarda da bu
zellikten faydalanyoruz. Eer taban snfta isimli (keyword ) argmanlar da olsayd, o zaman
da ift yldzl argmanlar kullanabilirdik.
Tek ve ift yldzl argmanlar genellikle u ekilde gsterilir:
class Asker(Oyuncu):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.g = 100

Bylece konumlu argmanlar bir demet iinde, isimli argmanlar ise bir szlk iinde
toplam oluyoruz. Bu da bizi st (ya da taban) snfn parametre listesini alt snarda tekrar
etme derdinden kurtaryor.
Bu arada, miras alnan taban snfa atfta bulunan super() fonksiyonu, Python programlama
diline sonradan eklenmi bir zelliktir. Bu fonksiyon gelmeden nce taban snfa atfta
bulunabilmek iin dorudan o snfn adn kullanyorduk:
class Asker(Oyuncu):
def __init__(self, isim, rtbe):
Oyuncu.__init__(self, isim, rtbe)
self.g = 100

veya:
class Asker(Oyuncu):
def __init__(self, *args):
Oyuncu.__init__(self, *args)
self.g = 100

752 Blm 42. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, eski yntemde taban snfn adn iki kez kullanmamz gerekiyor. Ayrca
__init__() fonksiyonunun parametre listesinde ilk sraya yine self kelimesini de eklemek
zorunda kalyoruz.
sterseniz yukarda gsterdiimiz eski yntemi kullanmaya devam edebilirsiniz elbette. Ancak
super() fonksiyonunu kullanmak eski ynteme gre biraz daha pratiktir.
Yukardaki rneklerde super() fonksiyonunu __init__() metodu iinde kullandk. Ancak
elbette super() fonksiyonunu yalnzca __init__() fonksiyonu iinde kullanmak zorunda
deiliz. Bu fonksiyonu baka fonksiyonlar iinde de kullanabiliriz:
class Oyuncu():
def __init__(self, isim, rtbe):
self.isim = isim
self.rtbe = rtbe
self.g = 0

def hareket_et(self):
print('hareket ediliyor...')

def puan_kazan(self):
print('puan kazanld')

def puan_kaybet(self):
print('puan kaybedildi')

class Asker(Oyuncu):
def __init__(self, isim, rtbe):
super().__init__(isim, rtbe)
self.g = 100

def hareket_et(self):
super().hareket_et()
print('hedefe ulald.')

Bu rnein, super() fonksiyonunun nasl ilediini daha iyi anlamanz saladn


zannediyorum. Grdnz gibi, taban snfn hareket_et() adl metodunu alt snfta
tanmladmz ayn adl fonksiyon iinde super() fonksiyonu yardmyla genilettik, yani
taban snfn hareket_et() adl fonksiyonuna yeni bir ilev ekledik:
def hareket_et(self):
super().hareket_et()
print('hedefe ulald.')

Burada super().hareket_et() satryla taban snfn hareket_et() adl metodunu alt snfta
tanmladmz yeni hareket_et() metodu iinde altrarak, bu metodun kabiliyetlerini yeni
hareket_et() metoduna aktaryoruz.

42.6 object Snf

Biz buraya gelinceye kadar Pythonda snar iki farkl ekilde tanmlayabileceimizi rendik:
class Deneme():
pass

veya:

42.6. object Snf 753


Python 3 iin Trke Klavuz, Srm 3

class Deneme:
pass

Snf tanmlarken parantez kullansak da olur kullanmasak da. Eer miras alacanz bir snf
yoksa parantezsiz yazm tercih edebilir, parantezli yazm tarzn ise baka bir snftan miras
aldnz durumlar iin saklayabilirsiniz:
class AltSnf(TabanSnf):
pass

Ancak sada solda incelediiniz Python kodlarnda bazen yle bir snf tanmlama ekli de
grrseniz armayn:
class Snf(object):
pass

Pythonn 3.x ncesi srmlerinde snar yeni ve eski tip olmak zere ikiye ayrlyordu. Bu
srmlerde eski tip snar yle tanmlanyordu:
class Snf:
pass

veya:
class Snf():
pass

Yeni tip snar ise yle:


class Snf(object):
pass

Yani eski tip snar ntanml olarak herhangi bir taban snftan miras almazken, yeni
tip snarn object adl bir snftan miras almas gerekiyordu. Dolaysyla, tanmladnz
bir snfta object snfn miras almadnzda, yeni tip snarla birlikte gelen zelliklerden
yararlanamyordunuz. Mesela nceki derslerde rendiimiz @property bezeyicisi yeni tip
snarla gelen bir zelliktir. Eer Python 3 ncesi bir srm iin kod yazyorsanz ve eer
@property bezeyicisini kullanmak istiyorsanz tanmladnz snarda ak ak object snfn
miras almalsnz.
Python 3te ise btn snar yeni tip snftr. Dolaysyla object snfn miras alsanz da
almasanz da, tanmladnz btn snar ntanml olarak object snfn miras alacaktr.
Yani Python 3 asndan u tanmlama arasnda bir fark bulunmaz:
class Snf:
pass

class Snf():
pass

class Snf(object):
pass

Bunlarn hepsi de Python 3 asndan birer yeni tip snftr. Daha dorusu Python 3te btn
snar bir yeni tip snf olduu iin, yukardaki snf tanmlamalar hep ayn tipte snara
iaret eder. Python 2de ise ilk iki tanmlama eski tip snar gsterirken, yalnzca nc
tanmlama yeni tip snar gsterir.

754 Blm 42. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

Geldik bir blmn daha sonuna... Bylece miras almaya ilikin temel konular
incelemi olduk. Bu blmde rendiklerimiz sayesinde, etrafta grdmz, miras alma
mekanizmasnn kullanld kodlarn ok byk bir blmn anlayabilecek duruma geldik.
Bu mekanizmaya ilikin olarak renmemiz gerekenlerin geri kalann da bir sonraki blmde,
grak arayz tasarm konusuyla birlikte ele alacaz.

42.6. object Snf 755


BLM 43

Nesne Tabanl Programlama (Devam)

Uyar: Bu makale youn bir ekilde gelitirilmekte, ierii sk sk gncellenmektedir.

Geen blmde verdiimiz bilgiler sayesinde miras alma konusunun temelini oluturan taban
snf, alt snf ve treme gibi kavramlarla birlikte super() ve object gibi aralarn ne olduunu
ve ne ie yaradn da rendik. Dolaysyla artk miras alma mekanizmasna dair daha renkli,
daha tevik edici rnekler verebiliriz. Bylece, belki de gznze ilk bakta pek de matah bir
ey deilmi gibi grnen bu miras alma denen mekanizmann aslnda ne kadar nemli bir
konu olduuna sizleri ikna edebiliriz.
Bu blmde ayrca geen blmlerde incelemeye frsat bulamasak da nesne tabanl
programlama kapsamnda incelememiz gereken baka konular da ele alacaz.
Nesne tabanl programlamadan ilk bahsettiimiz derste, nesne tabanl programlama
yaklamnn grak arayz tasarm iin biilmi kaftan olduundan sz etmitik hatrlarsanz.
Bu blmde inceleyeceimiz konularn bazlarn grak arayz tasarm eliinde anlatacaz.
Grak arayz programlamann bize sunduu dmeli-menl grsel programlarn, nesne
tabanl programlamaya ilikin soyut kavramlar somut bir dzleme tamamza imkan
tanmas sayesinde, nesne tabanl programlamaya ilikin etrelli konular daha rahat anlama
frsat bulacaz.

43.1 Tkinter Hakknda

Hatrlarsanz, nceki derslerimizde birka kez Tkinter adl bir modlden sz etmitik. Tkinter,
Python kurulumu ile birlikte gelen ve pencereli-menl modern programlar yazmamz
salayan grak arayz gelitirme takmlarndan biridir.
Tkinter bir standart ktphane paketi olduu iin, Python programlama dilini kurduunuzda
Tkinter de otomatik olarak kurulur1 .
Elbette Pythonda grak arayzl programlar yazmamz salayacak tek modl Tkinter
deildir. Bunun dnda PyQt, PyGI ve Kivy gibi alternatier de bulunur. Ancak Tkinterin
teki alternatiere kar en byk stnl hem brlerine kyasla ok daha kolay olmas
hem de Pythonla birlikte gelmesidir. PyQt, PyGI ve Kivyyi kullanabilmek iin ncelikle bunlar
bilgisayarnza kurmanz gerekir. Ayrca Tkinter dndaki alternatieri kullanarak yazdnz
1
GNU/Linux datmlarnda, datm gelitiren ekip genellikle Tkinter paketini Python paketinden ayrd
iin, Tkinteri ayrca kurmanz gerekebilir. Eer Pythonn etkileimli kabuunda import tkinter komutunu
verdiinizde bir hata mesaj alyorsanz http://www.istihza.com/forum adresinden yardm isteyin. Eer Windows
kullanyorsanz, byle bir probleminiz yok. Python kurduunuz anda Tkinter de emrinize amadedir.

756
Python 3 iin Trke Klavuz, Srm 3

programlar datrken, bu arayz ktphanelerini kullanclarnzn bilgisayarna ya kendiniz


kurmanz ya da kullanclarnzdan bu ktphaneleri kurmasn talep etmeniz gerekir.
Ben size, ilerde baka arayz takmlarna gei yapacak da olsanz, Tkinteri mutlaka
renmenizi tavsiye ederim. Hem nesne tabanl programlama hem de grak arayz
gelitirme kavramlarn renmek asndan Tkinter son derece uygun bir ortamdr.
Biz bu blmde Tkinter modln kullanarak, prosedrel programlama, nesne tabanl
programlama, snar, miras alma ve nesne programlamaya ilikin teki konular zerine
ufak tefek de olsa baz almalar yapacaz. Bu almalar sayesinde bir yandan
rendiimiz eski konulara ilikin gzel bir pratik yapma imkan bulacaz, bir yandan
Tkinterin almalarmzn sonucunu grsel bir ekilde izleme imkan salamas sayesinde
nesne tabanl programlamann etrelli kavramlarn anlamamz kolaylaacak, bir yandan da
ilk kez grdmz kodlar anlama ve bunlar hakknda kir yrtme kabiliyeti kazanacaz.
Yani bir tala tam tamna ku vurmu olacaz...

43.2 Prosedrel Bir rnek

Bata da sylediimiz gibi, nesne tabanl programlama, grak arayzl programlar


gelitirmek iin son derece uygun bir programlama yaklamdr. Zaten kendi aratrmalarnz
srasnda da, etraftaki grak arayzl programlarn byk ounluunun nesne tabanl
programlama yaklamyla yazldn greceksiniz. Biz de bu derste vereceimiz Tkinter
rneklerinde sn yaplar kullanacaz. Ancak dilerseniz Tkinterin nasl bir ey olduunu
daha kolay anlayabilmek iin ncelikle nesne tabanl yaklam yerine prosedrel yaklam
kullanarak birka kk alma yapalm. Zira zellikle basit kodlarda, prosedrel yapy
anlamak nesne tabanl programlama yaklam ile yazlm kodlar anlamaktan daha kolaydr.
Ancak tabii ki kodlar byyp karmaklatka sn yaplar kullanmak ok daha akllca
olacaktr.
O halde gelin isterseniz Tkinter modln nasl kullanacamz anlamak iin, bir metin
dosyas ap iine u kodlar yazalm:
import tkinter

pencere = tkinter.Tk()
pencere.mainloop()

Bu kodlar herhangi bir Python program gibi kaydedip altrdnzda bo bir pencerenin
aldn greceksiniz. te bylece siyah komut satrndan renkli grak arayze gei yapm
oldunuz. Hadi hayrl olsun!
Grdnz gibi, bu kodlarda snar kullanmadk. Dediimiz gibi, ilk etapta Tkinteri daha
iyi anlayabilmek iin sn yaplar yerine prosedrel bir yaklam benimseyeceiz.
Burada ncelikle Tkinter modln ie aktardmza dikkat edin:
import tkinter

Modl bu ekilde ie aktardmz iin, modl iindeki nitelik ve metotlara erimek


istediimizde modln adn kullanmamz gerekecek. Mesela yukarda modln adn
kullanarak, tkinter modl iindeki Tk() snfn rnekledik:
pencere = tkinter.Tk()

43.2. Prosedrel Bir rnek 757


Python 3 iin Trke Klavuz, Srm 3

Dilerseniz ie aktarma ilemini u ekilde yaparak ilerimizi biraz daha kolaylatrabiliriz:


import tkinter as tk

Bylece tkinter modlnn nitelik ve metotlarna tkinter yerine tk nekiyle eriebiliriz:


pencere = tk.Tk()

Yukardaki kodlar yazdmzda, yani tkinter modlnn Tk() snfn rneklediimiz anda
aslnda penceremiz olutu. Ancak bu pencere rnekleme ile birlikte olumu olsa da,
Tkinterin i ileyii gerei, ana dng adl bir mekanizma almaya balamadan grnr
hale gelmez. te bu zel ana dng mekanizmasn altrmak ve bylece oluturduumuz
pencereyi grnr hale getirmek iin, Tk() snf rneklerinin mainloop() adl bir metodunu
altracaz:
pencere.mainloop()

Grdnz gibi, Tk() snfn pencere adyla rnekledikten sonra Tk() snfnn mainloop()
adl metoduna pencere rnei zerinden eritik.
Bu ana dng mekanizmasnn benzerlerini Tkinterin dndaki br grak arayz tasarm
aralarnda da greceksiniz.
Bu arada, yukardaki prosedrel rnekte bile, biz istemesek de snarla muhatap
olduumuza dikkatinizi ekmek isterim. nk kullandmz tkinter modlnn kendisi
halihazrda birtakm snardan oluuyor. Dolaysyla bu modl ie aktardmzda,
kodlarmzn iine pek ok snf ister istemez dahil etmi oluyoruz. Esasnda srf bu durum
bile, grak arayzl programlarda neden nesne tabanl programlamann tercih edildiini
gayet gzel gsteriyor bize. Neticede, kullandmz harici kaynaklardan tr her ekilde
snarla ve nesne tabanl yaplarla ili dl olacamz iin, kendi yazdmz kodlarda da
nesne tabanl yaplardan kamamzn hibir gerekesi yok.
Neyse... Biz konumuza dnelim...
Yukarda Tkinter modln kullanarak bo bir pencere oluturduk. Gelin isterseniz bu bo
pencere zerinde birtakm deiiklikler yapalm.
ncelikle tkinter modlmz ie aktaralm:
import tkinter as tk

imdi bu modln Tk() adl snfn rnekleyelim:


pencere = tk.Tk()

Bylece penceremizi oluturmu olduk. Tkinterle verdiimiz ilk rnekte de grdnz


gibi, Tkinterle oluturulan bo bir pencere ntanml olarak 200 piksel genilie ve
200 piksel ykseklie sahip olacaktr. Ancak isterseniz, Tk() snfnn geometry() adl
metodunu kullanarak, pencere boyutunu ayarlayabilirsiniz (Tk() snfnn hangi metotlara
sahip olduunu grmek iin dir(pencere) komutunu verebileceinizi biliyorsunuz):
import tkinter as tk

pencere = tk.Tk()
pencere.geometry('200x70')

pencere.mainloop()

758 Blm 43. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

Kendi yazdmz snardaki nitelik ve metotlara nasl eriiyorsak, Tk() snfnn nitelik ve
metotlarna da ayn ekilde eritiimize dikkat edin. Neticede bizim yazdklarmz da snftr,
Tk() da snftr. Tk() snfnn bizimkilerden tek fark, Tk() snfnn Python gelitiricilerince
yazlm olmasdr. Yazarlar farkl olsa da btn snar ayn kurallara tabidir. Dolaysyla
ilgili snf kullanabilmek iin nce snfmz rnekliyoruz, ardndan da bu snf iinde tanml
olan nitelik ve metotlara noktal gsterim tekniini kullanarak ulayoruz. Burada da Tk()
snf rneklerinin geometry() metodunu kullanarak 200x200 yerine 200x70 boyutlarnda bir
pencere oluturduk:
pencere.geometry('200x70')

imdi bu bo pencereye bir etiket bir de dme ekleyelim:


import tkinter as tk

pencere = tk.Tk()
pencere.geometry('200x70')

etiket = tk.Label(text='Merhaba Zalim Dnya')


etiket.pack()

dme = tk.Button(text='Tamam', command=pencere.destroy)


dme.pack()

pencere.mainloop()

Burada tkinter modlnn Tk() snfna ek olarak, ayn modln Label() ve Button() adl iki
snfn daha kullandk. Label() snf etiketler, Button() snf ise dmeler oluturmamz
salyor. Bu snarn rnekleri zerinde altrdmz pack() metodunu ise, etiket ve
dmeleri pencere zerine yerletirmek iin kullanyoruz.
Label() ve Button() snarnn text adl bir parametre aldn gryorsunuz. Bu
parametrenin deeri, etiket veya dmenin zerinde ne yazacan gsteriyor.
Bu kodlar da tpk baka Python programlarn altrdnz gibi altrabilirsiniz.
Bu arada, Tkinterde bir eyi oluturmann ve grnr hale getirmenin iki farkl ilem
gerektirdiine zellikle dikkat edin. Mesela zerinde Merhaba Zalim Dnya yazan bir etiket
oluturmak iin u kodu kullanyoruz:
etiket = tk.Label(text='Merhaba Zalim Dnya')

Bu etiketi pencere zerine yerletirmek, yani grnr hale getirmek iin ise u komutu
kullanyoruz:
etiket.pack()

Ayn ekilde bir dme oluturmak iin de u komutu kullanyoruz:


dme = tk.Button(text='Tamam', command=pencere.destroy)

Bylece zerinde Tamam yazan ve tklandnda pencereyi kapatan bir dme oluturmu
oluyoruz. Dmenin zerine tklandnda ne olacan Button() snfnn command
parametresi araclyla belirledik. Bu parametreye, pencere rneinin destroy() metodunu
verdiimizde pencereye kapatma sinyali gnderilecektir. Yalnz bu metodu yazarken
parantez iaretlerini kullanmadmza dikkat edin. Eer metodu pencere.destroy() eklinde

43.2. Prosedrel Bir rnek 759


Python 3 iin Trke Klavuz, Srm 3

parantezli bir biimde yazarsak, kapatma komutu daha dmeye basmadan alacak ve bu
durumda dmemiz dzgn ilemeyecektir.
Tpk etikette olduu gibi, dmemizi de pencere zerine yerletirmek, yani grnr hale
getirmek iin pack() metodundan yararlanyoruz:
dme.pack()

Bunun, Tk() snf ile mainloop() metodu arasndaki ilikiye benzediine dikkatinizi ekmek
isterim: Tpk pack() metoduna benzer bir ekilde, Tk() snf yardmyla da bir pencere
oluturduktan sonra, bu pencerenin grnr hale gelebilmesi iin mainloop() metodunu
altrmamz gerektiini hatrlyorsunuz.
Bu kodlarda Tkintere ilikin ayrntlardan ziyade, sn yaplar kodlarmza nasl dahil
ettiimize ve bunlar nasl kullandmza odaklanmanz istiyorum. Grdnz gibi, tkinter
modlnden ie aktardmz Tk(), Label() ve Button() gibi snarn metot ve niteliklerini,
mesela tpk karakter dizilerinin metot ve niteliklerini kullanr gibi kullanyoruz.
Yukardaki rnekte, tkinter modlnn snarn, kodlarmz iine prosedrel olarak dahil
ettik. Yani her snf, belli bir sraya gre kodlarmz iinde belirtip, bunlar adm adm
altrdk. Prosedrel programlamada kodlarn yazl sras ok nemlidir. Bunu kantlamak
iin ok basit bir rnek verelim:
import tkinter as tk

pencere = tk.Tk()

def k():
etiket['text'] = 'Elveda zalim dnya...'
dme['text'] = 'Bekleyin...'
dme['state'] = 'disabled'
pencere.after(2000, pencere.destroy)

etiket = tk.Label(text='Merhaba Zalim Dnya')


etiket.pack()

dme = tk.Button(text='k', command=k)


dme.pack()

pencere.protocol('WM_DELETE_WINDOW', k)

pencere.mainloop()

Burada herzamanki gibi ncelikle gerekli modl ie aktardk:


import tkinter as tk

Daha sonra Tk() snf yardmyla penceremizi oluturduk:


pencere = tk.Tk()

Ardndan k() adl bir fonksiyon tanmladk:


def k():
etiket['text'] = 'Elveda zalim dnya...'
dme['text'] = 'Bekleyin...'
dme['state'] = 'disabled'
pencere.after(2000, pencere.destroy)

760 Blm 43. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

Bu fonksiyon, pencere kapatlrken hangi ilemlerin yaplacan belirliyor. Buna gre,


programdan klrken srasyla u ilemleri gerekletiriyoruz:
1. Etiketin text parametresini Elveda zalim dnya... olarak deitiriyoruz.
2. Dmenin text parametresini Bekleyin... olarak deitiriyoruz.
3. Dmenin state parametresini disabled olarak deitirerek dmeyi baslamaz hale
getiriyoruz.
4. 2000 milisaniye (yani 2 saniye) sonra ise pencere.destroy() komutunu ileterek
pencerenin kapanmasn salyoruz.
k() fonksiyonunu tanmladktan sonra Label() ve Button() dmeleri araclyla etiket
ve dmelerimizi oluturuyoruz:
etiket = tk.Label(text='Merhaba Zalim Dnya')
etiket.pack()

dme = tk.Button(text='k', command=k)


dme.pack()

Buna gre, dmeye basldnda, command parametresinin deeri olan k() fonksiyonu
almaya balayacak ve fonksiyon gvdesinde tanmladmz ilemler gerekleecek.
Bildiiniz gibi, bir program penceresinde, o program kapatmay salayacak dmelerin
yansra, bir de en st sa (veya sol) kede program penceresini kapatan bir X dmesi
bulunur. te bu X dmesine basldnda da pencere kapanmadan nce k()
fonksiyonunun almas iin u kodu yazyoruz:
pencere.protocol('WM_DELETE_WINDOW', k)

protocol() de tpk geometry() gibi, Tk() snfnn metotlarndan biridir. Bu metodu


WM_DELETE_WINDOW argmanyla birlikte kullanarak, pencere zerindeki X dmesine
basldnda neler olacan tanmlayabiliyoruz.
Son olarak da ana dng mekanizmasn altryoruz ve penceremizi grnr hale
getiriyoruz:
pencere.mainloop()

Bu prosedrel kodlar tekrar nmze alalm:


import tkinter as tk

pencere = tk.Tk()

def k():
etiket['text'] = 'Elveda zalim dnya...'
dme['text'] = 'Bekleyin...'
dme['state'] = 'disabled'
pencere.after(2000, pencere.destroy)

etiket = tk.Label(text='Merhaba Zalim Dnya')


etiket.pack()

dme = tk.Button(text='k', command=k)


dme.pack()

43.2. Prosedrel Bir rnek 761


Python 3 iin Trke Klavuz, Srm 3

pencere.protocol('WM_DELETE_WINDOW', k)

pencere.mainloop()

En bata da sylediimiz gibi, bu kodlarda, satr sralar ok nemlidir. Mesela burada


dmeyi oluturan kodlarla pencere.protocol() kodlarnn almas iin bunlarn mutlaka
k() fonksiyonu tanmlandktan sonra yazlmas gerekir. Eer bu kodlar yle yazarsanz:
import tkinter as tk

pencere = tk.Tk()
pencere.protocol('WM_DELETE_WINDOW', k)

def k():
etiket['text'] = 'Elveda zalim dnya...'
dme['text'] = 'Bekleyin...'
dme['state'] = 'disabled'
pencere.after(2000, pencere.destroy)

etiket = tk.Label(text='Merhaba Zalim Dnya')


etiket.pack()

dme = tk.Button(text='k', command=k)


dme.pack()

pencere.mainloop()

... programnz almayacaktr.


Bu durum, programcy, istedii kod dzenini oturtmak konusunda epey kstlar. Ama
eer nesne tabanl programlama yaklamn kullanrsak kod akn belirlerken daha zgr
olabiliriz. Ayrca prosedrel yaklamda kodlar bydke programnzn orbaya dnme
ihtimali nesne tabanl programlama yaklamna gre daha fazladr. Ancak elbette nesne
tabanl programlama yaklamn kullanmak tek bana dzgn ve dzenli kod yazmann
teminat deildir. Nesne tabanl programlama yaklamn kullanarak da gayet sebze orbas
kvamnda kodlar yazabilirsiniz. En bata da sylediimiz gibi, nesne tabanl programlama bir
seenektir. Eer istemezseniz, nesne tabanl programlama yaklamn kullanmak zorunda
deilsiniz. Ama elinizde byle bir imkannz olduunu ve bakalarnn da bu yaklamdan
youn bir ekilde faydalandn bilmek ok nemlidir.

43.3 Sn Bir rnek

Bir nceki balkta Tkinteri kullanlarak prosedrel bir kod yazdk. Peki acaba yukardaki
kodlar nesne tabanl olarak nasl yazabiliriz?
Dikkatlice bakn:
import tkinter as tk

class Pencere(tk.Tk):
def __init__(self):
super().__init__()
self.protocol('WM_DELETE_WINDOW', self.k)

self.etiket = tk.Label(text='Merhaba Zalim Dnya')

762 Blm 43. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

self.etiket.pack()

self.dme = tk.Button(text='k', command=self.k)


self.dme.pack()

def k(self):
self.etiket['text'] = 'Elveda zalim dnya...'
self.dme['text'] = 'Bekleyin...'
self.dme['state'] = 'disabled'
self.after(2000, self.destroy)

pencere = Pencere()
pencere.mainloop()

Bu kodlarda grdnz btn satrlar anlayacak kadar nesne tabanl programlama bilgisine
sahipsiniz. Ama gelin biz yine de bu kodlar sizin iin tek tek ve tane tane aklayalm.
ncelikle tkinter modln tk adyla ie aktaryoruz:
import tkinter as tk

Daha sonra Pencere() adl snfmz tanmlamaya balyoruz:


class Pencere(tk.Tk):
...

Burada ncelikle Tk() snfn miras aldmza dikkat edin. Bu sayede bu snfn iindeki btn
nitelik ve metotlar kendi uygulamamz iinden arabileceiz.
Penceremiz oluur olumaz pencere zerinde bir etiket ile bir dme olmasn planlyoruz.
Pencere oluur olumaz iletilecek kodlar tanmlamak iin bir __init__() metoduna
ihtiyacmz olduunu biliyorsunuz:
class Pencere(tk.Tk):
def __init__(self):
...

Ancak kendi __init__() metodumuzu tanmlarken, Tk() snfnn kendi __init__()


metodundaki ilemleri de glgelemememiz lazm. Dolaysyla orijinal __init__() metodunu
kendi __init__() metodumuza aktarmak iin super() fonksiyonundan yararlanacaz:
class Pencere(tk.Tk):
def __init__(self):
super().__init__()

Artk taban snfn __init__() metodunu kendi tanmladmz alt snfn __init__() metodu
iinden zelletirmeye balayabiliriz. ncelikle u satr yazyoruz:
self.protocol('WM_DELETE_WINDOW', self.k)

protocol() metodunun ntanml davran, pencerenin X dmesine basldnda program


sonlandrmaktr. te biz bu ntanml davran deitirmek iin protocol() metodunu
ieren kodu tekrar tanmlyoruz ve X dmesine basldnda k() fonksiyonunun
almasn salyoruz.
Daha sonra normal bir ekilde etiketimizi ve dmemizi tanmlyoruz:

43.3. Sn Bir rnek 763


Python 3 iin Trke Klavuz, Srm 3

self.etiket = tk.Label(text='Merhaba Zalim Dnya')


self.etiket.pack()

self.dme = tk.Button(text='k', command=self.k)


self.dme.pack()

ki farkl yerde atfta bulunduumuz k() fonksiyonumuz ise yle:


def k(self):
self.etiket['text'] = 'Elveda zalim dnya...'
self.dme['text'] = 'Bekleyin...'
self.dme['state'] = 'disabled'
self.after(2000, self.destroy)

Son olarak da u kodlar yazp programmz tamamlyoruz:


pencere = Pencere()
pencere.mainloop()

Elbette zevkler ve renkler tartlmaz, ancak ben yukardaki kodlar, prosedrel kodlara gre
ok daha dzgn, dzenli, anlalr ve okunakl bulduumu, bu kodlara baktmda, program
oluturan paralarn prosedrel kodlara kyasla daha yerli yerinde olduunu dndm
sylemeden de gemeyeceim...
Eer siz aksini dnyorsanz sizi prosedrel yolu tercih etmekten alkoyan hibir eyin
olmadn da bilin. Ancak tabii ki bu, nesne tabanl programlamadan kaabileceiniz
anlamna da gelmiyor! Unutmayn, bu yaklam siz kullanmasanz da bakalar kullanyor.

43.4 oklu Miras Alma

Pythonda bir snf, ayn anda birden fazla snf da miras alabilir. Eer yazdnz bir
uygulamada birden fazla taban snftan nitelik ve metot miras almanz gerekirse bunu u
ekilde gerekletirebilirsiniz:
class Snf(taban_snf1, taban_snf2):
pass

Bu ekilde hem taban_snf1 hem de taban_snf2 de bulunan nitelik ve metotlar ayn anda
Snf adl snfa dahil olacaktr.
Ufak bir rnek verelim. Diyelim ki elimizde u snar var:
class c1:
sn1 = 'sn1'

def __init__(self):
self.n1 = 'n1'
print(self.n1)

def rn_metot1(self):
self.m1 = 'm1'
return self.m1

class c2:
sn2 = 'sn2'

764 Blm 43. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

def __init__(self):
self.n2 = 'n2'
print(self.n2)

def rn_metot2(self):
self.m2 = 'm2'
return self.m2

class c3:
sn3 = 'sn3'

def __init__(self):
self.n3 = 'n3'
print(self.n3)

def rn_metot3(self):
self.m3 = 'm3'
return self.m3

Burada farkl snf ve herbir snfn iinde de birer snf nitelii, birer __init__() metodu,
birer rnek nitelii ve birer rnek metodu gryoruz.
imdi bu snf birden taban snf olarak miras alan drdnc bir snf tanmlayalm:
class c4(c1, c2, c3):
pass

Burada, taban snf vazifesi grecek snarn adn c4 snfnn parantezleri arasna tek tek
yerletirdiimize dikkat edin. Bu ekilde c1, c2 ve c3 adl snar ayn anda miras alm
oluyoruz. te bu mekanizmaya Pythonda oklu miras alma (multiple inheritance ) ad
veriliyor.
Tek bir snf miras aldnzda hangi kurallar geerliyse, birden fazla snf miras aldnzda da
temel olarak ayn kurallar geerlidir. Ancak oklu miras almada birden fazla snf sz konusu
olduu iin, miras alnan snarn da kendi aralarnda veya baka snarla nitelik ve/veya
metot alverii yapmas halinde ortaya kabilecek beklenmedik durumlara kar dikkatli
olmalsnz. Ayrca oklu miras alma ilemi srasnda, ayn ad tayan metotlardan yalnzca
birinin miras alnacan da unutmayn.
rnein:
class c1:
sn1 = 'sn1'

def __init__(self):
self.n1 = 'n1'
print(self.n1)

def rn_metot1(self):
self.m1 = 'm1'
return self.m1

def ortak_metot(self):
self.om = 'ortak metot_c1'
return self.om

class c2:

43.4. oklu Miras Alma 765


Python 3 iin Trke Klavuz, Srm 3

sn2 = 'sn2'

def __init__(self):
self.n2 = 'n2'
print(self.n2)

def rn_metot2(self):
self.m2 = 'm2'
return self.m2

def ortak_metot(self):
self.om = 'ortak metot_c2'
return self.om

class c3:
sn3 = 'sn3'

def __init__(self):
self.n3 = 'n3'
print(self.n3)

def rn_metot3(self):
self.m3 = 'm3'
return self.m3

def ortak_metot(self):
self.om = 'ortak metot_c3'
return self.om

class c4(c1, c2, c3):


def __init__(self):
super().__init__()

Burada, ayn ad tayan __init__() ve ortak_metot() adl metotlardan yalnzca biri miras
alnacaktr. Bunlardan hangisinin miras alnacan az ok tahmin etmisinizdir. Evet, doru
bildiniz. Miras alma listesinde hangi snf nde geliyorsa onun metotlar miras alnacaktr:
s = c4()
print(s.ortak_metot())

Grdnz gibi, c4() snf nce c1 snfn miras ald iin hep c1 snfnn metotlar ncelik
kazanyor.
Eer snar class c4(c2, c3, c1): eklinde miras alsaydk, bu kez de c2 snfnn metotlar
ncelik kazanacakt.
Elbette, Pythonn sizin iin belirledii ncelik sras yerine kendi belirlediiniz ncelik srasn
da dayatabilirsiniz:
class c4(c1, c2, c3):
def __init__(self):
c2.__init__(self)

def ortak_metot(self):
return c3.ortak_metot(self)

Burada c2 snfnn __init__() metodu ile c3 snfnn ortak_metotuna miras ncelii verdik.

766 Blm 43. Nesne Tabanl Programlama (Devam)


Python 3 iin Trke Klavuz, Srm 3

43.5 Dahil Etme

Bir snftaki nitelik ve metotlar baka bir snf iinde kullanmann tek yolu ilgili snf veya
snar miras almak deildir. Hatta baz durumlarda, miras alma iyi bir yntem dahi
olmayabilir. zellikle birden fazla snfa ait nitelik ve metotlara ihtiya duyduumuzda, oklu
miras alma yntemini kullanmak yerine, dahil etme (composition ) denen yntemi tercih
edebiliriz.
Peki nedir bu dahil etme denen ey? Adndan da anlalaca gibi, dahil etme ynteminde,
taban snfn nitelik ve metotlarn miras almak yerine, alt snf iine dahil ediyoruz. Esasnda
biz bunun rneini grmtk. u kodu hatrlyorsunuz:
import tkinter as tk

class Pencere(tk.Tk):
def __init__(self):
super().__init__()
self.protocol('WM_DELETE_WINDOW', self.k)

self.etiket = tk.Label(text='Merhaba Zalim Dnya')


self.etiket.pack()

self.dme = tk.Button(text='k', command=self.k)


self.dme.pack()

def k(self):
self.etiket['text'] = 'Elveda zalim dnya...'
self.dme['text'] = 'Bekleyin...'
self.dme['state'] = 'disabled'
self.after(2000, self.destroy)

pencere = Pencere()
pencere.mainloop()

Burada ayn anda hem miras alma hem de dahil etme ynteminden yararlanyoruz. lk
nce Tk() snfn miras aldk. Bylece bu snfn nitelik ve metotlarna dorudan eriim elde
ettik. Etiket ve dme oluturmamz salayan Label() ve Button() snarn ise Pencere()
snfmz iine dahil ettik. Bylece bu snarn nitelik ve metotlarna srasyla self.etiket ve
self.dme adlar altnda eriim kazandk.
Miras alma ve dahil etme yntemleri arasnda tercih yaparken genel yaklammz u olacak:
Eer yazdmz uygulama, bir baka snfn trevi ise, o snf miras alacaz. Ama eer bir
snf, yazdmz uygulamann bir paras ise o snf uygulamamza dahil edeceiz.
Yani mesela yukardaki rnekte temel olarak yaptmz ey bir uygulama penceresi
tasarlamaktr. Dolaysyla uygulama penceremiz, tk.Tk() snfnn dorudan bir trevidir.
O yzden bu snf miras almay tercih ediyoruz.
Pencere zerine etiket ve dme yerletirmemizi salayan Label() ve Button() snar ise,
uygulama penceresinin birer parasdr. Dolaysyla bu snar uygulamamz iine dahil
ediyoruz.
Yukarda anlattmz iki farkl iliki tr olma ilikisi (is-a relationship ) ve sahiplik ilikisi
(has-a relationship ) olarak adlandrlabilir. Olma ilikisinde, bir snf tekinin trevidir. Sahip
olma ilikisinde ise bir snf teki snfn parasdr. Eer iki snf arasnda olma ilikisi varsa
miras alma yntemini kullanyoruz. Ama eer iki snf arasnda sahiplik ilikisi varsa dahil

43.5. Dahil Etme 767


Python 3 iin Trke Klavuz, Srm 3

etme yntemini kullanyoruz.

Dipnotlar:

768 Blm 43. Nesne Tabanl Programlama (Devam)


BLM 44

Nesne Tabanl Programlama (Devam)

Nesne tabanl programlamaya ilikin bu son blmde nceki derslerde incelemeye frsat
bulamadmz ileri dzey konulardan sz edeceiz.

44.1 na, lklendirme ve Sonlandrma

Pythonda bir snfn mr aamadan oluur:


1. na (Construction )
2. lklendirme (initialization )
3. Sonlandrma (destruction )
Biz bundan nceki derslerimizde ilklendirme srecinin nasl yrdn grmtk. Bu
dersimizde ise, ilklendirme srecine de tekrar deinmekle birlikte, zellikle ina ve
sonlandrma srelerini ele alacaz.
nceki derslerimizden de bildiimiz gibi, Pythonda bir snf ilklendirmek iin __init__()
adl bir metottan yararlanyoruz. Ancak, adnn aksine, ilklendirme, snarn oluturulmasna
ilikin ilk basamak deildir. Python, bir snfn ilklendirilmesinden nce o snf ina eder.
Bu ina ileminden sorumlu metodun ad ise __new__()dur. Gelin bu metodu yakndan
tanmaya alalm.

44.1.1 __new__() Metodu

Bildiiniz gibi, Pythonda basit bir snf u ekilde tanmlyoruz:


class Snf():
def __init__(self):
print('merhaba snf!')

Burada __init__() metodu, snfmz rneklenir rneklenmez hangi ilemlerin yaplacan


gsteriyor. Yani mesela snf = Snf() gibi bir kod yardmyla Snf() adl snf
rneklediimiz anda ne olacan bu __init__() metodu iinde tanmlyoruz:
>>> # Yukardaki kodlarn `snf.py` adl bir dosyada olduunu varsayalm
>>> import snf
>>> snf = snf.Snf()

merhaba snf!

769
Python 3 iin Trke Klavuz, Srm 3

Grdnz gibi, tam da __init__() metodunda tanmladmz ekilde, snfmz


rneklediimiz anda ekrana merhaba snf kts verildi.
Ancak yukarda da belirttiimiz gibi, bir snf rneklendiinde alan ilk metot aslnda
__init__() deildir. Python bu srete alttan alta __new__() adl baka bir metodu altrr.
Gelin bunu kantlayalm:
class Snf():
def __new__(cls):
pass

def __init__(self):
print('merhaba snf')

Bu snf rneklediinizde, bir nceki kodlarn aksine, ekrana merhaba snf yazs kt olarak
verilmeyecektir. te bunun sebebi, Pythonn ntanml __new__() metodunun zerine yazp,
o metodun ilevselliini ortadan kaldrm olmanzdr. Eer __new__() metodunun ntanml
davrann taklit etmek isterseniz yukardaki kodlar u ekilde yazmalsnz:
class Snf():
def __new__(cls, *args, **kwargs):
return object.__new__(cls, *args, **kwargs)

def __init__(self):
print('merhaba snf')

Burada yaptmz eyin aslnda temel olarak basit bir miras alma ileminden ibaret olduunu
gryor olmalsnz. Bildiiniz gibi, Pythondaki btn snar, eer baka bir snf miras
olarak almyorlarsa, otomatik olarak object snfn miras alrlar. Yani aslnda yukardaki snf
tanmn Python yle grr:
class Snf(object):
...

Burada object taban snf olmu oluyor. Bu taban snfn __new__() metodunun sahip olduu
ilevsellii Snf adl alt snfa aktarabilmek iin taban snf kendi __new__() metodumuz
iinde aryoruz:
class Snf():
def __new__(cls, *args, **kwargs):
return object.__new__(cls, *args, **kwargs)

te eer bir snfn ina edilme srecinin nasl ileyeceini kontrol etmek isterseniz bu
__new__() metodunun zerine yazarak metodu deiiklie uratabilirsiniz:
class Snf():
def __new__(cls, *args, **kwargs):
print('Yeni snf ina edilirken ltfen bekleyiniz...')
return object.__new__(cls, *args, **kwargs)

def __init__(self):
print('merhaba snf')

Ancak bu noktada unu belirtmeden de gemeyelim. __new__() metodu, sk sk muhatap


olmanz gereken bir metot deil. __new__() metodunu kullanarak yapacanz pek ok eyi
aslnda dorudan __init__() metodu araclyla da yapabilirsiniz.

770 Blm 44. Nesne Tabanl Programlama (Devam)


BLM 45

Paketler

Uyar: Bu makale youn bir ekilde gelitirilmekte, ierii sk sk gncellenmektedir.

Birka blm nce, Pythonn belkemii olduunu sylediimiz modller konusundan sz


etmitik. Bu blmde de yine modllerle balantl bir konuyu ele alacaz. Konumuz
Pythonda paketler.

45.1 Paket Nedir?

ncelikle paketin ne demek olduunu anlamaya alarak balayalm. Pythonda bir dizin
yaps iinde bir araya getirilen, birbiriyle balantl modllere paket ad verilir. Dolaysyla
paketler modllerden oluur.
Python programlama dilinde paketler hem geni bir yer tutar, hem de byk bir nem tar.
Hatta Python bilmenin paketleri bilmek demek olduunu sylersek ok da abartm olmayz.
Mesela Pythonla web programlar yazmak iin kullanlan en gzde aralardan biri olan django
web ats, aslnda birtakm nc ahs modllerinin bir paket yaps iinde bir araya
getirilmi halinden baka bir ey deildir. Ayn ekilde Pythonla Android ve iOS zerinde
alabilecek programlar yazmak isterseniz kivy adl bir baka Python paketini renmeniz
gerekir. Python programlama dilini kullanarak grak arayzl yazlmlar gelitirmemizi
salayan tkinter ise standart ktphanede bulunan pek ok paketten yalnzca bir tanesidir.
Etrafta django, kivy ve tkinter gibi pek ok kullanl paket bulabilirsiniz. Mesela standart
ktphanede bulunan sqlite3, Sqlite veritabanlar zerinde almamza imkan tanyan eitli
modlleri iinde barndran bir Python paketidir. Yine standart ktphanede bulunan urllib
paketi yardmyla internet adresleri (URLler) zerinde eitli ilemler yapabilirsiniz. Python
kurulum dizini iindeki Lib klasr altnda pek ok standart Python paketi grebilirsiniz.
Peki modllerle paketleri birbirinden ayran ey nedir?
ncelikle, paketler modllere kyasla ok daha kapsaml bir yapdr. Zira bir paket iinde
(genellikle) birden fazla modl bulunur. rnein standart ktphanede bulunan ve tek
bir os.py dosyasndan oluan os bir modlken, iinde pek ok farkl modl barndran
collections bir pakettir. Tek bir dosyadan olutuu ve bir dizin yaps iinde yer almad
iin bir modlden ie aktarma ilemi gerekletirmek son derece kolaydr. Paketlerden ie
aktarma yaparken uymamz gereken kurallar ise haliyle biraz daha karmaktr.
kincisi, btn paketler ayn zamanda birer modldr, ancak btn modller birer paket
deildir. rnein venv paketinden bahsederken venv modl demek yanl olmaz. Ancak

771
Python 3 iin Trke Klavuz, Srm 3

os modlnden bahsederken os paketi demek biraz abes kaacaktr.


ncs, paketlerin __path__ adl zel bir nitelii bulunur. Modllerde ise bu nitelik
bulunmaz. rnein:
>>> import os
>>> os.__path__

AttributeError: 'module' object has no attribute '__path__'

os bir modl olduu iin, __path__ niteliine sahip deildir. Bir de json paketine bakalm:
>>> import json
>>> json.__path__

json ise bir paket olduu iin, __path__ niteliine sahiptir. Birazdan bu niteliin ne ie
yaradn anlatacaz. Ama ondan nce renmeniz gereken baka eyler var.

45.2 Paket Trleri

Tpk fonksiyonlarda ve modllerde olduu gibi, paketlerin de trleri vardr. Paketleri,


kaynaklarna gre ikiye ayrabiliriz:
Standart Paketler
nc ahs Paketleri
Bu trlerin ne anlama geldiini isimlerine bakarak rahatlkla anlayabiliyoruz. Ama gelin
isterseniz bunlar ksaca gzden geirelim.
ncelikle standart paketlerden balayalm.

45.2.1 Standart Paketler

Standart paketler, Pythonn standart ktphanesinde bulunan paketlerdir. Tpk gml


fonksiyonlar ve standart modller gibi, standart paketler de dilin bir paras olduklarndan,
bunlara eriebilmek iin herhangi bir ek yazlm indirip kurmamza gerek kalmaz; bu
paketler her an emrimize amadedir. Standart paketlere Python kurulum dizini iindeki Lib
klasrnden eriebilirsiniz. Bir standart paketin tam olarak hangi konumda bulunduunu
renmek iin ise ilgili paketin __path__ niteliini sorgulayabilirsiniz:
>>> import urllib
>>> urllib.__path__

Eer sorguladnz eyin bir __path__ nitelii yoksa, paket sandnz o ey, aslnda bir paket
deildir. rnein:
>>> import subprocess
>>> subprocess.__path__

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__path__'

772 Blm 45. Paketler


Python 3 iin Trke Klavuz, Srm 3

nk, bildiiniz gibi, paketlerin aksine, modllerin __path__ adl bir nitelii bulunmaz.
subprocess de bir paket deil, modl olduu iin __path__ sorgusu hata verecektir.
Bir paketin __path__ niteliini sorguladnzda ktda hangi dizini gryorsanz, o
paketin bilgisayardaki konumu odur. Mesela yukarda adn andmz urllib paketinin
__path__ niteliini sorgulayp, karmza kan klasre gidelim. Paket dizininin iini
atmzda karmza u dosyalar kacak:
error.py
parse.py
request.py
response.py
robotparser.py
__init__.py

Daha nce de dediimiz gibi, paketler modllerden oluur. te urllib paketi de yukarda
ismini grdmz modllerin birleiminden oluuyor. Python kurulum dizini iindeki Lib
klasr altnda yer alan paketleri inceleyerek, hangi paketin hangi modllerden olutuunu
kendiniz de grebilirsiniz.

45.2.2 nc ahs Paketleri

Pythonda standart paketlerin dnda bir de nc ahs paketleri vardr. Bunlar Python
gelitiricileri haricindeki kiilerce yazlp kullanmmza sunulmu aralardr. Bu paketler,
standart paketlerin aksine dilin bir paras olmadndan, bu paketleri kullanabilmek iin
ncelikle bunlar bilgisayarmza kurmamz gerekir. Mesela django, kivy ve ilk derslerimizden
birinde bahsettiimiz cx_freeze birer nc ahs paketidir.
Peki bu nc ahs paketlerini nereden bulabiliriz?
Hatrlarsanz Modller konusunu ilerken nc ahs Modllerinden de sz etmitik.
nc ahs modllerini bulabileceimiz balca kaynan https://pypi.python.org/pypi
adresi olduunu ve buradan 60.000in zerinde nc ahs Python modlne
ulaabileceimizi de ifade etmitik. te orada bahsettiimiz nc ahs modlleri, aslnda
birer pakettir. Zira nc ahs modlleri ounlukla birer paket biiminde sunulur.
Dolaysyla nc ahs modllerine nereden ve nasl ulayorsak, nc ahs paketlerine
de ayn yerden ve ayn ekilde ulaabiliriz. Ayrca bir nc ahs paketini kurmadan nce,
ilgili paketin yardm dosyalarn veya websitesini incelemekte de fayda var. nk baz nc
ahs modllerini kurabilmek iin birtakm zel gereksinimleri yerine getirmeniz gerekiyor
olabilir. Bu tr bilgilere de ancak ilgili paketi gelitiren kii veya ekibin websitesinden
ulaabilirsiniz.
Bir nc ahs paketinin https://pypi.python.org/pypi adresindeki adn rendikten sonra,
bu paketi u komutla kurabilirsiniz:
pip3 install paket_ad

Mesela restructuredText biimli metin dosyalarndan k ve kullanl belgeler retmemizi


salayan sphinx paketi PyPI sitesinde bulunuyor. Dolaysyla bu paketi kurmak iin u komutu
verebiliriz:
pip3 install sphinx

Elbette, eer bir GNU/Linux datm kullanyorsanz, bu komutu root haklaryla altrmanz
gerektiini sylememe herhalde gerek yok:

45.2. Paket Trleri 773


Python 3 iin Trke Klavuz, Srm 3

sudo pip3 install sphinx

pip3 adl yazlm, sphinx paketinin btn dosyalarn PyPI sitesinden ekip otomatik olarak
bilgisayarmza kuracaktr.
Bir nc ahs paketini pip3 komutuyla kurmak yerine elle kurmay da tercih
edebilirsiniz. rnek olarak bu defa django paketini alalm. Bu paketin en son srmn
https://github.com/django/django/archive/master.tar.gz adresinden indirebilirsiniz. Ayrca
arzu ederseniz https://www.djangoproject.com adresine urayarak bu modln resmi
websitesine de gzatabilirsiniz.
ndirdiiniz tar.gz uzantl sktrlm dosyay atnzda karsnza pek ok dizin ve bu
dizinlerin iinde de pek ok Python dosyas kacak. Django, geni kapsaml nc ahs
paketlerine gzel bir rnektir.
Django paketini ap django-master adl dizinin iine girdiinizde, orada setup.py adl
bir dosya greceksiniz. te pip3 komutu yerine, bu dosyay kullanarak da bu paketi
bilgisayarmza kurabiliriz.
Dikkatlice bakn:
python3 setup.py install

Bu komutta iki nemli unsur var. Birincisi, komutu altrdmz Python srm.
Unutmayn, bir Python paketini hangi Python srm ile kurarsanz, o paketi o srm
ile kullanabilirsiniz. Ben yukardaki komutta, sizin Python srmnz balatan komutun
python3 olduunu varsaydm. Eer siz Python balatmak iin veya baka Python
programlarn altrmak iin farkl bir komut kullanyorsanz, setup.py dosyasn da o
komutla altracaksnz. Neticede setup.py de sradan bir Python programdr. Bu program
install parametresi ile birlikte altrarak Django paketini sisteminize kurmu oluyorsunuz.
Kurulum tamamlandktan sonra, kurulumun baarl olup olmadn test etmek iin Python
komut satrnda u komutu verin:
>>> import django

Eer herhangi bir kt verilmeden alt satra geildiyse, bir nc ahs paketi olan
django yu bilgisayarnza baaryla kurmusunuz demektir. Bu nc ahs modln
nasl kullanacanz renmek iin internet zerindeki saysz makaleden ve kitaptan
yararlanabilirsiniz.

45.3 Paketlerin e Aktarlmas

Modllerle paketler arasndaki nemli bir fark, paketlerin modllere kyasla daha karmak
bir yapda olmasdr. Yalnzca tek bir dosyadan oluan modllerin bu basit yapsndan tr,
bir modlden nitelik veya metot ie aktarmak ok kolaydr. Mesela bir modl olan os u u
ekilde ie aktarabiliriz:
>>> import os

Eer os modlnden name niteliini almak istersek u komutu kullanabiliriz:


>>> from os import name

774 Blm 45. Paketler


Python 3 iin Trke Klavuz, Srm 3

os modl iindeki btn nitelik ve metotlar ie aktarmak istediimizde yldzl ie aktarma


ynteminden yararlanabiliriz:
>>> from os import *

Veya bu modl iindeki bir nitelii veya metodu baka bir isim altnda da ie aktarabiliriz:
>>> from os import execv as exe

Gelelim paketlere...

45.3.1 import paket

Mesela urllib paketini ele alalm. Tpk os modlnde yaptmz gibi, urllib modln de u
ekilde ie aktarabiliriz:
>>> import urllib

Ancak os modlnn aksine, urllib paketini ie aktardmzda mevcut isim alanna herhangi
bir nitelik veya metot otomatik olarak aktarlmaz. rnein os modln ie aktardmzda
bu modln ieriinin, os neki altnda mevcut isim alanna dkldn biliyoruz:
>>> dir(os)

Grdnz gibi, modl ierii kullanlabilir durumda. Listedeki nitelik ve metotlara os neki
ile eriebiliriz:
>>> os.name
>>> os.listdir(os.getcwd())

gibi...
Ancak import os komutunun aksine, import urllib komutu, paket ieriini otomatik olarak
mevcut isim alanna aktarmaz:
>>> import urllib
>>> dir(urllib)

['__builtins__', '__cached__', '__doc__', '__file__',


'__loader__', '__name__', '__package__', '__path__',
'__spec__']

Grdnz gibi listede yalnzca standart metot ve nitelikler var. Bu listede mesela paket
ieriinde olduunu bildiimiz error.py, parse.py, request.py, response.py ve robotparser.py
gibi modlleri gremiyoruz. Eer paket iinde bulunan belirli bir modl ie aktarmak
istiyorsak bunu ak ak belirtmeliyiz. Nasl m? Grelim...

45.3.2 import paket.modl

Mesela urllib paketinden request modln ie aktarmak istersek u komutu yazacaz:


>>> import urllib.request

Bu modl yukardaki ekilde ie aktardmzda, modl iindeki nitelik ve metotlara


urllib.request nekiyle eriebiliriz:

45.3. Paketlerin e Aktarlmas 775


Python 3 iin Trke Klavuz, Srm 3

>>> urllib.request.urlopen('http://www.istihza.com')

45.3.3 from paket import modl

Yukarda olduu gibi, urllib paketi iindeki request modln import paket.modl gibi
bir komutla ie aktardmzda ilgili modln btn nitelik ve metotlar urllib.request ismi
altnda ie aktarldndan, urllib paketi iindeki request modlnn nitelik ve metotlarna
ulaabilmek iin her defasnda urllib.request nekini kullanmamz gerekir. Eer her
defasnda uzun uzun urllib.request yazmak istemiyorsanz paket iindeki modl u ekilde
ie aktarabilirsiniz:
>>> from urllib import request

Bylece request modlnn nitelik ve metotlarna yalnzca request nekiyle eriebilirsiniz:


>>> request.urlopen('http://www.istihza.com')

45.3.4 from paket.modl import nitelik_veya_metot

Peki bir paket iinde yer alan herhangi bir modl iindeki nitelik ve metotlara neksiz olarak
erimek istersek ne yapacaz? Python bize bu isteimizi yerine getirmemizi salayacak bir
yol da sunar.
Dikkatlice bakn:
from urllib.request import urlopen

Bu ekilde urllib paketi iindeki request modlnden urlopen adl metodu dorudan ie
aktarm olduk. Dolaysyla bu metodu dmdz kullanabiliriz:
>>> urlopen('http://www.istihza.com')

Ancak, modller konusunu ilerken neksiz aktarmaya ilikin sylediklerimizin paketler iin
de geerli olduunu aklmzdan karmyoruz.

45.3.5 from paket.modl import *

Eer bir paket iindeki bir modln btn nitelik ve metotlarn mevcut isim alanna olduu
gibi aktarmak isterseniz u ie aktarma yntemini kullanabilirsiniz:
>>> from paket.modl import *

Bu bilgiyi urllib modlne uygulayalm:


>>> from urllib.request import *

Bu ekilde urllib paketi iindeki request modlnn btn nitelik ve metotlarn dorudan
mevcut isim alanna aktarm olduk. Bu yntemin byk bir rahatlk sunmakla birlikte nemli
dezavantajlara da sahip olduunu gayet iyi bildiinizden eminim.

776 Blm 45. Paketler


Python 3 iin Trke Klavuz, Srm 3

45.4 Kendi Oluturduumuz Paketler

Buraya kadar hep bakalarnn yazd, hazr paketlerden sz ettik. Bu sayede bir Python
paketinin yap olarak neye benzediini ve nasl kullanlacan kabataslak da olsa anlam
olduk. Elbette biz sadece bakalarnn yazd paketleri kullanmayacaz. Bir de bizim kendi
yazdmz Python paketleri olacak.
Kendi oluturduumuz paketler, ad zerinde, kendi kendimize yazp meydana getirdiimiz
paketlerdir. Bu paketleri iyice gelitirdikten ve bakalar iin de yararl olabilecek hale
getirdikten sonra, istersek https://pypi.python.org/pypi adresindeki nc ahs paket
deposuna ykleyebiliriz. Bylece kendi gelitirdiimiz paketler de, nc ahs Python
paketleri arasna girmi olur...
te bu blmde, bu tr paketleri nasl yazacamz ele alacaz.

45.4.1 Paket Oluturmak

Bir Python program yazdnz dnn. Programnz ilk yazmaya balarken doal olarak
programnz tek bir dosyadan oluacaktr. Ancak elbette programnz bydke, btn
kodlar tek bir dosyaya sktrmak yerine, farkl ilevleri farkl dosyalar iinde tanmlamann
daha mantkl olduunu farkedeceksiniz. Mesela programn grak arayz ksmn bir dosyada
tanmlarken, dmelere, menlere balayacanz ilevleri bir baka dosyada tanmlamak
isteyebilirsiniz. Programnzn gerekletirdii ilemleri kk, mantkl birimlere blp
bunlar farkl modllere tamanz, programnz ok daha rahat bir ekilde idare etmenizi
salayacaktr. Yani, yazdnz program birka modle blp, bunlar bir paket yaps iinde
sunmanz hem kendiniz asndan, hem de kodlarnz okuyan bakalar asndan ileri epey
kolaylatracaktr.
Pythonda bir paket oluturmak son derece kolaydr. Program kodlarn ieren .py dosyasn
bir klasr iine koyduunuz anda, o klasrn adn tayan bir paket meydana getirmi
olursunuz.
Mesela bir sipari takip program yazdmz dnelim. Ana klasrmzn adn siparistakip
koyalm. Bu klasr iinde de komut.py, veritabani.py ve siparis.py adl modller olsun. Yani
yle bir dosya-dizin yaps oluturalm:
+ siparistakip
|__ siparis.py
|__ komut.py
|__ veritabani.py

te bu ekilde basit bir dosya-dizin yaps oluturduumuzda, siparistakip adl bir Python
paketi meydana getirmi oluyoruz1 .
Gelin isterseniz, siparistakip dizininin gerekten bir paket olduunu teyit edelim.
ncelikle paketimizi ie aktaralm. Bunun iin siparistakip dizininin bulunduu klasrde u
komutu verelim:

1
Daha nce Pythonn 2.x srmlerini kullanm olanlar, bu yapnn bir paket oluturmak iin yeterli olmadn
dnebilir. nk Pythonn 2.x srmlerinde bir paket oluturabilmek iin, siparistakip dizininin iinde
__init__.py adl bir dosya daha oluturmamz gerekiyordu. Ancak Python3te bu zorunluluk ortadan kaldrld. Eer
bu sylediimiz eyin ne anlama geldiini bilmiyorsanz, bu uyary grmezden gelip yolunuza devam edebilirsiniz.

45.4. Kendi Oluturduumuz Paketler 777


Python 3 iin Trke Klavuz, Srm 3

>>> import siparistakip

imdi paket ieriini kontrol edelim:


>>> dir(siparistakip)

['__doc__', '__loader__', '__name__',


'__package__', '__path__', '__spec__']

Grdnz gibi, listede __path__ adl bir nitelik var. Bu niteliin yalnzca paketlerde
bulunduunu biliyorsunuz. Demek ki siparistakip gerekten de bir Python paketiymi. Bunun
dnda, listede grdnz __package__ niteliini kullanarak da bir modln paket olup
olmadn kontrol edebilirsiniz:
>>> siparistakip.__package__

'siparistakip'

Eer test ettiimiz modl bir paketse, __package__ nitelii bize bir paket ad verecektir. Yok
eer test ettiimiz modl bir paket deil de alelade bir modlse, __package__ nitelii bo bir
karakter dizisi dndrecektir. Mesela os modlnn bir paket olmadn biliyoruz:
>>> import os
>>> os.__package__

''

Grdnz gibi, bu modln __package__ nitelii bo bir karakter dizisi. Ayrca bu modl bir
paket olmad iin, __path__ adl bir nitelik de barndrmyor:
>>> os.__path__

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute '__path__'

Dolaysyla btn iaretler, gerekten de siparistakip adl bir paket oluturduumuzu


gsteriyor...

45.4.2 e Aktarma lemleri

Standart paketleri anlatrken, bu paketlerin her konumdan ie aktarlabileceini sylemitik.


Ayn ey nc ahs paketleri iin de geerlidir. nk gerek Python gelitiricileri, gerekse
nc ahs paketleri gelitirenler, bu paketleri bize sunarken bunlar Pythonn sys.path
ktsna eklemilerdir. O yzden standart ve nc ahs paketlerini ie aktarrken sorun
yaamayz.
Ancak tabii ki kendi yazdmz paketler sys.path listesine ekli olmad iin, bunlar ie
aktarrken baz noktalara dikkat etmeniz gerekir.
Mesela masastnde u yapya sahip bir paket oluturalm:
+ paket
|__ modul1.py
|__ modul2.py
|__ modul3.py

778 Blm 45. Paketler


Python 3 iin Trke Klavuz, Srm 3

+ altdizin
|__altmodul1.py
|__altmodul2.py

Bu dizinde dosya ierikleri yle olsun:


modul1.py :
isim1 = 'modul1'
print(isim1)

modul2.py :
isim2 = 'modul2'
print(isim2)

modul3.py :
isim3 = 'modul3'
print(isim3)

altmodul1.py :
altisim1 = 'altmodul1'
print(altisim1)

altmodul2.py :
altisim2 = 'altmodul2'
print(altisim2)

imdi paket adl dizinin bulunduu klasrde bir etkileimli kabuk oturumu aalm. Yalnz bu
oturumu paket dizinin iinde deil, bir st dizinde aacaksnz. Yani o anda bulunduunuz
dizinde dir veya ls komutu verdiinizde paket adl dizini gryor olmanz lazm... Eer dir
veya ls komutunun ktsnda altdizin adl dizini gryorsanz yanl yerdesiniz demektir.
Hemen bir st dizine gidin.
Bulunduumuz konumda u komutu verelim:
>>> import paket

Eer hibir kt almadan bir alt satra getiyseniz her ey yolunda demektir. Eer bir hata
mesaj gryorsanz, etkileimli kabuk oturumunu yanl konumda amsnzdr. Oturumu
doru konumda ap tekrar gelin...
Standart paketlerde ve nc ahs paketlerinde grdmz gibi, bir paketi yukardaki
ekilde ie aktardmzda, o pakete ait herhangi bir modl veya nitelik otomatik olarak ie
aktarlmyor. dir(paket) komutu verdiinizde yalnzca standart niteliklerin ie aktarldn
greceksiniz:
>>> dir(paket)

['__doc__', '__loader__', '__name__',


'__package__', '__path__', '__spec__']

Grdnz gibi, oluturduumuz paket, bir Python paketinin sahip olmas gereken btn
niteliklere sahip.
imdi bu paket iindeki modul1 adl modl ie aktaralm:

45.4. Kendi Oluturduumuz Paketler 779


Python 3 iin Trke Klavuz, Srm 3

>>> from paket import modul1

modul1

Bylece modul1 adl modln iindeki deikenin deerini alm olduk. Paket iindeki teki
modlleri de ayn ekilde ie aktarabilirsiniz:
>>> from paket import modul2

modul2

>>> from paket import modul3

modul3

Peki ya mesela modul1 iindeki isim1 deikenini almak istersek ne yapacaz?


Dikkatlice bakn:
>>> from paket.modul1 import isim1

modul1

Grdnz gibi, paket iindeki modul1 modlnn isim1 niteliini baaryla aldk. rnek
olmas asndan tekileri de alalm:
>>> from paket.modul2 import isim2

modul2

>>> from paket.modul3 import isim3

modul3

Buradaki temel mant kavradnz zannediyorum. Standart modlleri incelerken


bahsettiimiz ie aktarma yntemlerini tek tek yukardaki yapya uygulayarak, buraya kadar
anlattklarmz anlayp anlamadnz test edebilirsiniz. Dilerseniz pratik yapmak asndan
bir de altdizin iindeki modllere uzanalm.
ncelikle altdizin i ie aktaralm:
>>> import paket.altdizin

Bu ekilde paket adl paketin altdizin adl alt dizinini ie aktarm olduk. Artk bu alt dizin
iindeki modllere ve onlarn niteliklerine eriebiliriz. Mesela paket adl paketin altdizin adl
alt dizini iindeki altmodul1 adl modln altisim1 niteliini alalm:
>>> paket.altdizin.altmodul1.altisim1

'altmodul1'

Grdnz gibi, altisim1 niteliine erimek iin uzun bir yol gitmemiz gerekiyor. Bu yolu
ksaltmak isterseniz modl u ekilde ie aktarabilirsiniz:
>>> from paket.altdizin import altmodul1

Artk altmodul1 in niteliklerine yalnzca altmodul1 nekiyle ulaabilirsiniz:

780 Blm 45. Paketler


Python 3 iin Trke Klavuz, Srm 3

>>> altmodul1.altisim1

'altmodul1'

Hatta dorudan altisim1 niteliinin kendisini de alabilirsiniz:


>>> from paket.altdizin.altmodul1 import altisim1
>>> altisim1

'altmodul1'

Grdnz gibi, Pythonn ie aktarma mant gayet basit. Bulunduunuz konumdan


itibaren, alt dizin ve modl adlarn srasyla kullanarak ve bunlar birbiriyle nokta iareti ile
birletirerek her bir modle ve modl iindeki nitelie eriebiliyoruz.

45.4.3 e Aktarma Mant

Yukardaki rneklerden grdnz gibi, Pythonn ie aktarma mekanizmas gayet basit bir
ekilde iliyor. Ancak yine de bu durum sizin rehavete kaplmanza yol amasn. Zira kimi
zaman bu mekanizma hi beklemediiniz durumlarn ortaya kmasna da yol aabilir.
Pythonda paketler zerinde alrken, Python programlama dilinin paketleri ie aktarma
mekanizmasn ok iyi anlam olmalsnz. Eer bu mekanizmay hakkyla anlamadan paket
yapmaya kalkrsanz, Pythonn ie aktarma srasnda verebilecei srpriz hatalar size sa
ba yoldurabilir. te bu blmde Pythonn paket ie aktarma mant zerine eilerek,
engebeli yzeyleri nasl aabileceimizi anlamaya alacaz.

e Aktarma leminin Konumu

Pythonda herhangi bir ie aktarma ilemi yapacamz zaman, unutmamamz gereken en


nemli konu, Pythonn btn ie aktarma ilemlerini tek bir konumdan gerekletirdii
gereidir. Bunun ne demek olduunu anlamak iin ok basit bir rnek verelim.
Yukarda yle bir paket yaps oluturmutuk:
+ paket
|__ modul1.py
|__ modul2.py
|__ modul3.py
+ altdizin
|__altmodul1.py
|__altmodul2.py

Burada altmodul2.py dosyasnn iine unu yazalm:


import altmodul1

Yani bu dosya ile ayn dizinde bulunan altmodul1.py dosyasn, altmodul2.py dosyas iinden
bir modl olarak ie aktaralm.
imdi, daha nce yaptmz gibi, paket adl dizinin bulunduu klasrde bir etkileimli kabuk
oturumu aalm ve u komutu yazalm:
>>> from paket.altdizin import altmodul2

45.4. Kendi Oluturduumuz Paketler 781


Python 3 iin Trke Klavuz, Srm 3

Bu komut bize yle bir hata mesaj verecek:


ImportError: No module named 'altmodul1'

Bu hatann sebebi, Pythonn altmodul1 adl modl bulamyor olmasdr. Halbuki bu modl,
altmodul2 ile ayn dizinde bulunuyor. O halde acaba Python bu modl neden bulamyor?
Bunu anlamak iin yle bir deneme yapalm:
imdi altmodul1.py ve altmodul2.py dosyalarnn bulunduu konumda bir etkileimli kabuk
oturumu balatn ve u komutu verin:
>>> import altmodul2

Grdnz gibi, bu defa Python herhangi bir hata mesaj vermeden, impport altmodul1
komutuyla altmodul2.py dosyas iinden ardmz altmodul1 modlnn ieriini
alabildi. Peki ama neden?
Bata da sylediimiz gibi, Python btn aktarma ilemlerini tek bir konumdan yapar.
Yani eer siz bir modl st dizinden ie aktardysanz, o st dizinin ad paket iindeki
btn aktarmalara nek olarak eklenecektir. Dolaysyla paket adl dizinin bulunduu
konumdan altdizin iindeki altmodul2.py dosyasn ardnzda, altmodul2.py iindeki
import altmodul1 komutu, altmodul1.py dosyasn bulamayacaktr. Ama siz altmodul2.py
dosyasn kendi dizini iinden ardnzda, import altmodul1 komutu, ayn dizin iindeki
altmodul1.py dosyasn bulabilecektir.
Bu okuduklarnz ilk bakta size ok karmakm gibi gelebilir, ama aslnda biraz dikkat
ederseniz bu sistemin hi de yle karmak olmadn, aksine son derece mantkl olduunu
greceksiniz.
Durumu daha da netletirmek iin yle bir ey yapalm:
altmodul2.py dosyasn ap, import altmodul1 komutunu yle yazalm:
from paket.altdizin import altmodul1

Bu deiiklii kaydettikten sonra tekrar paket dizininin bulunduu konumda bir oturum ap
u komutu verelim:
>>> from paket.altdizin import altmodul2

te bu kez komutumuz baaryla alt ve altmodul1 modln bulabildi...


imdi de altmodul1.py ve altmodul2.py dosyalarnn bulunduu konuma tekrar dnp
burada yine bir etkileimli kabuk oturumu balatalm ve daha nce verdiimiz u komutu
tekrar verelim:
>>> import altmodul2

O da ne! Geen sefer hatasz alan kod bu defa hata verdi:


ImportError: No module named 'paket'

Grdnz gibi, modl ie aktardmz konumdan tr Python bu kez de paket adl


paketi bulamyor.
Birazdan btn bu sorunlarn kesin zmn vereceiz. Ama ondan nce baka bir konudan
sz edelim.

782 Blm 45. Paketler


Python 3 iin Trke Klavuz, Srm 3

Bal e Aktarma

Dediimiz gibi, bir ie aktarma ileminin baarl olabilmesi, o ie aktarma ileminin yapld
konumun neresi olduuna ve paket iinde bulunan teki modllerdeki ie aktarmalarn
nasl yazldna baldr. Yani mesela normalde ayn konumda bulunan iki modl birbirini
yalnzca import modl_ad gibi bir komutla ie aktarabilecekken, eer bu modller st dizinin
bulunduu konumdan arlyorsa, ie aktarma baarsz olabilir. Bunun bir rneini yukarda
grmtk. altdizin iinde bulunan altmodul1.py dosyasn, ayn dizindeki altmodul2.py
dosyasndan ie aktarmak iin altmodul2.py dosyasna import altmodul1 yazdmzda,
ana paket dizininin bulunduu konumdan altdizin iindeki altmodul2.py dosyasn from
paket.altdizin import altmodul2 gibi bir komut ile ie aktarma giriimimiz baarszla
uruyordu. Pythonn ilgili modl bulabilmesini salamak iin, altmodul2.py dosyasna
import altmodul1 yazmak yerine from paket.altdizin import altmodul1 yazmtk. te
ayn eyi bal ie aktarma (relative import ) denen bir mekanizma yardmyla da
gerekletirebiliriz.
Bu mekanizmada ie aktarma ilemi, ie aktaran modln bulunduu konuma gre
gerekleir. Bir rnek verelim...
altmodul2.py dosyasna import altmodul1 veya from paket.altdizin import altmodul1
yerine unu yazalm:
from . import altmodul1

Burada from kelimesinden sonra gelen nokta (.), ie aktaran modlle ayn dizine atfta
bulunuyor. Yani bu ekilde altmodul2.py nin bulunduu dizine atfta bulunmu, bylece
bu dizinde bulunan altmodul1 adl modl ie aktarabilmi olduk. paket dizininden, hatta
altdizin dizininden yaplacak ie aktarma ilemleri bu komut sayesinde baarl olacaktr.
Dediimiz gibi, orada . iareti, ie aktaran modlle ayn dizini temsil ediyor. Eer oraya
yan yana iki nokta (..) koyacak olursanz, bir st dizine atfta bulunabilirsiniz. Mesela bir
st dizinde bulunan modul3.py dosyasn altmodul2.py veya altmodul1.py dosyasndan ie
aktarmak isterseniz, bu dosyalarn herhangi birine u kodu yazabilirsiniz:
from .. import modul3

nokta yan yana koyduunuzda ise (...) iki st dizine atfta bulunmu olursunuz. Ancak bu
ekilde paketin dna kamayacanz da unutmayn. Yani mesela paket dizininin bulunduu
konuma gre bir st dizinde bulunan, yani paket dndaki falanca.py adl bir modl u
ekilde ie aktaramazsnz:
from ... import falanca

Ama tabii eer paketinizin dizin yaps iki st dizine klmasna msaade ediyorsa yukardaki
komut alacaktr. Yani elinizdeki, aadakine benzer yapda bir pakette:
+ paket
|__ modul1.py
|__ modul2.py
|__ modul3.py
+ altdizin
|__altmodul1.py
|__altmodul2.py
+ altaltdizin
|__altaltmodul1.py
|__altaltmodul2.py

45.4. Kendi Oluturduumuz Paketler 783


Python 3 iin Trke Klavuz, Srm 3

altaltmodul1.py dosyasnn bulunduu konumdan itibaren iki st dizine karak modul2.py


dosyasn ie aktarabilirsiniz:
from ... import modul2

Yukarda gsterdiimiz bal ie aktarma mekanizmas, paket ad belirtmeden ie aktarma


ilemi gerekletirmenizi salar. Yani bu mekanizma sayesinde from paketadi.modul import
altmodul yerine from . import modul gibi bir kod yazarak, ayn dizin iinde veya st
dizinlerde bulunan modllere atfta bulunabilirsiniz.

45.4.4 Paketlerin Yola Eklenmesi

Daha nce de birka kez vurguladmz gibi, ie aktarma ilemlerinde Python aradmz
modl veya paketi bulabilmek iin sys.path adl listede grnen dizinlerin iine bakar. Eer
ie aktarmak istediiniz paket dizini bu listede deilse, o paketi ie aktarabilmek iin, komut
satrn o dizinin bulunduu klasrde amanz gerekir. Yani standart paketler ve nc ahs
paketlerin aksine, sys.path e eklenmemi bir paketi her yerden ie aktaramazsnz.
Peki bir paketi sys.path listesine nasl ekleyeceiz?
Aslnda bu sorunun cevab ok basit. Bildiiniz gibi, sys.path aslnda basit bir listeden
ibarettir. Dolaysyla listeler zerinde nasl deiiklik yapyorsanz, sys.path zerinde de o
ekilde deiiklik yapacaksnz.
Gelin isterseniz, yukarda oluturduumuz paket adl paket zerinden bir uygulama yapalm.
Pythonda bir paketi sys.path listesine eklerken dikkat etmemiz gereken ok nemli bir konu
var: Bir paketi sys.path listesine eklerken, paket adna karlk gelen dizini deil, paketi ieren
dizini bu listeye eklemeliyiz. Yani mesela paket adl dizin masastndeyse, bizim listeye
masastnn olduu dizini eklememiz gerekiyor, paketin olduu dizini deil...
Dikkatlice bakn:
>>> import os, sys
>>> kullanc = os.environ['HOME'] #Windows'ta os.environ['HOMEPATH']
>>> masast = os.path.join(kullanc, 'Desktop')
>>> sys.path.append(masast)

Bylece masastnn bulunduu dizini sys.path e eklemi olduk. Burada uyguladmz


admlara yle bir bakalm.
ncelikle gerekli modlleri ie aktardk:
>>> import os, sys

Amacmz masastnn yolunu sys.path e eklemek. Dolaysyla ncelikle kullanc dizininin


nerede olduunu tespit etmemiz lazm. Bildiiniz gibi, kullanc dizinleri, bilgisayar kuran
kiinin ismine gre belirlendii iin, btn bilgisayarlarda bu deer farkl olur. Bu deerin ne
olduu tespit edebilmek iin os modlnn environ niteliinden yararlanabiliriz. Bu nitelik,
iletim sistemine zg evre deikenlerini tutar.
GNU/Linuxta kullanc dizinini tutan evre deikeni HOME anahtar ile gsterilir:
>>> kullanc = os.environ['HOME']

Windowsta ise HOMEPATH anahtarn kullanyoruz:

784 Blm 45. Paketler


Python 3 iin Trke Klavuz, Srm 3

>>> kullanc = os.environ['HOMEPATH']

Kullanc dizinini elde ettikten sonra, masastne giden yolu bulabilmek iin u komutu
kullanyoruz:
>>> masast = os.path.join(kullanc, 'Desktop')

Sra geldi elde ettiimiz tam dizin yolunu sys.path e eklemeye:


>>> sys.path.append(masast)

Grdnz gibi, listelerin append() metodu yardmyla masastnn yolunu sys.path adl
listeye ekledik.
Artk masastnde bulunan paketleri rahatlkla her yerden ie aktarabiliriz.

Not: os modl hakknda daha geni bilgi iin os Modl balkl konuyu inceleyebilirsiniz.
sys modl hakknda bilgi iin ise sys Modl baln ziyaret edebilirsiniz.

45.4.5 Paketlerde sim akmalar

__init__.py Dosyas

Dipnotlar:

45.4. Kendi Oluturduumuz Paketler 785


BLM 46

Dzenli fadeler

Dzenli ifadeler Python programlama dilinin en etrelli konularndan biridir. yle ki,
dzenli ifadelerin Python iinde ayr bir dil olarak dnlmesi gerektiini syleyenler
dahi vardr. Ama btn zorluklarna ramen programlama deneyimimizin bir noktasnda
mutlaka karmza kacak olan bu yapy renmemizde byk fayda var. Dzenli ifadeleri
rendikten sonra, elle yaplmas saatler srecek bir ilemi saliseler iinde yapabildiinizi
grdnzde eminim dzenli ifadelerin ne byk bir nimet olduunu siz de anlayacaksnz.
Tabii her gzel ey gibi, dzenli ifadelerin nimetlerinden yararlanabilecek dzeye gelmek de
bir miktar kan, ter ve gzya istiyor.
Peki, dzenli ifadeleri kullanarak neler yapabiliriz? ok genel bir ifadeyle, bu yapy kullanarak
metinleri veya karakter dizilerini parmamzda oynatabiliriz. rnein bir web sitesinde
dank halde duran verileri bir rpda ayklayabiliriz. Bu veriler, mesela, toplu halde grmek
istediimiz web adreslerinin bir listesi olabilir. Bunun dnda, rnein, ok sayda belge
zerinde tek admda istediimiz deiiklikleri yapabiliriz.
Ancak genel bir kural olarak, dzenli ifadelerden kaabildiimiz mddete kamamz gerekir.
Eer Pythondaki karakter dizisi metotlar, o anda yapmak istediimiz ey iin yeterli
geliyorsa mutlaka o metotlar kullanmalyz. nk karakter dizisi metotlar, dzenli ifadelere
kyasla hem daha basit, hem de ok daha hzldr. Ama bir noktadan sonra karakter
dizilerini kullanarak yazdnz kodlar iyice karmaklamaya balamsa, kodlarn her taraf
if deyimleriyle dolmusa, hatta basit bir ilemi gerekletirmek iin yazdnz kod sayfa
snrlarn zorlamaya balamsa, ite o noktada artk dzenli ifadelerin dnyasna adm
atmanz gerekiyor olabilir. Ama bu durumda Jamie Zawinskinin u szn de aklnzdan
karmayn: Bazlar, bir sorunla kar karya kaldklarnda unu der: Evet, burada dzenli
ifadeleri kullanmam gerekiyor. te onlarn bir sorunu daha vardr artk...
Bata da sylediim gibi, dzenli ifadeler bize zorluklar unutturacak kadar byk kolaylklar
sunar. Emin olun yzlerce dosya zerinde tek tek elle deiiklik yapmaktan daha zor deildir
dzenli ifadeleri renip kullanmak... Hem zaten biz de bu sayfalarda bu sevimsiz konuyu
olabildiince sevimli hale getirmek iin elimizden gelen abay gstereceiz. Sizin de aba
gstermeniz, bol bol altrma yapmanz durumunda dzenli ifadeleri kavramak o kadar da
zorlayc olmayacaktr. Unutmayn, dzenli ifadeler ne kadar uratrc olsa da programcnn
en nemli silahlarndan biridir. Hatta dzenli ifadeleri rendikten sonra onsuz geen
yllarnza acyacaksnz.
imdi laf daha fazla uzatmadan iimize koyulalm.

786
Python 3 iin Trke Klavuz, Srm 3

46.1 Dzenli fadelerin Metotlar

Pythondaki dzenli ifadelere ilikin her ey bir modl iinde tutulur. Bu modln ad re. Tpk
os modlnde, sys modlnde, tkinter modlnde ve teki btn modllerde olduu gibi,
dzenli ifadeleri kullanabilmemiz iin de ncelikle bu re modln ie aktarmamz gerekecek.
Bu ilemi nasl yapacamz ok iyi biliyorsunuz:
>>> import re

Bata da sylediimiz gibi, dzenli ifadeler bir programcnn en nemli silahlarndan biridir.
u halde silahmzn zelliklerine bakalm. Yani bu yapnn bize sunduu aralar yle bir
listeleyelim. Etkileimli kabukta u kodu yazyoruz:
>>> dir(re)

Tabii yukardaki dir(re) komutunu yazmadan nce import re eklinde modlmz ie


aktarm olmamz gerekiyor.
Grdnz gibi, re modl iinde epey metot/fonksiyon var. Biz bu sayfada ve ilerleyen
sayfalarda, yukardaki metotlarn/fonksiyonlarn en sk kullanlanlarn size olabildiince
yaln bir ekilde anlatmaya alacaz. Eer isterseniz, u komutu kullanarak yukardaki
metotlar/fonksiyonlar hakknda yardm da alabilirsiniz:
>>> help(metot_veya_fonksiyon_ad)

Bir rnek vermek gerekirse:


>>> help(re.match)

Help on function match in module re:


match(pattern, string, flags=0)
Try to apply the pattern at the start of the string,
returning a match object, or None if no match was found.

Ne yazk ki, Pythonn yardm dosyalar hep ngilizce. Dolaysyla eer ngilizce bilmiyorsanz,
bu yardm dosyalar pek iinize yaramayacaktr. Bu arada yukardaki yardm blmnden
kmak iin klavyedeki q dmesine basmanz gerekir.

46.1.1 match() Metodu

Bir nceki blmde metotlar hakknda yardm almaktan bahsederken ilk rneimizi match()
metoduyla vermitik, o halde match() metodu ile devam edelim.
match() metodunu tarif etmek yerine, isterseniz bir rnek yardmyla bu metodun ne ie
yaradn anlamaya alalm. Diyelim ki elimizde yle bir karakter dizisi var:
>>> a = "python gl bir programlama dilidir."

Varsayalm ki biz bu karakter dizisi iinde python kelimesi geip gemediini renmek
istiyoruz. Ve bunu da dzenli ifadeleri kullanarak yapmak istiyoruz. Dzenli ifadeleri
bu rnee uygulayabilmek iin yapmamz gereken ey, ncelikle bir dzenli ifade kalb
oluturup, daha sonra bu kalb yukardaki karakter dizisi ile karlatrmak. Biz btn bu
ilemleri match() metodunu kullanarak yapabiliriz:

46.1. Dzenli fadelerin Metotlar 787


Python 3 iin Trke Klavuz, Srm 3

>>> re.match("python", a)

Burada, python eklinde bir dzenli ifade kalb oluturduk. Dzenli ifade kalplar match()
metodunun ilk argmandr (yani parantez iindeki ilk deer). kinci argmanmz ise (yani
parantez iindeki ikinci deer), hazrladmz kalb kendisiyle eletireceimiz karakter dizisi
olacaktr.
Klavyede ENTER tuuna bastktan sonra karmza yle bir kt gelecek:
<_sre.SRE_Match object; span=(0, 6), match='python'>

Bu kt, dzenli ifade kalbnn karakter dizisi ile eletii anlamna geliyor. Yani aradmz
ey, karakter dizisi iinde bulunmu.
Yukardaki ktda grdmz ifadeye Pythoncada eleme nesnesi (match object ) ad
veriliyor. nk match() metodu yardmyla yaptmz ey aslnda bir eletirme ilemidir
(match kelimesi ngilizcede elemek anlamna gelir). Biz burada python dzenli ifadesinin
a deikeniyle eleip elemediine bakyoruz. Yani re.match("python", a) ifadesi
araclyla python ifadesi ile a deikeninin tuttuu karakter dizisinin eleip elemediini
sorguluyoruz. Bizim rneimizde python a deikeninin tuttuu karakter dizisi ile eletii
iin bize bir eleme nesnesi dndrlyor.
Bu kt, dzenli ifade kalbnn karakter dizisi ile eletiini bildirmenin yansra, bize baka
birtakm bilgiler daha veriyor. Mesela bu ktdaki span parametresi, aradmz python
karakter dizisinin, a deikeninin 0. ila 6. karakterleri arasnda yer aldn sylyor bize.
Yani:
>>> a[0:6]

'python'

Ayrca yukardaki ktda grdmz match parametresi de bize eleen ifadenin python
olduu bilgisini veriyor.
Bir de u rnee bakalm:
>>> re.match("Java", a)

Burada ENTER tuuna bastmzda hi bir kt almyoruz. Aslnda biz grmesek de Python
burada None kts veriyor. Eer yukardaki komutu yle yazarsak None ktsn biz de
grebiliriz:
>>> print(re.match("Java", a))

None

Grdnz gibi, ENTER tuuna bastktan sonra None kts geldi. Demek ki Java ifadesi,
a deikeninin tuttuu karakter dizisi ile elemiyormu. Buradan kardmz sonuca gre,
Python match() metodu yardmyla aradmz eyi eletirdii zaman bir eleme nesnesi
(match object ) dndryor. Eer eleme yoksa, o zaman da None deerini dndryor.
Biraz kafa kartrmak iin yle bir rnek verelim:
>>> a = "Python gl bir dildir"
>>> re.match("gl", a)

788 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

Burada a deikeninde gl ifadesi getii halde match() metodu bize bir eleme
nesnesi dndrmedi. Peki ama neden?
Aslnda bu gayet normal. nk match() metodu bir karakter dizisinin sadece en bana
bakar. Yani Python gl bir dildir ifadesini tutan a deikenine re.match(gl, a) gibi bir
fonksiyon uyguladmzda, match() metodu a deikeninin yalnzca en bana bakaca ve a
deikeninin en banda gl yerine python olduu iin, match() metodu bize olumsuz
yant veriyor.
Aslnda match() metodunun yapt bu ii, karakter dizilerinin split() metodu yardmyla da
yapabiliriz:
>>> a.split()[0] == "python"

True

Demek ki a deikeninin en banda python ifadesi varm. Bir de una bakalm:


>>> a.split()[0] == "gl"

False

Veya ayn ii sadece startswith() metodunu kullanarak dahi yapabiliriz:


>>> a.startswith("python")

Eer dzenli ifadelerden tek beklentiniz bir karakter dizisinin en bandaki veriyle eletirme
ilemi yapmaksa, split() veya startswith() metotlarn kullanmak daha mantkldr. nk
split() ve startswith() metotlar match() metodundan ok daha hzl alacaktr.
match() metodunu kullanarak bir ka rnek daha yapalm:
>>> sorgu = "1234567890"
>>> re.match("1", sorgu)

<_sre.SRE_Match object; span=(0, 1), match='1'>

>>> re.match("1234", sorgu)

<_sre.SRE_Match object; span=(0, 4), match='1234'>

>>> re.match("124", sorgu)

sterseniz imdiye kadar rendiimiz eyleri yle bir gzden geirelim:


1. Dzenli ifadeler Pythonn ok gl aralarndan biridir.
2. Pythondaki dzenli ifadelere ilikin btn fonksiyonlar re adl bir modl iinde yer alr.
3. Dolaysyla dzenli ifadeleri kullanabilmek iin ncelikle bu re modln import re
diyerek ie aktarmamz gerekir.
4. re modlnn ieriini dir(re) komutu yardmyla listeleyebiliriz.
5. match() metodu re modl iindeki fonksiyonlardan biridir.
6. match() metodu bir karakter dizisinin yalnzca en bana bakar.
7. Eer aradmz ey karakter dizisinin en banda yer alyorsa, match() metodu bir
eletirme nesnesi dndrr.

46.1. Dzenli fadelerin Metotlar 789


Python 3 iin Trke Klavuz, Srm 3

8. Eer aradmz ey karakter dizisinin en banda yer almyorsa, match() metodu None
deeri dndrr.
Daha nce sylediimiz gibi, match() metodu ile bir eletirme ilemi yaptmzda, eer
eleme varsa Python bize bir eleme nesnesi dndrecektir. Dndrlen bu eleme
nesnesi bize span ve match parametreleri araclyla, eleen karakter dizisinin sorgu dizisi
iindeki yerini ve eleen dizinin ne olduu sylyor. span paramtresinin deerine span()
adl bir metot yardmyla eriebiliyoruz. rnein:
>>> import re
>>> sorgu = 'Bin kunduz'
>>> eleme = re.match('Bin', sorgu)
>>> eleme

<_sre.SRE_Match object; span=(0, 3), match='Bin'>

>>> eleme.span()
(0, 3)

Ancak, match() metodu ile bulunan eyin ne olduunu eleme nesnesinin match
parametresine bakarak grebilsek de, bu deeri bir kod yardmyla alamyoruz. nk
eleme nesnelerinin span() metoduna benzeyen bir match() metodu bulunmaz.
Ama istersek tabii ki bulunan eyi de programatik olarak alma imknmz var. Bunun iin
group() adl bir baka metottan yararlanacaz:
>>> kardiz = "perl, python ve ruby yksek seviyeli dillerdir."
>>> eleme = re.match("perl", kardiz)
>>> eleme.group()

'perl'

Burada, re.match("perl", kardiz) komutunu bir deikene atadk. Hatrlarsanz, bu


fonksiyonu komut satrna yazdmzda bir eleme nesnesi elde ediyorduk. te burada
deikene atadmz ey aslnda bu eleme nesnesinin kendisi oluyor. Bu durumu u ekilde
teyit edebilirsiniz:
>>> type(eleme)

<class '_sre.SRE_Match'>

Grdnz gibi, eleme deikeninin tipi bir eleme nesnesi (match object ). sterseniz bu
nesnenin metotlarna bir gz gezdirebiliriz:
>>> dir(eleme)

Dikkat ederseniz yukarda kullandmz group() metodu listede grnyor. Bu metot,


dorudan doruya dzenli ifadelerin deil, eleme nesnelerinin bir metodudur. Listedeki
br metotlar da sras geldiinde inceleyeceiz. imdi isterseniz bir rnek daha yapp bu
konuyu kapatalm:
>>> iddia = "Adana memleketlerin en gzelidir!"
>>> nesne = re.match("Adana", iddia)
>>> nesne.group()

'Adana'

790 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

Peki, eletirmek istediimiz dzenli ifade kalb bulunamazsa ne olur? yle bir durumda
yukardaki kodlar hata verecektir. Hemen bakalm:
>>> nesne = re.match("stanbul", iddia)
>>> nesne.group()

Hata mesajmz:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

Byle bir hata, yazdnz bir programn kmesine neden olabilir. O yzden kodlarmz una
benzer bir ekilde yazmamz daha mantkl olacaktr:
>>> nesne = re.match("stanbul", iddia)
>>> if nesne:
... print("eleen ifade:", nesne.group())
... else:
... print("eleme baarsz!")

imdi isterseniz bu match() metoduna bir ara verip baka bir metodu inceleyelim.

46.1.2 search() Metodu

Bir nceki blmde incelediimiz match() metodu, karakter dizilerinin sadece en bana
bakyordu. Ama istediimiz ey tabii ki her zaman bununla snrl olmayacaktr. match()
metodunun, karakter dizilerinin sadece bana bakmasn engellemenin yollar olmakla
birlikte, bizim iimizi grecek ok daha kullanl bir metodu vardr dzenli ifadelerin. nceki
blmde dir(re) eklinde gsterdiimiz listeye tekrar bakarsanz, orada re modlnn
search() adl bir metodu olduunu greceksiniz. te bu yazmzda inceleyeceimiz metot
bu search() metodu olacaktr.
search() metodu ile match() metodu arasnda ok nemli bir fark vardr. match() metodu bir
karakter dizisinin en bana bakp bir eletirme ilemi yaparken, search() metodu karakter
dizisinin genelinde bir arama ilemi yapar. Yani biri eletirir, br arar.
Hatrlarsanz, match() metodunu anlatrken yle bir rnek vermitik:
>>> a = "Python gl bir dildir"
>>> re.match("gl", a)

Yukardaki kod, karakter dizisinin banda bir eleme bulamad iin bize None deeri
dndryordu. Ama eer ayn ilemi yle yaparsak, daha farkl bir sonu elde ederiz:
>>> a = "Python gl bir dildir"
>>> re.search("gl", a)

<_sre.SRE_Match object; span=(7, 12), match='gl'>

Grdnz gibi, search() metodu gl kelimesini buldu. nk search() metodu,


match() metodunun aksine, bir karakter dizisinin sadece ba tarafna bakmakla yetinmiyor,
karakter dizisinin geneli zerinde bir arama ilemi gerekletiriyor.
Tpk match() metodunda olduu gibi, search() metodunda da span() ve group()
metotlarndan faydalanarak bulunan eyin hangi aralkta olduunu ve bu eyin ne olduunu

46.1. Dzenli fadelerin Metotlar 791


Python 3 iin Trke Klavuz, Srm 3

grntleyebiliriz:
>>> kardiz = "Python gl bir dildir"
>>> nesne = re.search("gl", kardiz)
>>> nesne.span()

(7, 12)

>>> nesne.group()

'gl'

imdiye kadar hep karakter dizileri zerinde altk. sterseniz biraz da listeler zerinde
rnekler verelim.
yle bir listemiz olsun:
>>> liste = ["elma", "armut", "kebap"]
>>> re.search("kebap", liste)

Ne oldu? Hata aldnz, deil mi? Bu normal. nk dzenli ifadeler karakter dizileri zerinde
iler. Bunlar dorudan listeler zerinde ilem yapamaz. O yzden bizim Pythona biraz
yardmc olmamz gerekiyor:
>>> for i in liste::
... nesne = re.search("kebap", i)
... if nesne:
... print(nesne.group())
...
kebap

Hatta imdiye kadar rendiklerimizle daha karmak bir eyler de yapabiliriz:


>>> import re
>>> from urllib.request import urlopen
>>> f = urlopen("http://www.istihza.com")
>>> for i in f:
... nesne = re.search(b'programlama', i)
... if nesne:
... print(nesne.group())
...
b'programlama'
b'programlama'

Grdnz gibi, www.istihza.com sayfasnda ka adet programlama kelimesi geiyorsa


hepsi ekrana dklyor.
Bu arada, websitesinde arama ilemi gerekletirirken urllib paketinin iindeki request
modlnn urlopen() adl fonksiyonunu kullandmza dikkat edin. Ayrca search()
metoduna parametre olarak bir karakter dizisi deil, bayt dizisi verdiimizi de gzden
karmayn:
re.search(b'programlama', i)

Siz isterseniz bu kodlar biraz daha gelitirebilirsiniz:


import re
from urllib.request import urlopen

792 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

kelime = input("istihza.com'da aramak istediiniz kelime: ")

f = urlopen("http://www.istihza.com")
data = str(f.read())

nesne = re.search(kelime, data)

if nesne:
print("kelime bulundu:", nesne.group())
else:
print("kelime bulunamad!:", kelime)

Burada, kullancdan aldmz kelimeyi search() metoduna gndermeden nce, siteden


okuduumuz verileri str() metodu yardmyla karakter dizisine dntrdmze dikkat
edin. Bylece kullancdan gelen karakter dizisini bayt dizisine evirmemize gerek kalmad.
lerde bilgimiz artnca daha yetkin kodlar yazabilecek duruma geleceiz. Ama imdilik
elimizde olanlar ancak yukardaki kodu yazmamza msaade ediyor. Unutmayn, dzenli
ifadeler sahasnda snma turlar atyoruz daha...

46.1.3 ndall() Metodu

Python komut satrnda, yani etkileimli kabukta, dir(re) yazdmz zaman aldmz listeye
tekrar bakarsak orada bir de findall() adl bir metodun olduunu grrz. te bu blmde
findall() adl bu nemli metodu incelemeye alacaz.
nce yle bir metin alalm elimize:
metin = """Guido Van Rossum Python' gelitirmeye 1990 ylnda balam... Yani
aslnda Python iin nispeten yeni bir dil denebilir. Ancak Python'un ok uzun
bir gemii olmasa da, bu dil teki dillere kyasla kolay olmas, hzl olmas,
ayr bir derleyici programa ihtiya duymamas ve bunun gibi pek ok nedenden
tr ou kimsenin gzdesi haline gelmitir. Ayrca Google'n da Python'a zel
bir nem ve deer verdiini, ok iyi derecede Python bilenlere i olana
sunduunu da hemen syleyelim. Mesela bundan ksa bir sre nce Python'n
yaratcs Guido Van Rossum Google'de ie balad..."""

Bu metin iinde geen btn Python kelimelerini bulmak istiyoruz:


print(re.findall("Python", metin))

['Python', 'Python', 'Python', 'Python', 'Python', 'Python']

Grdnz gibi, metinde geen btn Python kelimelerini bir rpda liste olarak aldk.
Ayn ilemi search() metodunu kullanarak yapmak istersek yolu biraz uzatmamz gerekir:
>>> liste = metin.split()
>>> for i in liste:
... nesne = re.search("Python", i)
... if nesne:
... print(nesne.group())
...
Python
Python
Python
Python

46.1. Dzenli fadelerin Metotlar 793


Python 3 iin Trke Klavuz, Srm 3

Python
Python

Grdnz gibi, metinde geen btn Python kelimelerini search() metodunu kullanarak
bulmak iin ncelikle metin adl karakter dizisini, daha nce karakter dizilerini ilerken
grdmz split() metodu yardmyla bir liste haline getiriyoruz. Ardndan bu liste
zerinde bir for dngs kurarak search() ve group() metotlarn kullanarak btn Python
kelimelerini ayklyoruz. Eer karakter dizisini yukardaki ekilde listeye dntrmezsek yle
bir netice alrz:
>>> nesne = re.search("Python", metin)
>>> print(nesne.group())

Python

Bu ekilde metinde geen sadece ilk Python kelimesini alabiliyoruz.

46.2 Metakarakterler

imdiye kadar dzenli ifadelerle ilgili olarak verdiimiz rnekler sizi biraz artm olabilir.
Zor dediin bunlar myd? diye dnm olabilirsiniz. Haklsnz, zira zor dediim,
buraya kadar olan ksmda verdiim rneklerden ibaret deildir. Buraya kadar olan blmde
verdiim rnekler iin en temel ksmn gzler nne sermek iindi. imdiye kadar olan
blmde, mesela, python karakter dizisiyle eletirme yapmak iin python kelimesini
kullandk. Esasnda bu, dzenli ifadelerin en temel zelliidir. Yani python karakter dizisini
bir dzenli ifade sayacak olursak (ki zaten yledir), bu dzenli ifade en bata kendisiyle
eleecektir. Bu ne demek? yle ki: Eer aradnz ey python karakter dizisi ise,
kullanmanz gereken dzenli ifade de python olacaktr.
Diyoruz ki: Dzenli ifadeler en bata kendileriyle eleirler. Buradan u anlam kyor:
Demek ki bir de kendileriyle elemeyen dzenli ifadeler var. te bu durum, Pythondaki
dzenli ifadelere kiiliini kazandran eydir. Biraz sonra ne demek istediimizi daha ak
anlayacaksnz. Artk gerek anlamyla dzenli ifadelere giri yapyoruz!
ncelikle, elimizde aadaki gibi bir liste olduunu varsayalm:
>>> liste = ["zcan", "mehmet", "sleyman", "selim",
... "kemal", "zkan", "esra", "dndar", "esin",
... "esma", "zhan", "zlem"]

Diyelim ki, biz bu liste iinden zcan, zkan ve zhan elerini ayklamak/almak istiyoruz.
Bunu yapabilmek iin yeni bir bilgiye ihtiyacmz var: Metakarakterler.
Metakarakterler; kabaca, programlama dilleri iin zel anlam ifade eden sembollerdir.
rnein daha nce grdmz \n bir bakma bir metakarakterdir. nk \n sembol
Python iin zel bir anlam tar. Python bu sembol grd yerde yeni bir satra
geer. Yukarda kendisiyle elemeyen karakterler ifadesiyle kastettiimiz ey de ite bu
metakarakterlerdir. rnein, a har yalnzca kendisiyle eleir. Tpk istihza kelimesinin
yalnzca kendisiyle eleecei gibi... Ama mesela \t ifadesi kendisiyle elemez. Python bu
iareti grd yerde sekme (tab) dmesine baslm gibi tepki verecektir. te dzenli
ifadelerde de buna benzer metakarakterlerden yararlanacaz. Dzenli ifadeler iinde de,
zel anlam ifade eden pek ok sembol, yani metakarakter vardr. Bu metakarakterlerden biri

794 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

de [ ] semboldr. imdi yukarda verdiimiz listeden zcan, zhan ve zkan elerini


bu sembolden yararlanarak nasl ayklayacamz grelim:
>>> re.search("z[chk]an", liste)

Bu kodu byle yazmamamz gerektiini artk biliyoruz. Aksi halde hata alrz. nk daha
nce de dediimiz gibi, dzenli ifadeler karakter dizileri zerinde ilem yapabilir. Listeler
zerinde deil. Dolaysyla komutumuzu u ekilde vermemiz gerekiyor:
>>> for i in liste:
... nesne = re.search("z[chk]an", i)
... if nesne:
... print(nesne.group())

Ayn ilemi u ekilde de yapabiliriz:


>>> for i in liste:
... if re.search("z[chk]an",i):
... print(i)

Ancak, bu rnekte pek belli olmasa da, son yazdmz kod her zaman istediimiz sonucu
vermez. Mesela listemiz yle olsayd:
>>> liste = ["zcan demir", "mehmet", "sleyman",
... "selim", "kemal", "zkan nuri", "esra", "dndar",
... "esin", "esma", "zhan kamil", "zlem"]

Yukardaki kod bu liste zerine uygulandnda, sadece almak istediimiz ksm deil, ilgisiz
ksmlar da gelecektir.
Grdnz gibi, uygun kodlar kullanarak, zcan, zkan ve zhan elerini listeden
kolayca aykladk. Bize bu imkn veren ey ise [ ] adl metakarakter oldu. Aslnda [ ]
metakarakterinin ne ie yaradn az ok anlam olmalsnz. Ama biz yine de yle bir
bakalm bu metakaraktere:
[ ] adl metakarakter, yukarda verdiimiz listedeki z ile balayp, c, h veya k
harerinden herhangi biri ile devam eden ve an ile biten btn eleri ayklyor. Gelin
bununla ilgili bir rnek daha yapalm:
>>> for i in liste:
... nesne = re.search("es[mr]a",i)
... if nesne:
... print(nesne.group())

Grdnz gibi, es ile balayp, m veya r harerinden herhangi biriyle devam eden ve
sonunda da a har bulunan btn eleri aykladk. Bu da bize esma ve esra ktlarn
verdi...
Dediimiz gibi, metakarakterler programlama dilleri iin zel anlam ifade eden sembollerdir.
Normal karakterlerden farkl olarak, metakarakterlerle karlaan bir bilgisayar normalden
farkl bir tepki verecektir. Yukarda metakarakterlere rnek olarak \n ve \t ka dizilerini
vermitik. rnein Pythonda print(\n) gibi bir komut verdiimizde, Python ekrana \n
yazdrmak yerine bir alt satra geecektir. nk \n Python iin zel bir anlam tamaktadr.
Dzenli ifadelerde de birtakm metakarakterlerin kullanldn rendik. Bu metakarakterler,
dzenli ifadeleri dzenli ifade yapan eydir. Bunlar olmadan dzenli ifadelerle yararl bir i
yapmak mmkn olmaz. Bu giri blmnde dzenli ifadelerde kullanlan metakarakterlere
rnek olarak [ ] semboln verdik. Herhangi bir dzenli ifade iinde [ ] semboln gren

46.2. Metakarakterler 795


Python 3 iin Trke Klavuz, Srm 3

Python, dorudan doruya bu sembolle eleen bir karakter dizisi aramak yerine, zel bir
ilem gerekletirecektir. Yani [ ] sembol kendisiyle elemeyecektir...
Pythonda bulunan temel metakarakterleri topluca grelim:
[ ] . \* + ? { } ^ $ | ( )

Dorudur, yukardaki karakterler, izgi romanlardaki kfrlere benziyor. Endielenmeyin,


biz bu metakarakterleri olabildiince sindirilebilir hale getirmek iin elimizden gelen abay
gstereceiz.
Bu blmde dzenli ifadelerin zor ksm olan metakarakterlere, okurlarmz rktmeden,
yumuak bir giri yapmay amaladk. imdi artk metakarakterlerin temelini attmza gre
ste kat kmaya balayabiliriz.

46.2.1 [ ] (Keli Parantez)

[ ] adl metakaraktere nceki blmde deinmitik. Orada verdiimiz rnek uydu:


>>> for i in liste:
... nesne = re.search("z[chk]an", i)
... if nesne:
... print(nesne.group())

Yukardaki rnekte, bir liste iinde geen zcan, zhan ve zkan elerini ayklyoruz.
Burada bu edeki farkl karakterleri (c, h ve k) keli parantez iinde nasl
belirttiimize dikkat edin. Python, keli parantez iinde grd btn karakterleri tek
tek liste elerine uyguluyor. nce z ile balayan btn eleri alyor, ardndan z
hecesinden sonra c haryle devam eden ve an hecesi ile biten eyi buluyor. Bylece
zcan esini bulmu oldu. Ayn ilemi, z hecesinden sonra h harni barndran ve an
hecesiyle biten eye uyguluyor. Bu ekilde ise zhan esini bulmu oldu. En son hedef
ise z ile balayp k har ile devam eden ve an ile biten e. Yani listedeki zkan esi...
En nihayetinde de elimizde zcan, zhan ve zkan eleri kalm oluyor.
Bir nceki blmde yine [ ] metakarakteriyle ilgili olarak u rnei de vermitik:
>>> for i in liste:
... nesne = re.search("es[mr]a",i)
... if nesne:
... print(nesne.group())

Bu rnein de zcan, zkan, zhan rneinden bir fark yok. Burada da Python keli
parantez iinde grd btn karakterleri tek tek liste elerine uygulayp, esma ve esra
elerini bize veriyor.
imdi bununla ilgili yeni bir rnek verelim
Diyelim ki elimizde yle bir liste var:
>>> a = ["23BH56","TY76Z","4Y7UZ","TYUDZ","34534"]

Mesela biz bu listedeki eler iinde, sayyla balayanlar ayklayalm. imdi u kodlar
dikkatlice inceleyin:
>>> for i in a:
... if re.match("[0-9]",i):
... print(i)

796 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

...
23BH56
4Y7UZ
34534

Burada parantez iinde kullandmz ifadeye dikkat edin. 0 ile 9 arasndaki btn eleri
ieren bir karakter dizisi tanmladk. Yani ksaca, iinde herhangi bir say barndran eleri
kapsama alanmza aldk. Burada ayrca search() yerine match() metodunu kullandmza
da dikkat edin. match() metodunu kullanmamzn nedeni, bu metodun bir karakter dizisinin
sadece en bana bakmas... Amacmz say ile balayan btn eleri ayklamak olduuna
gre, yukarda yazdmz kod, liste eleri iinde yer alan ve say ile balayan btn eleri
ayklayacaktr. Biz burada Pythona u emri vermi oluyoruz:
Bana say ile balayan btn eleri bul! nemli olan bu elerin sayyla balamasdr!
Sayyla balayan bu eler ister hare devam etsin, ister baka bir karakterle... Sen yeter
ki bana say ile balayan eleri bul!
Bu emri alan Python, hemen liste elerini gzden geirecek ve bize 23BH56, 4Y7UZ ve
34534 elerini verecektir. Dikkat ederseniz, Python bize listedeki TY76Z ve TYUDZ
elerini vermedi. nk TY76Z iinde saylar olsa da bunlar bizim ltmze uyacak
ekilde en bata yer almyor. TYUDZ esinde ise tek bir say bile yok...
imdi de isterseniz listedeki TY76Z esini nasl alabileceimize bakalm:
>>> for i in a:
... if re.match("[A-Z][A-Z][0-9]",i):
... print(i)

Burada dikkat ederseniz dzenli ifademizin banda A-Z diye bir ey yazdk. Bu ifade
A ile Z hareri arasndaki btn karakterleri temsil ediyor. Biz burada yalnzca byk
hareri sorguladk. Eer kk hareri sorgulamak isteseydik A-Z yerine a-z diyecektik.
Dzenli ifademiz iinde geen birinci A-Z ifadesi aradmz karakter dizisi olan TY76Z
iindeki T harni, ikinci A-Z ifadesi Y harni, 0-9 ifadesi ise 7 saysn temsil ediyor.
Karakter dizisi iindeki geri kalan harer ve saylar otomatik olarak eletirilecektir. O yzden
onlar iin ayr bir ey yazmaya gerek yok. Yalnz bu sylediimiz son ey sizi aldatmasn.
Bu otomatik eletirme ilemi bizim u anda kar karya olduumuz karakter dizisi iin
geerlidir. Farkl nitelikteki karakter dizilerinin sz konusu olduu baka durumlarda iler
byle yrmeyebilir. Dzenli ifadeleri baarl bir ekilde kullanabilmenin ilk art, zerinde
ilem yaplacak karakter dizisini tanmaktr. Bizim rneimizde yukardaki gibi bir dzenli
ifade kalb oluturmak iimizi gryor. Ama baka durumlarda, duruma uygun baka
kalplar yazmak gerekebilir/gerekecektir. Dolaysyla, tek bir dzenli ifade kalbyla hayatn
gemeyeceini unutmamalyz.
imdi yukardaki kodu search() ve group() metotlarn kullanarak yazmay deneyin. Elde
ettiiniz sonular dikkatlice inceleyin. match() ve search() metotlarnn ne gibi farkllklara
sahip olduunu kavramaya aln... Sorunuz olursa bana nasl ulaacanz biliyorsunuz...
Bu arada, dzenli ifadelerle ilgili daha fazla ey rendiimizde yukardaki kodu ok daha
sade bir biimde yazabileceiz.

46.2.2 . (Nokta)

Bir nceki blmde [] adl metakarakteri incelemitik. Bu blmde ise farkl bir
metakarakteri inceleyeceiz. nceleyeceimiz metakarakter: .

46.2. Metakarakterler 797


Python 3 iin Trke Klavuz, Srm 3

Bu metakarakter, yeni satr karakteri hari btn karakterleri temsil etmek iin kullanlr.
Mesela:
>>> for i in liste:
... nesne = re.match("es.a",i)
... if nesne:
... print(nesne.group())
...
esma
esra

Grdnz gibi, daha nce [] metakarakterini kullanarak yazdmz bir dzenli ifadeyi
bu kez farkl ekilde yazyoruz. Unutmayn, bir dzenli ifade birka farkl ekilde yazlabilir.
Biz bunlar iinde en basit ve en anlalr olann semeliyiz. Ayrca yukardaki kodu birka
farkl ekilde de yazabilirsiniz. Mesela u yazm da bizim durumumuzda geerli bir seenek
olacaktr:
>>> for i in liste:
... if re.match("es.a",i):
... print(i)

Tabii ki biz, o anda zmek durumunda olduumuz soruna en uygun olan seenei tercih
etmeliyiz...
Yalnz, unutmamamz gereken ey, bu . adl metakarakterin sadece tek bir karakterin yerini
tutuyor olmasdr. Yani yle bir kullanm bize istediimiz sonucu vermez:
>>> liste = ["ahmet","kemal", "kamil", "mehmet"]
>>> for i in liste:
... if re.match(".met",i):
... print(i)

Burada . sembol ah ve meh hecelerinin yerini tutamaz. . sembolnn grevi sadece


tek bir karakterin yerini tutmaktr (yeni satr karakteri hari). Ama biraz sonra reneceimiz
metakarakter yardmyla ah ve meh hecelerinin yerini de tutabileceiz.
. semboln kullanarak bir rnek daha yapalm. Bir nceki blmde verdiimiz a listesini
hatrlyorsunuz:
>>> a = ['23BH56', 'TY76Z', '4Y7UZ', 'TYUDZ', '34534']

nce bu listeye bir e daha ekleyelim:


>>> a.append("1agAY54")

Artk elimizde yle bir liste var:


>>> a = ['23BH56', 'TY76Z', '4Y7UZ', 'TYUDZ',
... '34534', "1agAY54"]

imdi bu listeye yle bir dzenli ifade uygulayalm:


>>> for i in a:
... if re.match(".[0-9a-z]", i):
... print(i)
...
23BH56
34534
1agAY54

798 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

Burada yaptmz ey ok basit. u zelliklere sahip bir karakter dizisi aryoruz:


1. Herhangi bir karakter ile balayacak. Bu karakter say, harf veya baka bir karakter
olabilir.
2. Ardndan bir say veya alfabedeki kk harerden herhangi birisi gelecek.
3. Bu ltleri karladktan sonra, aradmz karakter dizisi herhangi bir karakter ile
devam edebilir.
Yukardaki ltlere uyan karakter dizilerimiz: 23BH56, 34534, 1agAY54
Yine burada da kendinize gre birtakm deiiklikler yaparak, farkl yazm ekilleri ve farkl
metotlar kullanarak ne olup ne bittiini daha iyi kavrayabilirsiniz. Dzenli ifadeleri gerei gibi
anlayabilmek iin bol bol uygulama yapmamz gerektiini unutmamalyz.

46.2.3 * (Yldz)

Bu metakarakter, kendinden nce gelen bir dzenli ifade kalbn sfr veya daha fazla sayda
eletirir. Tanm biraz kark olsa da rnek yardmyla bunu da anlayacaz:
>>> yeniliste = ["st", "sat", "saat", "saaat", "falanca"]
>>> for i in yeniliste:
... if re.match("sa*t",i):
... print(i)

Burada * sembol kendinden nce gelen a karakterini sfr veya daha fazla sayda
eletiriyor. Yani mesela st iinde sfr adet a karakteri var. Dolaysyla bu karakter
yazdmz dzenli ifadeyle eleiyor. sat iinde bir adet a karakteri var. Dolaysyla bu da
eleiyor. saat ve saaat karakter dizilerinde srasyla iki ve adet a karakteri var. Tabii
ki bunlar da yazdmz dzenli ifadeyle eleiyor. Listemizin en son esi olan falancada da
ilk hecede bir adet a karakteri var. Ama bu edeki sorun, bunun s haryle balamamas.
nk biz yazdmz dzenli ifadede, aradmz eyin s har ile balamasn, sfr veya daha
fazla sayda a karakteri ile devam etmesini ve ardndan da t harnin gelmesini istemitik.
falanca esi bu koullar karlamad iin szgecimizin dnda kald.
Burada dikkat edeceimiz nokta, * metakarakterinin kendinden nce gelen yalnzca bir
karakterle ilgileniyor olmas... Yani bizim rneimizde * sembol sadece a harnin sfr
veya daha fazla sayda bulunup bulunmamasyla ilgileniyor. Bu ilgi, en bataki s harni
kapsamyor. s harnin de sfr veya daha fazla sayda elemesini istersek dzenli ifademizi
s*a*t veya [sa]*t biiminde yazmamz gerekir... Bu iki seenek iinde [sa]*t eklindeki
yazm tercih etmenizi tavsiye ederim. Burada, daha nce rendiimiz [ ] metakarakteri
yardmyla sa harerini nasl grupladmza dikkat edin...
imdi . metakarakterini anlatrken istediimiz sonucu alamadmz listeye dnelim. Orada
ahmet ve mehmet elerini listeden baaryla ayklayamamtk. O durumda bizim
baarsz olmamza neden olan kullanm yleydi:
>>> liste = ["ahmet", "kemal", "kamil", "mehmet"]
>>> for i in liste:
... if re.match(".met",i):
... print(i)

46.2. Metakarakterler 799


Python 3 iin Trke Klavuz, Srm 3

Ama artk elimizde * gibi bir ara olduuna gre imdi istediimiz eyi yapabiliriz. Yapmamz
gereken tek ey . sembolnden sonra * semboln getirmek:
>>> for i in liste:
... if re.match(".*met", i):
... print(i)

Grdnz gibi ahmet ve mehmet elerini bu kez baaryla aykladk. Bunu yapmamz
salayan ey de * adl metakarakter oldu... Burada Pythona u emri verdik: Bana kelime
banda herhangi bir karakteri (. sembol herhangi bir karakterin yerini tutuyor) sfr veya
daha fazla sayda ieren ve sonu da met ile biten btn eleri ver!
Bir nceki rneimizde a harnin sfr veya daha fazla sayda bulunup bulunmamasyla
ilgilenmitik. Bu son rneimizde ise herhangi bir harn/karakterin sfr veya daha fazla
sayda bulunup bulunmamasyla ilgilendik. Dolaysyla .*met eklinde yazdmz dzenli
ifade, ahmet, mehmet, muhammet, ismet, ksmet ve hatta tek bana met gibi
btn eleri kapsayacaktr. Ksaca ifade etmek gerekirse, sonu met ile biten her ey (met
ifadesinin kendisi de dhil olmak zere) kapsama alanmza girecektir. Bunu gnlk hayatta
nerede kullanabileceinizi hemen anlam olmalsnz. Mesela bir dizin iindeki btn mp3
dosyalarn bu dzenli ifade yardmyla listeleyebiliriz:
>>> import os
>>> import re
>>> dizin = os.listdir(os.getcwd())
>>> for i in dizin:
... if re.match(".*mp3",i):
... print(i)

match() metodunu anlattmz blmde bu metodun bir karakter dizisinin yalnzca


balangcyla ilgilendiini sylemitik. Mesela o blmde verdiimiz u rnei
hatrlyorsunuzdur:
>>> a = "python gl bir dildir"
>>> re.match("gl", a)

Bu rnekte Python bize kt olarak None deerini vermiti. Yani herhangi bir eleme
bulamamt. nk dediimiz gibi, match() metodu bir karakter dizisinin yalnzca en bana
bakar. Ama geldiimiz u noktada artk bu kstlamay nasl kaldracanz biliyorsunuz:
>>> re.match(".*gl", a)

Ama match() metodunu bu ekilde zorlamak yerine performans asndan en doru yol bu
tr iler iin search() metodunu kullanmak olacaktr.
Bunu da getiimize gre artk yeni bir metakarakteri incelemeye balayabiliriz.

46.2.4 + (Art)

Bu metakarakter, bir nceki metakarakterimiz olan * ile benzerdir. Hatrlarsanz, *


metakarakteri kendisinden nceki sfr veya daha fazla sayda tekrar eden karakterleri
ayklyordu. + metakarakteri ise kendisinden nceki bir veya daha fazla sayda tekrar eden
karakterleri ayklar. Bildiiniz gibi, nceki rneklerimizden birinde ahmet ve mehmet
elerini u ekilde ayklamtk:

800 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

>>> for i in liste:


... if re.match(".*met",i):
... print(i)

Burada ahmet ve mehmet dnda met eklinde bir e de bu dzenli ifadenin


kapsamna girecektir. Mesela listemiz yle olsa idi:
>>> liste = ["ahmet", "mehmet", "met", "kezban"]

Yukardaki dzenli ifade bu listedeki met esini de iine alacakt. nk * adl


metakarakter sfr sayda tekrar eden karakterleri de ayklyor. Ama bizim istediimiz her
zaman bu olmayabilir. Bazen de, ilgili karakterin en az bir kez tekrar etmesini isteriz. Bu
durumda yukardaki dzenli ifadeyi u ekilde yazmamz gerekir:
>>> for i in liste:
... if re.match(".+met",i):
... print(i)

Burada u komutu vermi olduk: Bana sonu met ile biten btn eleri ver! Ama bana
met esini yalnz bana verme!
Ayn ilemi search() metodunu kullanarak da yapabileceimizi biliyorsunuz:
>>> for i in liste:
... nesne = re.search(".+met",i)
... if nesne:
... nesne.group()
...
ahmet
mehmet

Bir de daha nce verdiimiz u rnee bakalm:


>>> yeniliste = ["st", "sat", "saat", "saaat", "falanca"]
>>> for i in yeniliste:
... if re.match("sa*t",i):
... print(i)

Burada yazdmz dzenli ifadenin zellii nedeniyle st de kapsama alan iine giriyordu.
nk burada * sembol a karakterinin hi bulunmad durumlar da iine alyor. Ama
eer biz a karakteri en az bir kez gesin istiyorsak, dzenli ifademizi u ekilde yazmalyz:
>>> for i in yeniliste:
... if re.match("sa+t", i):
... print(i)

Hatrlarsanz nceki derslerimizden birinde keli parantezi anlatrken yle bir rnek
vermitik:
>>> a = ["23BH56", "TY76Z", "4Y7UZ", "TYUDZ", "34534"]
>>> for i in a:
... if re.match("[A-Z][A-Z][0-9]",i):
... print(i)

Burada amacmz sadece TY76Z esini almakt. Dikkat ederseniz, enin bandaki T ve
Y harerini bulmak iin iki kez [A-Z] yazdk. Ama artk + metakarakterini rendiimize
gre ayn ii daha basit bir ekilde yapabiliriz:

46.2. Metakarakterler 801


Python 3 iin Trke Klavuz, Srm 3

>>> for i in a:
... if re.match("[A-Z]+[0-9]",i):
... print(i)
...
TY76Z

Burada [A-Z] dzenli ifade kalbn iki kez yazmak yerine bir kez yazp yanna da +
semboln koyarak, bu ifade kalbnn bir veya daha fazla sayda tekrar etmesini istediimizi
belirttik...
+ sembolnn ne i yaptn da anladmza gre, artk yeni bir metakarakteri incelemeye
balayabiliriz.

46.2.5 ? (Soru areti)

Hatrlarsanz, * karakteri sfr ya da daha fazla sayda elemeleri; + ise bir ya da daha fazla
sayda elemeleri kapsyordu. te imdi greceimiz ? sembol de eleme saysnn sfr
veya bir olduu durumlar kapsyor. Bunu daha iyi anlayabilmek iin nceden verdiimiz u
rnee bakalm:
>>> yeniliste = ["st", "sat", "saat", "saaat", "falanca"]
>>> for i in yeniliste:
... if re.match("sa*t",i):
... print(i)
...
st
sat
saat
saaat

>>> for i in yeniliste:


... if re.match("sa+t",i):
... print(i)
...
sat
saat
saaat

* ve + sembollerinin hangi karakter dizilerini aykladn gryoruz. imdi de ?


sembolnn ne yaptna bakalm:
>>> for i in yeniliste:
... if re.match("sa?t",i):
... print(i)
...
st
sat

Grdnz gibi, ? adl metakarakterimiz, kendisinden nce gelen karakterin hi


bulunmad (yani sfr sayda olduu) ve bir adet bulunduu durumlar iine alyor. Bu
yzden de kt olarak bize sadece st ve sat elerini veriyor.
imdi bu metakarakteri kullanarak gerek hayatta karmza kabilecek bir rnek verelim.
Bu metakarakterin tanmna tekrar bakarsak, olsa da olur olmasa da olur diyebileceimiz
durumlar iin bu metakarakterin rahatlkla kullanlabileceini grrz. yle bir rnek
verelim: Diyelim ki bir metin zerinde arama yapacaksnz. Aradnz kelime uluslararas:

802 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

metin = """Uluslararas hukuk, uluslar aras ilikiler altnda bir


disiplindir. Uluslararas ilikilerin hukuksal boyutunu bilimsel bir
disiplin iinde inceler. Devletleraras hukuk da denir. Ancak uluslar
aras ilikilere yeni aktrlerin girii bu dal sadece devletleraras
olmaktan karmtr."""

Not: Bu metin http://tr.wikipedia.org/wiki/Uluslararas%C4%B1_hukuk adresinden alnp


zerinde ufak deiiklikler yaplmtr.

imdi yapmak istediimiz ey uluslararas kelimesini bulmak. Ama dikkat ederseniz metin
iinde uluslararas kelimesi ayn zamanda uluslar aras eklinde de geiyor. Bizim bu iki
kullanm da kapsayacak bir dzenli ifade yazmamz gerekecek...
>>> nesne = re.findall("[Uu]luslar ?aras", metin)
>>> for i in nesne:
... print(i)

Verdiimiz dzenli ifade kalbn dikkatlice inceleyin. Bildiiniz gibi, ? metakarakteri,


kendinden nce gelen karakterin (dzenli ifade kalbn) sfr veya bir kez getii durumlar
aryor. Burada ? semboln karakterinden, yani boluk karakterinden sonra kullandk.
Dolaysyla, boluk karakterinin sfr veya bir kez getii durumlar hedeedik. Bu ekilde
hem uluslar aras hem de uluslararas kelimesini ayklam olduk. Dzenli ifademizde
ayrca yle bir ey daha yazdk: [Uu]. Bu da gerekiyor. nk metnimiz iinde uluslararas
kelimesinin byk hare balad yerler de var... Bildiiniz gibi, uluslar ve Uluslar
kelimeleri asla ayn deildir. Dolaysyla hem u harni hem de U harni bulmak iin, daha
nce rendiimiz [] metakarakterini kullanyoruz.

46.2.6 { } (Kme Parantezi)

{ } adl metakarakterimiz yardmyla bir elemeden ka adet istediimizi belirtebiliyoruz. Yine


ayn rnek zerinden gidelim:
>>> for i in yeniliste:
... if re.match("sa{3}t",i):
... print(i)
...
saaat

Burada a karakterinin 3 kez tekrar etmesini istediimizi belirttik. Python da bu emrimizi


hemen yerine getirdi.
Bu metakarakterin ilgin bir zellii daha vardr. Kme iinde iki farkl say yazarak, bir
karakterin en az ve en ok ka kez tekrar etmesini istediimizi belirtebiliriz. rnein:
>>> for i in yeniliste:
... if re.match("sa{0,3}t",i):
... print(i)
...
st
sat
saat
saaat

sa{0,3}t ifadesiyle, a harnin en az sfr kez, en ok da kez tekrar etmesini istediimiz


syledik. Dolaysyla, a harnin sfr, bir, iki ve kez tekrar ettii durumlar ayklanm oldu.

46.2. Metakarakterler 803


Python 3 iin Trke Klavuz, Srm 3

Bu say iftlerini deitirerek daha farkl sonular elde edebilirsiniz. Ayrca hangi say iftinin
daha nce rendiimiz ? metakarakteriyle ayn ii yaptn bulmaya aln...

46.2.7 ^ (apka)

^ sembolnn iki ilevi var. Birinci ilevi, bir karakter dizisinin en bandaki veriyi
sorgulamaktr. Yani aslnda match() metodunun varsaylan olarak yerine getirdii ilevi bu
metakarakter yardmyla aka belirterek yerine getirebiliyoruz. u rnee bakalm:
>>> a = ['23BH56', 'TY76Z', '4Y7UZ', 'TYUDZ',
... '34534', '1agAY54']
>>> for i in a:
... if re.search("[A-Z]+[0-9]",i):
... print(i)
...
23BH56
TY76Z
4Y7UZ
1agAY54

Bir de una bakalm:


>>> for i in a:
... nesne = re.search("[A-Z]+[0-9]",i)
... if nesne:
... print(nesne.group())
...
BH5
TY7
Y7
AY5

Dikkat ederseniz, u son verdiimiz kod olduka hassas bir kt verdi bize. ktdaki btn
deerler, aynen dzenli ifademizde belirttiimiz gibi, yan yana bir veya daha fazla harf ieriyor
ve sonra da bir say ile devam ediyor. Bu farklln nedeni, ilk kodlarda print(i) ifadesini
kullanmamz. Bu durumun ktlarmz nasl deitirdiine dikkat edin. Bir de u rnee
bakalm:
>>> for i in a:
... if re.match("[A-Z]+[0-9]",i):
... print(i)
...
TY76Z

Burada sadece TY76Z ktsn almamzn nedeni, match() metodunun karakter dizilerinin en
bana bakyor olmas. Ayn etkiyi search() metoduyla da elde etmek iin, balkta geen ^
(apka) sembolnden yararlanacaz:
>>> for i in a:
... nesne = re.search("^[A-Z]+[0-9]",i)
... if nesne:
... print(nesne.group())
...
TY7

Grdnz gibi, ^ (apka) metakarakteri search() metodunun, karakter dizilerinin sadece


en bana bakmasn salad. O yzden de bize sadece, TY7 ktsn verdi. Hatrlarsanz ayn

804 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

kodu, apkasz olarak, u ekilde kullanmtk yukarda:


>>> for i in a:
... nesne = re.search("[A-Z]+[0-9]",i)
... if nesne:
... print(nesne.group())
...
BH5
TY7
Y7
AY5

Grdnz gibi, apka sembol olmadnda search() metodu karakter dizisinin bana
bakmakla yetinmiyor, ayn zamanda karakter dizisinin tamamn taryor. Biz yukardaki koda
bir ^ sembol ekleyerek, metodumuzun sadece karakter dizisinin en bana bakmasn
istedik. O da emrimize sadakatle uydu. Burada dikkatimizi ekmesi gereken baka bir nokta
da search() metodundaki ktnn krplm olmas. Dikkat ettiyseniz, search() metodu bize
enin tamamn vermedi. elerin yalnzca [A-Z]+[0-9] kalbna uyan ksmlarn kesip att
nmze. nk biz ona tersini sylemedik. Eer elerin tamamn istiyorsak bunu ak ak
belirtmemiz gerekir:
>>> for i in a:
... nesne = re.search("[A-Z]+[0-9].*",i)
... if nesne:
... print(nesne.group())
...
BH56
TY76Z
Y7UZ
AY54

Veya metodumuzun karakter dizisinin sadece en bana bakmasn istersek:


>>> for i in a:
... nesne = re.search("^[A-Z]+[0-9].*",i)
... if nesne:
... print(nesne.group())
...
TY76Z

Bu kodlarda dzenli ifade kalbnn sonuna .* semboln eklediimize dikkat edin.


Bylelikle metodumuzun sonu herhangi bir ekilde biten eleri bize vermesini saladk...
Bata da sylediimiz gibi, ^ metakarakterinin, karakter dizilerinin en bana demir atmak
dnda baka bir grevi daha vardr: Hari anlamna gelmek... Bu grevini sadece
[] metakarakterinin iinde kullanld zaman yerine getirir. Bunu bir rnekle grelim.
Yukardaki listemiz zerinde yle bir szge uygulayalm ki, 1agAY54 esi ktlarmz
arasnda grnmesin... Bu eyi avlayabilmek iin kullanmamz gereken dzenli ifade yle
olacaktr: [0-9A-Z][^a-z]+
>>> for i in a:
... nesne = re.match("[0-9A-Z][^a-z]+",i)
... if nesne:
... print(nesne.group())

Burada u ltlere sahip bir e aryoruz:


1. Aradmz e bir say veya byk harf ile balamal

46.2. Metakarakterler 805


Python 3 iin Trke Klavuz, Srm 3

2. En bataki say veya byk harften sonra kk harf GELMEMEL (Bu lt ^ iareti
salyor)
3. stelik bu kk harf gelmeme durumu bir veya daha fazla sayda tekrar etmeli... Yani
bataki say veya byk harften sonra ka tane olursa olsun asla kk harf gelmemeli
(Bu lt de + iareti salyor)
Bu ltlere uymayan tek e 1agAY54 olacaktr. Dolaysyla bu e ktda grnmeyecek...
Burada, ^ iaretinin nasl kullanldna ve kk hareri nasl darda braktna dikkat
edin. Unutmayalm, bu ^ iaretinin hari anlam sadece [] metakarakterinin iinde
kullanld zaman geerlidir.

46.2.8 $ (Dolar)

Bir nceki blmde ^ iaretinin, karakter dizilerinin en bana demir attn sylemitik.
Yani bu sembol arama/eletirme ileminin karakter dizisinin en bandan balamasn
salyordu. Bu sembol bir bakma karakter dizilerinin nasl balayacan belirliyordu. te
imdi greceimiz dolar iareti de ($) karakter dizilerinin nasl biteceini belirliyor. Bu soyut
aklamalar somut bir rnekle balayalm:
>>> liste = ["at", "katk", "fakat", "atk", "rahat",
... "mat", "yat", "sat", "satlk", "katlm"]

Grdnz gibi, elimizde on elik bir liste var. Diyelim ki biz bu listeden, at hecesiyle
biten kelimeleri ayklamak istiyoruz:
>>> for i in liste:
... if re.search("at$",i):
... print(i)
...
at
fakat
rahat
mat
yat
sat

Burada $ metakarakteri sayesinde aradmz karakter dizisinin nasl bitmesi gerektiini


belirleyebildik. Eer biz at ile balayan btn eleri ayklamak isteseydik ne yapmamz
gerektiini biliyorsunuz:
>>> for i in liste:
... if re.search("^at",i):
... print(i)
...
at
atk

Grdnz gibi, ^ iareti bir karakter dizisinin nasl balayacan belirlerken, $ iareti
ayn karakter dizisinin nasl biteceini belirliyor. Hatta istersek bu metakarakterleri birlikte de
kullanabiliriz:
>>> for i in liste:
... if re.search("^at$",i):
... print(i)

806 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

...
at

Sonu tam da beklediimiz gibi oldu. Verdiimiz dzenli ifade kalb ile at ile balayan ve
ayn ekilde biten karakter dizilerini aykladk. Bu da bize at ktsn verdi.

46.2.9 \ (Ters Bl)

Bu iaret bildiimiz ka dizisidir... Peki burada ne ii var? imdiye kadar rendiimiz


konulardan grdnz gibi, Pythondaki dzenli ifadeler asndan zel anlam tayan bir
takm semboller/metakarakterler var. Bunlar kendileriyle elemiyorlar. Yani bir karakter
dizisi iinde bu sembolleri aryorsak eer, bunlarn tadklar zel anlam yznden bu
sembolleri ayklamak hemencecik mmkn olmayacaktr. Yani mesela biz $ semboln
aryor olsak, bunu Pythona nasl anlatacaz? nk bu sembol yazdmz zaman Python
bunu farkl alglyor. Laf dolandrmadan hemen bir rnek verelim...
Diyelim ki elimizde yle bir liste var:
>>> liste = ["10$", "25", "20$", "10TL", "25"]

Amacmz bu listedeki dolarl deerleri ayklamaksa ne yapacaz? unu deneyelim nce:


>>> for i in liste:
... if re.match("[0-9]+$",i):
... print(i)

Python $ iaretinin zel anlamndan dolay, bizim sayyla biten bir karakter dizisi aradmz
zannedecek, dolaysyla da herhangi bir kt vermeyecektir. nk listemizde sayyla biten
bir karakter dizisi yok... Peki biz ne yapacaz? te bu noktada \ metakarakteri devreye
girecek... Hemen bakalm:
>>> for i in liste:
... if re.match("[0-9]+\$",i):
... print(i)
...
10$
20$

Grdnz gibi, \ semboln kullanarak $ iaretinin zel anlamndan katk... Bu


metakarakteri de ksaca anlattmza gre yeni bir metakarakterle yolumuza devam
edebiliriz...

46.2.10 | (Dik izgi)

Bu metakarakter, birden fazla dzenli ifade kalbn birlikte eletirmemizi salar. Bu ne


demek? Hemen grelim:
>>> liste = ["at", "katk", "fakat", "atk", "rahat",
... "mat", "yat", "sat", "satlk", "katlm"]
>>> for i in liste:
... if re.search("^at|at$",i):
... print(i)
...
at
fakat

46.2. Metakarakterler 807


Python 3 iin Trke Klavuz, Srm 3

atk
rahat
mat
yat
sat

Grdnz gibi | metakarakterini kullanarak bata ve sonda at hecesini ieren kelimeleri


aykladk. Ayn ekilde, mesela, renkleri ieren bir listeden belli renkleri de ayklayabiliriz bu
metakarakter yardmyla...
>>> for i in renkler:
... if re.search("krmz|mavi|sar", i):
... print(i)

Srada son metakarakterimiz olan () var...

46.2.11 ( ) (Parantez)

Bu metakarakter yardmyla dzenli ifade kalplarn gruplayacaz. Bu metakarakter bizim bir


karakter dizisinin istediimiz ksmlarn ayklamamzda ok byk kolaylklar salayacak.
Diyelim ki biz http://www.istihza.com/py2/icindekiler_python.html adresindeki btn
balklar ve bu balklara ait html dosyalarn bir liste halinde almak istiyoruz. Bunun iin
yle bir ey yazabiliriz:
import re
from urllib.request import urlopen

url = "http://belgeler.istihza.com/py3/index.html"
f = urlopen(url)

regex = 'href=".+html">.+</a>'

for i in f:
nesne = re.search(regex, str(i, 'utf-8'))
if nesne:
print(nesne.group())

Burada yaptmz ey u:
1. ncelikle http://belgeler.istihza.com/py3/index.html sayfasn urllib modl
yardmyla atk. Amacmz bu sayfadaki balklar ve bu balklara ait html dosyalarn
listelemek
2. Ardndan, btn sayfay taramak iin basit bir for dngs kurduk
3. Dzenli ifade kalbmz yle yazdk: <href=".+html">.+</a> nk bahsi geen
web sayfasndaki html uzantl dosyalar bu ekilde gsteriliyor. Bu durumu, web
taraycnzda http://belgeler.istihza.com/py3/index.html sayfasn ap sayfa kaynan
grntleyerek teyit edebilirsiniz. (Firefoxta CTRL+Uya basarak sayfa kaynan
grebilirsiniz)
4. Yazdmz dzenli ifade kalb iinde dikkatimizi ekmesi gereken baz noktalar var:
Kalbn (.+html) ksmnda geen + metakarakteri kendisinden nce gelen dzenli
ifadenin bir veya daha fazla sayda tekrar eden elemelerini buluyor. Burada
+ metakarakterinden nce gelen dzenli ifade, kendisi de bir metakarakter olan

808 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

. sembol... Bu sembol bildiiniz gibi, herhangi bir karakter anlamna geliyor.


Dolaysyla .+ ifadesi u demek oluyor: Bana bir veya daha fazla sayda tekrar eden
btn karakterleri bul! Dolaysyla burada (.+html) ifadesini birlikte dnrsek,
yazdmz ey u anlama geliyor: Bana html ile biten btn karakter dizilerini bul!
5. http://belgeler.istihza.com/py3/index.html adresinin kaynana baktmz
zaman aradmz bilgilerin hep u ekilde olduunu gryoruz:
href=kitap_hakkinda.html>Bu Kitap Hakkxc4xb1nda</a> Dolaysyla aslnda dzenli
ifade kalbmz yazarken yaptmz ey, dzenli ifademizi kaynakta grnen ablona
uydurmak...
6. Ayrca ktdaki Trke karakterlerin dzgn grnmesi iin de bayt dizilerini karakter
dizisine dntrrken utf-8 kodlamasn kullandk.
Yukarda verdiimiz kodlar altrdmz zaman aldmz kt u ekilde oluyor:
b'href="kitap_hakkinda.html">Bu Kitap Hakk\xc4\xb1nda</a>'
b'href="python_hakkinda.html">Python Hakk\xc4\xb1nda</a>'
...

Hemen hemen amacmza ulatk saylr. Ama grdnz gibi ktmz biraz karmak.
Bunlar istediimiz gibi dzenleyebilsek iyi olurdu, deil mi? Mesela bu ktlar u ekilde
dzenleyebilmek ho olurdu:
Balk: ANA SAYFA; Balant: index.html

te bu blmde greceimiz ( ) metakarakteri istediimiz eyi yapmada bize yardmc


olacak.
Dilerseniz en bata verdiimiz kodlara tekrar dnelim:
import re
from urllib.request import urlopen

url = "http://belgeler.istihza.com/py3/index.html"
f = urlopen(url)

regex = 'href=".+html">.+</a>'

for i in f:
nesne = re.search(regex, str(i, 'utf-8'))
if nesne:
print(nesne.group())

imdi bu kodlarda u deiiklii yapyoruz:


import re
from urllib.request import urlopen

url = "http://belgeler.istihza.com/py3/index.html"
f = urlopen(url)

kt = "Balk: {};\nBalant: {}\n"


regex = 'href="(.+html)">(.+)</a>'

for i in f:
nesne = re.search(regex, str(i, 'utf-8'))
if nesne:

46.2. Metakarakterler 809


Python 3 iin Trke Klavuz, Srm 3

print(kt.format(nesne.group(2),
nesne.group(1)))

Kodlarda yaptmz deiikliklere dikkat edin ve anlamaya aln. Baz noktalar gznze
karanlk grndyse hi endie etmeyin, nk bir sonraki blmde btn karanlk noktalar
tek tek aklayacaz. Burada en azndan, ( ) metakarakterini kullanarak dzenli ifadenin
baz blmlerini nasl grupladmza dikkat edin.
Bu arada, elbette www.istihza.com sitesinde herhangi bir deiiklik olursa yukardaki kodlarn
istediiniz kty vermeyeceini bilmelisiniz. nk yazdmz dzenli ifade istihza.com
sitesinin sayfa yapsyla sk skya balantldr.

46.3 Eleme Nesnelerinin Metotlar

46.3.1 group() metodu

Bu blmde dorudan dzenli ifadelerin deil, ama dzenli ifadeler kullanlarak retilen
eleme nesnelerinin bir metodu olan group() metodundan bahsedeceiz. Esasnda biz
bu metodu nceki blmlerde de kullanmtk. Ama burada bu metoda biraz daha ayrntl
olarak bakacaz.
Daha nceki blmlerden hatrlayacanz gibi, bu metot dzenli ifadeleri kullanarak
eletirdiimiz karakter dizilerini grme imkan salyordu. Bu blmde bu metodu ( )
metakarakteri yardmyla daha verimli bir ekilde kullanacaz. sterseniz ilk olarak yle basit
bir rnek verelim:
>>> kardiz = "python bir programlama dilidir"
>>> nesne = re.search("(python) (bir) (programlama) (dilidir)", kardiz)
>>> print(nesne.group())

python bir programlama dilidir

Burada dzenli ifade kalbmz nasl grupladmza dikkat edin. print(nesne.group())


komutunu verdiimizde eleen karakter dizileri ekrana dkld. imdi bu grupladmz
blmlere tek tek erielim:
>>> nesne.group(0)

'python bir programlama dilidir'

Grdnz gibi, 0 indeksi eleen karakter dizisinin tamamn veriyor. Bir de una bakalm:
>>> nesne.group(1)

'python'

Burada 1 numaral grubun esi olan pythonu aldk. Gerisinin nasl olacan tahmin
edebilirsiniz:
>>> nesne.group(2)

'bir'

>>> nesne.group(3)

810 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

'programlama'

>>> nesne.group(4)

'dilidir'

Bu metodun bize ilerde ne byk kolaylklar salayacan az ok tahmin ediyorsunuzdur.


sterseniz kullanabileceimiz metotlar tekrar listeleyelim:
>>> dir(nesne)

Bu listede group() dnda bir de groups() adl bir metodun olduunu gryoruz. imdi
bunun ne i yaptna bakalm.

46.3.2 groups() metodu

Bu metot, bize kullanabileceimiz btn gruplar bir demet halinde sunar:


>>> nesne.groups()

('python', 'bir', 'programlama', 'dilidir')

imdi isterseniz bir nceki blmde yaptmz rnee geri dnelim:


import re
from urllib.request import urlopen

url = "http://belgeler.istihza.com/py3/index.html"
f = urlopen(url)

kt = "Balk: {};\nBalant: {}\n"


regex = 'href="(.+html)">(.+)</a>'

for i in f:
nesne = re.search(regex, str(i, 'utf-8'))
if nesne:
print(kt.format(nesne.group(2),
nesne.group(1)))

Bu kodlarda son satr yle deitirelim:


import re
from urllib.request import urlopen

url = "http://belgeler.istihza.com/py3/index.html"
f = urlopen(url)

kt = "Balk: {};\nBalant: {}\n"


regex = 'href="(.+html)">(.+)</a>'

for i in f:
nesne = re.search(regex, str(i, 'utf-8'))
if nesne:
print(nesne.groups())

Grdnz gibi una benzer ktlar elde ediyoruz:

46.3. Eleme Nesnelerinin Metotlar 811


Python 3 iin Trke Klavuz, Srm 3

('kitap_hakkinda.html', 'Bu Kitap Hakknda')


('python_hakkinda.html', 'Python Hakknda')
('temel_komut_satiri_bilgisi.html', 'Temel Komut Satr Bilgisi')
('path.html', 'YOL (<em>PATH</em>) Kavram')
('kurulum.html', 'Python Nasl Kurulur?')
...
...
...

Demek ki (nesne.groups()) komutu bize ( ) metakarakteri ile daha nceden gruplam


olduumuz eleri bir demet olarak veriyor. Biz de bu demetin elerine daha sonradan
rahatlkla eriebiliyoruz...
Bylece eletirme nesnelerinin en sk kullanlan iki metodunu grm olduk. Bunlar daha
sonraki rneklerimizde de bol bol kullanacaz. O yzden imdilik bu konuya ara verelim.

46.4 zel Diziler

Dzenli ifadeler iinde metakarakterler dnda, zel anlamlar tayan baz baka ifadeler de
vardr. Bu blmde bu zel dizileri inceleyeceiz: Boluk karakterinin yerini tutan zel dizi: \s
Bu sembol, bir karakter dizisi iinde geen boluklar yakalamak iin kullanlr. rnein:
>>> a = ["5 Ocak", "27Mart", "4 Ekim", "Nisan 3"]
>>> for i in a:
... nesne = re.search("[0-9]\\s[A-Za-z]+",i)
... if nesne:
... print(nesne.group())
...
5 Ocak
4 Ekim

Yukardaki rnekte, bir say ile balayan, ardndan bir adet boluk karakteri ieren, sonra
da bir byk veya kk hare devam eden karakter dizilerini aykladk. Burada boluk
karakterini \s simgesi ile gsterdiimize dikkat edin.

46.4.1 Ondalk Saylarn Yerini Tutan zel Dizi: \d

Bu sembol, bir karakter dizisi iinde geen ondalk saylar eletirmek iin kullanlr. Buraya
kadar olan rneklerde bu ilevi yerine getirmek iin [0-9] ifadesinden yararlanyorduk. imdi
artk ayn ilevi daha ksa yoldan, \d dizisi ile yerine getirebiliriz. sterseniz yine yukardaki
rnekten gidelim:
>>> a = ["5 Ocak", "27Mart", "4 Ekim", "Nisan 3"]
>>> for i in a:
... nesne = re.search("\d\s[A-Za-z]+",i)
... if nesne:
... print(nesne.group())
...
5 Ocak
4 Ekim

Burada, [0-9] yerine \d yerletirerek daha ksa yoldan sonuca vardk.

812 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

46.4.2 Alfanmerik Karakterlerin Yerini Tutan zel Dizi: \w

Bu sembol, bir karakter dizisi iinde geen alfanmerik karakterleri ve buna ek olarak _
karakterini bulmak iin kullanlr. u rnee bakalm:
>>> a = "abc123_$%+"
>>> print(re.search("\w*", a).group())

abc123_

\w zel dizisinin hangi karakterleri elediine dikkat edin. Bu zel dizi u ifadeyle ayn
anlama gelir:
[A-Za-z0-9_]

Dzenli ifadeler iindeki zel diziler genel olarak bunlardan ibarettir. Ama bir de bunlarn
byk hari versiyonlar vardr ki, nemli olduklar iin onlar da inceleyeceiz.
Grdnz gibi;
1. \s zel dizisi boluk karakterlerini avlyor
2. \d zel dizisi ondalk saylar avlyor
3. \w zel dizisi alfanmerik karakterleri ve _ karakterini avlyor
Dedik ki, bir de bunlarn byk hari versiyonlar vardr. te bu byk hari versiyonlar da
yukardaki dizilerin yapt iin tam tersini yapar. Yani:
1. \S zel dizisi boluk olmayan karakterleri avlar
2. \D zel dizisi ondalk say olmayan karakterleri avlar. Yani [^0-9] ile edeerdir.
3. \W zel dizisi alfanmerik olmayan karakterleri ve _ olmayan karakterleri avlar. Yani
[^A-Za-z0-9_] ile edeerdir.
\D ve \W dizilerinin yeterince anlalr olduunu zannediyorum. Burada sanrm sadece
S dizisi bir rnekle somutlatrlmay hakediyor:
>>> a = ["5 Ocak", "27Mart", "4 Ekim", "Nisan 3"]
>>> for i in a:
... nesne = re.search("\d+\S\w+",i)
... if nesne:
... print(nesne.group())
...
27Mart

Burada \S zel dizisinin listede belirtilen konumda boluk iermeyen eyi nasl bulduuna
dikkat edin.
imdi bu zel diziler iin genel bir rnek verip konuyu kapatalm...
Bilgisayarmzda u bilgileri ieren adres.txt adl bir dosya olduunu varsayyoruz:
esra : istinye 05331233445 esma : levent 05322134344 sevgi : dudullu
05354445434 kemal : sanayi 05425455555 osman : tahtakale 02124334444
metin : taksim 02124344332 kezban : caddebostan 02163222122

Amacmz bu dosyada yer alan isim ve telefon numaralarn isim > telefon numaras eklinde
almak:

46.4. zel Diziler 813


Python 3 iin Trke Klavuz, Srm 3

import re
dosya = open("adres.txt")
for i in dosya.readlines():
nesne = re.search("(\w+)\s+:\s(\w+)\s+(\d+)",i)
if nesne:
print("{} > {}".format(nesne.group(1), nesne.group(3)))

Burada formlmz u ekilde: Bir veya daha fazla karakter + bir veya daha fazla boluk
+ : iareti + bir adet boluk + bir veya daha fazla say
sterseniz bu blm ok basit bir soruyla kapatalm. Sorumuz u:
Elimizde u adresteki yn var: http://www.istihza.com/denemeler/yigin.txt
Yapmanz gereken, bu yn iindeki gizli mesaj dzenli ifadeleri kullanarak bulmak...

46.5 Dzenli fadelerin Derlenmesi

46.5.1 compile() metodu

En bata da sylediimiz gibi, dzenli ifadeler karakter dizilerine gre biraz daha yava
alrlar. Ancak dzenli ifadelerin ileyiini hzlandrmann da baz yollar vardr. Bu yollardan
biri de compile() metodunu kullanmaktr. compile kelimesi ngilizcede derlemek anlamna
gelir. te biz de bu compile() metodu yardmyla dzenli ifade kalplarmz kullanmadan
nce derleyerek daha hzl almalarn salayacaz. Kk boyutlu projelerde compile()
metodu pek hissedilir bir fark yaratmasa da zellikle byk apl programlarda bu metodu
kullanmak olduka faydal olacaktr.
Basit bir rnekle balayalm:
>>> liste = ["Python2.7", "Python3.2", "Python3.3",
... "Python3.4", "Java"]
>>> derli = re.compile("[A-Za-z]+[0-9]\.[0-9]")
>>> for i in liste:
... nesne = derli.search(i)
... if nesne:
... print(nesne.group())
...
Python2.7
Python3.2
Python3.3
Python3.4

Burada ncelikle dzenli ifade kalbmz derledik. Derleme ilemini nasl yaptmza dikkat
edin. Derlenecek dzenli ifade kalbn compile() metodunda parantez iinde belirtiyoruz.
Daha sonra search() metodunu kullanrken ise, re.search() demek yerine, derli.search()
eklinde bir ifade kullanyoruz. Ayrca dikkat ederseniz derli.search() kullanmnda
parantez iinde sadece eleecek karakter dizisini kullandk (i). Eer derleme ilemi yapmam
olsaydk, hem bu karakter dizisini, hem de dzenli ifade kalbn yan yana kullanmamz
gerekecektir. Ama dzenli ifade kalbmz yukarda derleme ilemi esnasnda belirttiimiz
iin, bu kalb ikinci kez yazmamza gerek kalmad. Ayrca burada kullandmz dzenli ifade
kalbna da dikkat edin. Nasl bir ablon oturttuumuzu anlamaya aln. Grdnz gibi,
liste elerinde bulunan . iaretini eletirmek iin dzenli ifade kalb iinde \. ifadesini

814 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

kullandk. nk bildiiniz gibi, tek bana . iaretinin Python asndan zel bir anlam var.
Dolaysyla bu zel anlamdan kamak iin \ iaretini de kullanmamz gerekiyor.

46.5.2 compile() ile Derleme Seenekleri

Bir nceki blmde compile() metodunun ne olduunu, ne ie yaradn ve nasl


kullanldn grmtk. Bu blmde ise compile (derleme) ilemi srasnda kullanlabilecek
seenekleri anlatacaz.

re.IGNORECASE veya re.I

Bildiiniz gibi, Pythonda byk-kk harer nemlidir. Yani eer python kelimesini
aryorsanz, alacanz ktlar arasnda Python olmayacaktr. nk python ve Python
birbirlerinden farkl iki karakter dizisidir. te re.IGNORECASE veya ksaca re.I adl derleme
seenekleri bize byk-kk harfe dikkat etmeden arama yapma imkan salar. Hemen bir
rnek verelim:
import re

metin = """Programlama dili, programcnn bir bilgisayara ne yapmasn


istediini anlatmasnn standartlatrlm bir yoludur. Programlama
dilleri, programcnn bilgisayara hangi veri zerinde ilem yapacan,
verinin nasl depolanp iletileceini, hangi koullarda hangi ilemlerin
yaplacan tam olarak anlatmasn salar. u ana kadar 2500den fazla
programlama dili yaplmtr. Bunlardan bazlar: Pascal, Basic, C, C#,
C++, Java, Cobol, Perl, Python, Ada, Fortran, Delphi programlama
dilleridir."""

derli = re.compile("programlama",re.IGNORECASE)
print(derli.findall(metin))

Bu program altrdmzda u kty alyoruz:


['Programlama', 'Programlama', 'programlama', 'programlama']

Not: Bu metin http://tr.wikipedia.org/wiki/Programlama_dili adresinden alnmtr.

Grdnz gibi, metinde geen hem programlama kelimesini hem de Programlama


kelimesini ayklayabildik. Bunu yapmamz salayan ey de re.IGNORECASE adl derleme
seenei oldu. Eer bu seenei kullanmasaydk, ktda yalnzca programlama kelimesini
grrdk. nk aradmz ey aslnda programlama kelimesi idi. Biz istersek
re.IGNORECASE yerine ksaca re.I ifadesini de kullanabiliriz. Ayn anlama gelecektir...

re.DOTALL veya re.S

Bildiiniz gibi, metakarakterler arasnda yer alan . sembol herhangi bir karakterin
yerini tutuyordu. Bu metakarakter btn karakterlerin yerini tutmak zere kullanlabilir.
Hatrlarsanz, . metakarakterini anlatrken, bu metakarakterin, yeni satr karakterinin yerini
tutmayacan sylemitik. Bunu bir rnek yardmyla grelim. Diyelim ki elimizde yle bir
karakter dizisi var:

46.5. Dzenli fadelerin Derlenmesi 815


Python 3 iin Trke Klavuz, Srm 3

>>> a = "Ben Python,\nMonty Python"

Bu karakter dizisi iinde Python kelimesini temel alarak bir arama yapmak istiyorsak eer,
kullanacamz u kod istediimiz eyi yeterince yerine getiremeyecektir:
>>> print(re.search("Python.*", a).group())

Bu kod u kty verecektir:


Python,

Bunun sebebi, . metakarakterinin \n (yeni satr) ka dizisini dikkate almamasdr. Bu


yzden bu ka dizisinin tesine geip orada arama yapmyor. Ama imdi biz ona bu yetenei
de kazandracaz:
>>> derle = re.compile("Python.*", re.DOTALL)
>>> nesne = derle.search(a)
>>> if nesne:
... print(nesne.group())

re.DOTALL seeneini sadece re.S eklinde de ksaltabilirsiniz...

46.6 Dzenli fadelerle Metin/Karakter Dizisi Deitirme lemleri

46.6.1 sub() metodu

imdiye kadar hep dzenli ifadeler yoluyla bir karakter dizisini nasl eletireceimizi
inceledik. Ama tabii ki dzenli ifadeler yalnzca bir karakter dizisi bulmakla ilgili deildir.
Bu ara ayn zamanda bir karakter dizisini deitirmeyi de kapsar. Bu i iin temel
olarak iki metot kullanlr. Bunlardan ilki sub() metodudur. Bu blmde sub() metodunu
inceleyeceiz.
En basit ekliyle sub() metodunu u ekilde kullanabiliriz:
>>> a = "Krmz balkl kz, krmz elma dolu sepetiyle \
... anneannesinin evine gidiyormu!"
>>> derle = re.compile("krmz", re.IGNORECASE)
>>> print(derle.sub("yeil", a))

Burada karakter dizimiz iinde geen btn krmz kelimelerini yeil kelimesiyle
deitirdik. Bunu yaparken de re.IGNORECASE adl derleme seeneinden yararlandk.
Elbette sub() metoduyla daha karmak ilemler yaplabilir. Bu noktada yle bir hatrlatma
yapalm. Bu sub() metodu karakter dizilerinin replace() metoduna ok benzer. Ama tabii ki
sub() metodu hem kendi bana replace() metodundan ok daha gldr, hem de beraber
kullanlabilecek derleme seenekleri sayesinde replace() metodundan ok daha esnektir.
Ama tabii ki, eer yapmak istediiniz i replace() metoduyla halledilebiliyorsa en doru yol,
replace() metodunu kullanmaktr...
imdi bu sub() metodunu kullanarak biraz daha karmak bir ilem yapacaz. Aadaki
metne bakalm:
metin = """Karadeniz Erelisi denince akla ilk olarak kmr ve demir-elik
gelir. Kokusu ve tadyla dnyaya nam salm mehur Osmanl ilei ise ismini

816 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

verdii festival gnleri dnda pek hatrlanmaz. Oysa in'den Arnavutky'e


oradan da Ereli'ye getirilen krallarn meyvesi ilek, burada geirdii deiim
sonucu tadna doyulmaz bir hal alr. Ereli'nin havasndan m suyundan m
bilinmez, kokusu, tad bambaka bir hale dnr ve mehur Osmanl ilei
unvann hak eder. Bu nazik ve aromal ilekten yaplan reel de likr de bir
baka olur. Bu yl dokuzuncusu dzenlenen Uluslararas Osmanl ilei Kltr
Festivali'nde 36 retici arasnda yetitirdii ileklerle birinci olan Kocaali
Ky'nden Gner zdemir, ylda bir ton rn alyor. 60 yandaki zdemir,
ileklerinin srrn youn ilgiye ve iten duyduu sevgiye balyor: "Erkekler
bahemize giremez. Koca ayaklaryla ezerler ileklerimizi" ilei toplamann zor
olduunu syleyen Aye zhan da ocukluundan bu yana ilek bahesinde
alyor. Her sabah 04.00'te kalkan zhan, ileklerini zenle suluyor. Kasm
banda ektii ilek fideleri haziran banda meyve veriyor."""

Not: Bu metin http://www.radikal.com.tr/haber.php?haberno=40130 adresinden alnmtr.

Gelin bu metin iinde geen ilek kelimelerini erik kelimesi ile deitirelim. Ama bunu
yaparken, metin iinde ilek kelimesinin ilek eklinde de getiine dikkat edelim. Ayrca
Trke kurallar gerei bu ilek kelimesinin baz yerlerde nsz yumuamasna urayarak
ile- ekline dntn de unutmayalm.
Bu metin iinde geen ilek kelimelerini erikle deitirmek iin birka yol kullanabilirsiniz.
Birinci yolda, her deiiklik iin ayr bir dzenli ifade oluturulabilir. Ancak bu yolun
dezavantaj, metnin de birka kez kopyalanmasn gerektirmesidir. nk ilk dzenli ifade
oluturulup buna gre metinde bir deiiklik yapldktan sonra, ilk deiiklikleri ieren metnin,
farkl bir metin olarak kopyalanmas gerekir (metin2 gibi...). Ardndan ikinci deiiklik
yaplaca zaman, bu deiikliin metin2 zerinden yaplmas gerekir. Ayn ekilde bu metin
de, mesela, metin3 eklinde tekrar kopyalanmaldr. Bundan sonraki yeni bir deiiklik de
bu metin3 zerinden yaplacaktr... Bu durum bu ekilde uzar gider... Metni tekrar tekrar
kopyalamak yerine, dzenli ifadeleri kullanarak yle bir zm de retebiliriz:
import re

derle = re.compile("ile[k]", re.IGNORECASE)

def degistir(nesne):
a = {"ile":"eri", "ile":"Eri", "ilek":"Erik", "ilek":"erik"}
b = nesne.group().split()
for i in b:
return a[i]

print(derle.sub(degistir, metin))

Grdnz gibi, sub() metodu, argman olarak bir fonksiyon da alabiliyor. Yukardaki
kodlar biraz kark grnm olabilir. Tek tek aklayalm...
ncelikle u satra bakalm:
derle = re.compile("ile[k]", re.IGNORECASE)

Burada amacmz, metin iinde geen ilek ve ile kelimelerini bulmak. Neden ile?
nk ilek kelimesi bir sesli harften nce geldiinde sonundaki k har ye dnyor.
Bu seenekli yapy, daha nceki blmlerde grdmz [ ] adl metakarakter yardmyla
oluturduk. Dzenli ifade kalbmzn hem byk hareri hem de kk hareri ayn anda
bulmas iin re.IGNORECASE seeneinden yararlandk.

46.6. Dzenli fadelerle Metin/Karakter Dizisi Deitirme lemleri 817


Python 3 iin Trke Klavuz, Srm 3

imdi de u satrlara bakalm:


def degistir(nesne):
a = {"ile":"eri", "ile":"Eri", "ilek":"Erik", "ilek":"erik"}
b = nesne.group().split()
for i in b:
return a[i]

Burada, daha sonra sub() metodu iinde kullanacamz fonksiyonu yazyoruz. Fonksiyonu,
def degistir(nesne) eklinde tanmladk. Burada nesne adl bir argman kullanmamzn
nedeni, fonksiyon iinde group() metodunu kullanacak olmamz. Bu metodu fonksiyon
iinde nesne adl argmana balayacaz. Bu fonksiyon, daha sonra yazacamz sub()
metodu tarafndan arldnda, yaptmz arama ilemi sonucunda ortaya kan eleme
nesnesi fonksiyona atanacaktr (eleme nesnesinin ne demek olduunu ilk blmlerden
hatrlyorsunuz). te nesne adl bir argman kullanmamzn nedeni de, eleme
nesnelerinin bir metodu olan group() metodunu fonksiyon iinde kullanabilmek...
Bir sonraki satrda bir adet szlk gryoruz:
a = {"ile":"eri", "ile":"Eri", "ilek":"Erik", "ilek":"erik"}

Bu szl oluturmamzn nedeni, metin iinde geen btn ilek kelimelerini tek bir erik
kelimesiyle deitiremeyecek olmamz... nk ilek kelimesi metin iinde pek ok farkl
biimde geiyor. Bata da dediimiz gibi, yukardaki yol yerine metni birka kez kopyalayarak
ve her defasnda bir deiiklik yaparak da sorunu zebilirsiniz. (Mesela nce ilek
kelimelerini bulup bunlar erik ile deitirirsiniz. Daha sonra ile kelimelerini arayp
bunlar eri ile deitirirsiniz, vb...) Ama metni tekrar tekrar oluturmak pek performansl
bir yntem olmayacaktr. Bizim imdi kullandmz yntem metin kopyalama zorunluluunu
ortadan kaldryor. Bu szlk iinde ilek kelimesinin alaca ekilleri szlk iinde birer
anahtar olarak, erik kelimesinin alaca ekilleri ise birer deer olarak belirliyoruz.
Sonraki satrda iki metot birden var:
b = nesne.group().split()

Burada, fonksiyonumuzun argman olarak vazife gren eleme nesnesine ait metotlardan
biri olan group() metodunu kullanyoruz. Bylece derle = re.compile("ile[k]",
re.IGNORECASE) satr yardmyla metin iinde bulduumuz btn ilek ve enilerini
alyoruz. Karakter dizilerinin split() metodunu kullanmamzn nedeni ise group()
metodunun verdii kty liste haline getirip daha kolay maniple etmek. Burada for
i in b: print(i) komutunu verirseniz group() metodu yardmyla ne bulduumuzu
grebilirsiniz:
ile
ilek
ile
ilek
ile
ilek
ilek
ilek
ile
ilek
ilek
ilek

818 Blm 46. Dzenli fadeler


Python 3 iin Trke Klavuz, Srm 3

Bu kty grdkten sonra, kodlarda yapmaya altmz ey daha anlaml grnmeye


balam olmal... imdi sonraki satra geiyoruz:
for i in b:
return a[i]

Burada, group() metodu yardmyla bulduumuz elemeler zerinde bir for dngs
oluturduk. Ardndan da return a[i] komutunu vererek a adl szlk iinde yer alan eleri
yazdryoruz. Bu arada, buradaki inin yukarda verdiimiz group() ktlarn temsil ettiine
dikkat edin. a[i] gibi bir komut verdiimizde aslnda srasyla u komutlar vermi oluyoruz:
a["ilek"]
a["ile"]
a["ilek"]
a["ile"]
a["ilek"]
a["ilek"]
a["ilek"]
a["ile"]
a["ilek"]
a["ilek"]

Bu komutlarn ktlar srasyla erik, eri, erik, Eri, erik, erik, erik, Eri, erik,
erik olacaktr. te bu return satr bir sonraki kod olan print(derle.sub(degistir,metin))
ifadesinde etkinlik kazanacak. Bu son satrmz szlk elerini tek tek metne uygulayacak ve
mesela a["ilek"] komutu sayesinde metin iinde ilek grd yerde erik kelimesini
yaptracak ve bylece bize istediimiz ekilde deitirilmi bir metin verecektir...
Bu kodlarn biraz kark gibi grndn biliyorum, ama aslnda ok basit bir mant
var: group() metodu ile metin iinde aradmz kelimeleri ayklyor. Ardndan da a
szl iinde bunlar anahtar olarak kullanarak ilek ve eitleri yerine erik ve eitlerini
koyuyor...
Yukarda verdiimiz dzenli ifadeyi byle ufak bir metinde kullanmak ok anlaml olmayabilir.
Ama ok byk metinler zerinde ok eitli ve karmak deiiklikler yapmak istediinizde bu
kodlarn iinize yarayabileceini greceksiniz.

46.6.2 subn() metodu

Bu metodu ok ksa bir ekilde anlatp geeceiz. nk bu metot sub() metoduyla


neredeyse tamamen ayndr. Tek fark, subn() metodunun bir metin iinde yaplan deiiklik
saysn da gstermesidir. Yani bu metodu kullanarak, kullanclarnza toplam u kadar
sayda deiiklik yaplmtr eklinde bir bilgi verebilirsiniz. Bu metot kt olarak iki eli
bir demet verir. Birinci e deitirilen metin, ikinci e ise yaplan deiiklik saysdr.
Yani kullancya deiiklik saysn gstermek iin yapmanz gereken ey, bu demetin ikinci
esini almaktr. Mesela sub() metodunu anlatrken verdiimiz kodlarn son satrn yle
deitirebilirsiniz:
ab = derle.subn(degistir, metin)
print("Toplam {} deiiklik yaplmtr.".format(ab[1]))

Yani:
import re

46.6. Dzenli fadelerle Metin/Karakter Dizisi Deitirme lemleri 819


Python 3 iin Trke Klavuz, Srm 3

metin = """Karadeniz Erelisi denince akla ilk olarak kmr ve demir-elik


gelir. Kokusu ve tadyla dnyaya nam salm mehur Osmanl ilei ise ismini
verdii festival gnleri dnda pek hatrlanmaz. Oysa in'den Arnavutky'e
oradan da Ereli'ye getirilen krallarn meyvesi ilek, burada geirdii deiim
sonucu tadna doyulmaz bir hal alr. Ereli'nin havasndan m suyundan m
bilinmez, kokusu, tad bambaka bir hale dnr ve mehur Osmanl ilei
unvann hak eder. Bu nazik ve aromal ilekten yaplan reel de likr de bir
baka olur. Bu yl dokuzuncusu dzenlenen Uluslararas Osmanl ilei Kltr
Festivali'nde 36 retici arasnda yetitirdii ileklerle birinci olan Kocaali
Ky'nden Gner zdemir, ylda bir ton rn alyor. 60 yandaki zdemir,
ileklerinin srrn youn ilgiye ve iten duyduu sevgiye balyor: "Erkekler
bahemize giremez. Koca ayaklaryla ezerler ileklerimizi" ilei toplamann zor
olduunu syleyen Aye zhan da ocukluundan bu yana ilek bahesinde
alyor. Her sabah 04.00'te kalkan zhan, ileklerini zenle suluyor. Kasm
banda ektii ilek fideleri haziran banda meyve veriyor."""

derle = re.compile("ile[k]", re.IGNORECASE)

def degistir(nesne):
a = {"ile":"eri", "ile":"Eri", "ilek":"Erik", "ilek":"erik"}
b = nesne.group().split()
for i in b:
return a[i]

ab = derle.subn(degistir, metin)
print("Toplam {} deiiklik yaplmtr.".format(ab[1]))

46.7 Sonu

Bylelikle dzenli ifadeler konusunu bitirmi olduk. Buradaki amacmz, size dzenli ifadeler
konusunda genel bir bak sunabilmekti. Bu yazlar okuduktan sonra kafanzda dzenli
ifadelerle ilgili kabataslak da olsa bir resim olutuysa bu yazlar amacna ulam demektir.
Elbette dzenli ifadeler burada anlattklarmzdan ibaret deildir. Bu konunun zerine
eildiinizde aslnda dzenli ifadelerin dipsiz bir kuyu gibi olduunu greceksiniz. Esasnda
en bata da dediimiz gibi, dzenli ifadeler apayr bir dil gibidir. Dorusu u ki, dzenli
ifadeler bal bana bamsz bir sistemdir. Hemen hemen btn programlama dilleri
yle ya da byle dzenli ifadeleri destekler. Pythonda dzenli ifadeleri bnyesine adapte
etmi dillerden biridir. Bizim dzenli ifadeler konusundaki yaklammz, her zaman bunlar
gerektiinde kullanmak olmaldr. Dediimiz gibi, eer yapmak istediiniz bir ilemi karakter
dizilerinin metotlar yardmyla yapabiliyorsanz dzenli ifadelere girimemek en iyisidir.
nk karakter dizisi metotlar hem daha hzldr hem de anlamas daha kolaydr.

820 Blm 46. Dzenli fadeler


BLM 47

Sqlite ile Veritaban Programlama

47.1 Giri

Bu blmde, Pythondaki ileri dzey konulardan biri olan veritaban programlamay (database
programming ) inceleyeceiz. Dilerseniz ncelikle veritaban denen eyin ne olduunu
anlamaya alarak ie balayalm.
Esasnda veritaban, hibirimizin yabancs olduu bir kavram deil. Biz bu kelimeyi, teknik
anlamnn dnda, gnlk hayatta da ska kullanyoruz. Veritaban, herkesin bildii ve
kulland anlamyla, iinde veri barndran bir eydir. Gnlk kullanmda, hakikaten, iinde
veri barndran her eye veritaban dendiini duyarsnz.
Veritaban kelimesinin gnlk kullanmdaki anlam dnda bir de teknik anlam vardr. Bizi
esas ilgilendiren de zaten terimin teknik anlamdr. Mesela Vikipedide veritaban yle
tanmlanyor:
Bilgisayar terminolojisinde, sistematik eriim imkn olan, ynetilebilir,
gncellenebilir, tanabilir, birbirleri arasnda tanml ilikiler bulunabilen bilgiler
kmesidir. Bir baka tanm da, bir bilgisayarda sistematik ekilde saklanm,
programlarca ilenebilecek veri yndr.
Yukardaki tanm, veritabannn ne demek olduunu gayet iyi ifade ediyor. Ama esasnda
bizim veritaban tanm zerinde fazlaca durmamza gerek yok. Biz her zaman olduu gibi
iin teknik boyutuyla deil, taktik boyutuyla ilgilenmeyi tercih edeceiz. O halde yava yava
ie koyulmaya balayalm.
Pythonla veritaban programlama ilemleri iin pek ok alternatimiz
var. Pythonla hangi veritaban sistemlerini kullanabileceinizi grmek iin
http://wiki.python.org/moin/DatabaseInterfaces adresindeki listeyi inceleyebilirsiniz. Biz
bunlar iinde, sadelii, basitlii ve kullanm kolayl nedeniyle Sqlite adl veritaban ynetim
sistemini ele alacaz.

47.2 Neden Sqlite?

Dediimiz gibi, Pythonda veritaban ilemleri iin kullanabileceiniz pek ok alternatif


bulunur. Ama biz btn bu alternatier iinde Sqlite tercih edeceiz. Peki neden Sqlite?
Sqliten teki sistemlere gre pek ok avantaj bulunur. Gelin isterseniz Sqliten baz
avantajlarna yle bir gz gezdirelim:

821
Python 3 iin Trke Klavuz, Srm 3

Her eyden nce Sqlite Pythonun 2.5 srmlerinden bu yana bu dilin bir parasdr.
Dolaysyla eer kullandnz Python srm 2.5 veya st ise Sqlite Pythondaki
herhangi bir modl gibi ie aktarabilir ve kullanmaya balayabilirsiniz.
Sqlite herhangi bir yazlm veya sunucu kurulumu gerektirmez. Bu sayede, bu
modl kullanabilmek iin ncelikle bir sunucu yaplandrmanza da gerek yoktur.
Baz veritabanlarn kullanabilmek iin arka planda bir veritaban sunucusu altryor
olmanz gerekir. Sqliteta ise byle bir ey yapmazsnz.
Sqlite, teki pek ok veritaban alternatine gre basittir. Bu yzden Sqlite ok ksa bir
srede kavrayp kullanmaya balayabilirsiniz.
Sqlite zgr bir yazlmdr. Bu yazlmn batan aa btn kodlar kamuya aktr.
Dolaysyla Sqlite kodlarnn her zerresini istediiniz gibi kullanabilir, deiiklie
uratabilir, satabilir ve ticari olan/olmayan btn uygulamalarnzda gnl rahatlyla
kullanabilirsiniz.
Sqliten sade ve basit olmas sizi yanltmasn. Bu zelliklerine bakarak, Sqliten
yeteneksiz bir veritaban sistemi olduunu dnmeyin. Bugn Sqlite aktif olarak
kullanan pek ok byk ve tannm irket bulunur. Mesela, Adobe, Apple,
Mozilla/Firefox, Google, Symbian ve Sun bu irketlerden bazlardr. Hatta GNOME
masast ortamnn sevilen mzik ve video alarlarndan Bansheede de veritaban
olarak Sqlite kullanldn syleyelim.
Yukardaki sebeplerden tr, veritaban konusunu Sqlite zerinden anlatacaz. O halde
hemen yola koyulalm.

47.3 Sqliten Yaps

Bu blmn en banda verdiimiz veritaban tanmndan da anlalaca gibi, veritabanlar,


verileri sonradan kullanlmak zere iinde tutan bir sistemdir. Btn ilikisel veritabanlarnda
olduu gibi, Sqlite da bu verileri tablo benzeri bir yap iinde tutar. Yani aslnda bir Sqlite
veritaban iindeki veriler yle bir yapya sahiptir:
Stun 1 Stun 2 Stun 3 Stun 4 Stun 5
Deer 1/1 Deer 2/1 Deer 3/1 Deer 4/1 Deer 5/1
Deer 1/2 Deer 2/2 Deer 3/2 Deer 4/2 Deer 5/2
Deer 1/3 Deer 2/3 Deer 3/3 Deer 4/3 Deer 5/3
Deer 1/4 Deer 2/4 Deer 3/4 Deer 4/4 Deer 5/4
Sqlite iinde oluturulan yukardakine benzer her tablonun bir de ismi vardr. Daha dorusu,
Sqlite ile bir tablo olutururken, bu tabloya bir de ad vermemiz gerekir. Mesela yukardaki
tabloya deerler adn verdiimizi varsayabilirsiniz.
Sqlite ile alrken veriler zerinde yapacamz ilemleri, yukardaki tablonun adn ve bu
tablodaki stunlar kullanarak gerekletireceiz. Bu yzden Sqliten yapsn anlamak byk
nem tar. Grdnz gibi, bu veritaban sisteminin yapsn anlamak da yle zor bir i
deildir.

822 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

47.4 Yardmc Aralar

Veritabanlar zerinde yapacamz almalar srasnda, ilerimizi kolaylatrmak iin baz


harici aralara da ihtiya duyacaz. Gelin imdi bu aralar tanyalm.

47.4.1 Sqlitebrowser

Sqlitebrowser, Sqlite veritabanlarnn ieriini grak bir arayz araclyla


grntleyebilmemizi salayan bir program. Bu program sayesinde, veritaban zerinde
yaptnz almann doru sonu verip vermediini teyit edebilir, elinizdeki veritabannn
ieriinde hangi verilerin olduunu ak seik grebilirsiniz.
Bu program indirmek iin ziyaret etmemiz gereken adres http://sqlitebrowser.org/.
Eer siz bir Windows kullancs iseniz, sitedeki .exe dosyasn indirip, program herhangi bir
Windows program gibi kurabilirsiniz.
GNU/Linux kullanclarnn nnde ise her zaman olduu gibi birka farkl seenek var.
ncelikle, bu program ou GNU/Linux datmnn paket deposunda zaten bulunur.
Dolaysyla bu program datmnzn paket deposu araclyla rahatlkla kurabilirsiniz.
Mesela Ubuntu kullananlar u komutla program kurabilir:
sudo apt-get install sqlitebrowser

GNU/Linux kullanclar, eer arzu ederlerse, programn kaynak kodlarn sitesinden


indirip program kendileri derlemeyi de tercih edebilir. Bunun iin ncelikle
http://sqlitebrowser.org/ adresine gidip .tar.gz uzantl dosyay indirin.
Bu program derlemeye gemeden nce u bamllklar kurmamz gerekiyor:
1. cmake
2. libqt4-dev
3. libsqlite3-dev
Ubuntuda ayrca build-essential paketine de ihtiyacnz olacak. Ubuntu kullanclar u
komutu vererek Sqlitebrowser programnn btn bamllklarn sistemlerine kurabilir:
sudo apt-get install build-essential cmake libqt4-dev libsqlite3-dev

Bamllklar kurduktan sonra, indirdiiniz .tar.gz dosyasn aadaki komut yardmyla an:
tar zxvf sqlitebrowser-3.7.0.tar.gz

Ben burada indirdiiniz program srmnn 3.7.0 olduunu varsaydm. Sizin indirdiiniz
srm farklysa yukardaki komutu o srme gre vereceksiniz.
Daha sonra u komutu vererek, atnz klasrn iine girin:
cd sqlitebrowser-3.7.0

Yine, burada da klasr ad ve srm numaras sizde farklysa komutu dzeltin.


Ardndan srasyla u komutlar verin (cmake komutunun yanndaki nokta iaretine dikkat!!):
cmake .

47.4. Yardmc Aralar 823


Python 3 iin Trke Klavuz, Srm 3

make

sudo make install

Bylece Sqlitebrowser programn sisteminize kurmu oldunuz. Programn kurulduunu teyit


etmek iin u komutu altrn:
sqlitebrowser

Eer program penceresi aldysa her ey yolunda demektir. Eer program


altramadysanz veya yukardaki komutlar anlamakta ve iletmekte zorluk ekiyorsanz
paket deponuzdaki Sqlitebrowser srm ile yola devam etmenizi tavsiye ederim. Ya da
eer arzu ederseniz, http://www.istihza.com/forum adresine urayp yardm talebinde
bulunabilirsiniz.

47.4.2 rnek Veritaban

Sqlite renirken, iinde rnek veriler barndran bir veritabannn elimizin


altnda bulunmas altrma yapabilmek asndan faydal olacaktr. Bunun iin
http://www.istihza.com/denemeler/kitaplar.sqlite adresindeki rnek veritabann
bilgisayarnza indirin. Veritaban sorgu almalarmz bu rnek veritaban zerinde
gerekletireceiz.
imdi mesela biraz nce indirip kurduunuz Sqlitebrowser programn altrn ve File >
Open Database yolunu takip ederek bu kitaplar.sqlite adl veritaban dosyasn an. Eer
Sqlitebrowser programn Sqlite veritaban dosyalar ile ilikilendirdiyseniz, kitaplar.sqlite
dosyas zerine ift tkladnzda da bu veritaban dosyas otomatik olarak Sqlitebrowser
program ile alacaktr. Ayrca elbette veritaban dosyas zerine sa tklayp, Birlikte a...
seeneini kullanarak da Sqlitebrowser programn altrmay deneyebilirsiniz.
Sqlitebrowser programn altrp, kitaplar.sqlite dosyasn da atktan sonra, program
penceresi zerindeki Browse Data sekmesine tklayarak veritabannn iinde ne tr verilerin
olduunu inceleyin. Grdnz gibi, Sqlitebrowser program, veritaban iindeki verileri
grselletirmek asndan epey kolaylk salyor. Birazdan bu verilere Python araclyla nasl
eriebileceimizi de reneceiz.

47.5 Yeni Bir Veritaban Oluturmak

Bu blmde sqlite adl bir modl araclyla yeni bir veritabann nasl oluturacamz
reneceiz.
Yukarda sqlite adl bir modlden sz ettik. Dolaysyla, tahmin edebileceiniz gibi, bu modl
kullanabilmek iin ncelikle modl ie aktarmamz gerekiyor. Bu blmn banda da
sylediimiz gibi, Sqlite, Pythonn 2.5 srmnden bu yana dilin bir parasdr:
>>> import sqlite3

Pythonda Sqlite veritaban sistemine ait modl sqlite3 adn tar. Bu yzden, bu modl ie
aktarmak iin import sqlite3 ifadesini kullanmamz gerekiyor. Eer bu isim size ok uzun
geliyorsa veya modl adnda saylarn ve harerin birlikte bulunmas nedeniyle hem say hem
de harf girmeyi bir angarya olarak gryorsanz elbette sqlite3 modln farkl bir adla da
ie aktarabileceinizi biliyorsunuz. Mesela:

824 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

>>> import sqlite3 as sql

Veya:
>>> import sqlite3 as lite

Bylece sqlite3 modln sql veya lite adyla ie aktarm olduk. Ancak ben konuyu
anlatrken, okur asndan kafa karklna sebep olmamak iin, modl import sqlite3
eklinde ie aktarmz gibi davranacam.
Gelelim bu modl yardmyla nasl veritaban oluturulacana... Bunun iin sqlite3
modlnn connect() adl metodundan yararlanacaz. Bu metodu u ekilde kullanyoruz:
>>> vt = sqlite3.connect('veritaban_ad')

connect() metoduna verdiimiz varitaban_ad adl argman, kullanacamz veritabannn


addr. Eer belirtilen isimde bir veritaban sistemde bulunmuyorsa o adla yeni bir veritaban
oluturulacaktr. Mesela:
>>> vt = sqlite3.connect('deneme.sqlite')

Eer bu komutu verdiiniz dizin iinde deneme.sqlite adl bir veritaban yoksa, bu ada sahip
bir veritaban oluturulacaktr.
Bu arada, biz veritaban dosyasnn uzants olarak .sqlite setik. Ama eer siz isterseniz
kendinize uygun baka bir uzant da belirleyebilirsiniz. Veritaban dosyasnn uzantsnn ne
olmas gerektii konusunda kesin kurallar bulunmaz. .sqlite uzantsnn yerine, .sqlite3, .db
veya .db3 gibi uzantlar tercih edenler de vardr. Hatta eer siz isterseniz veritabannzn
uzantsn .osman olarak dahi belirleyebilirsiniz. Bu konuda herhangi bir kstlama bulunmaz.
Yukardaki rnekte deneme.sqlite adn verdiimiz bir veritaban dosyasna, connect()
metodu yardmyla balandk. Elbette isteseydik connect() metoduna argman olarak tam
dosya yolu da verebilirdik:
>>> import sqlite3
>>> vt = sqlite3.connect('/home/istihza/test.sqlite') #GNU/Linux
>>> vt = sqlite3.connect('c:/users/fozgul/desktop/test.sqlite') #Windows

Bu komut yardmyla sabit disk zerinde bir Sqlite veritaban dosyas oluturmu oluyoruz.
Ancak isterseniz sqlite3 ile geici bir veritaban da oluturabilirsiniz:
>>> vt = sqlite3.connect(':memory:')

Oluturduunuz bu geici veritaban sabit disk zerinde deil RAM (bellek) zerinde alr.
Veritabann kapattnz anda da bu geici veritaban silinir. Eer arzu ederseniz, RAM
zerinde deil, disk zerinde de geici veritabanlar oluturabilirsiniz. Bunun iin de yle
bir komut kullanyoruz:
>>> vt = sqlite3.connect('')

Grdnz gibi, disk zerinde geici bir veritaban oluturmak iin bo bir karakter dizisi
kullandk. Tpk :memory: kullanmnda olduu gibi, bo karakter dizisiyle oluturulan geici
veritabanlar da veritaban balantsnn kesilmesiyle birlikte ortadan kalkacaktr.
Geici veritaban oluturmak, zellikle eitli testler veya denemeler yaptnz durumlarda
iinize yarar. Sonradan nasl olsa sileceiniz, srf test amal tuttuunuz bir veritabann
disk zerinde oluturmak yerine RAM zerinde oluturmay tercih edebilirsiniz. Ayrca, geici

47.5. Yeni Bir Veritaban Oluturmak 825


Python 3 iin Trke Klavuz, Srm 3

veritabanlar sayesinde, yazdnz bir kodu test ederken bir hatayla karlarsanz sorunun
veritaban iinde varolan verilerden deil, yazdnz koddan kaynaklandndan da emin
olabilirsiniz. nk, dediimiz gibi, programn her yeniden alnda veritaban batan
oluturulacaktr.
Dikkatinizi ekmek istediim bir nokta da udur: Grdnz gibi Sqlite, veritabann o
anda iinde bulunduunuz dizin iinde oluturuyor. Mesela MySQL kullanyor olsaydnz,
oluturulan veritabanlarnn nceden tanmlanm bir dizin iine atldn grecektiniz.
rnein GNU/Linux sistemlerinde, MySQL veritabanlar /var/lib/mysql gibi bir dizinin iinde
tutulur.

47.6 Varolan Bir Veritabanyla Balant Kurmak

Biraz nce, deneme.sqlite adl yeni bir Sqlite veritaban oluturmak iin yle bir komut
kullanmtk:
>>> vt = sqlite3.connect('deneme.sqlite')

Eer bu komutu verdiiniz dizin iinde deneme.sqlite adl bir veritaban yoksa, bu ada sahip
bir veritaban oluturulur. Eer zaten bu adla bir veritaban dosyanz varsa, sqlite3 bu
veritabanna balanacaktr. Dolaysyla Sqliteta hem yeni bir veritaban oluturmak hem de
mevcut bir veritabanna balanmak iin birbiriyle tamamen ayn kodlar kullanyoruz.
Mesela biraz nce http://www.istihza.com/denemeler/kitaplar.sqlite adresinden indirdiimiz
kitaplar.sqlite adl veritabanna balanalm.
Bu dosyann bulunduu konumda bir Python etkileimli kabuk oturumu atmz
varsayarsak:
>>> vt = sqlite3.connect('kitaplar.sqlite')

komutunu kullanarak kitaplar.sqlite adl veritabanyla balant kurabiliriz.

47.7 mle Oluturma

Yukarda connect() metodunu kullanarak hem Sqlite ile nasl veritaban balants
kuracamz hem de nasl yeni bir veritaban oluturacamz rendik.
connect() metodu, bir veritaban zerinde ilem yapabilmemizin ilk admdr. Veritabann
oluturduktan veya varolan bir veritaban ile balant kurduktan sonra, veritaban zerinde
ilem yapabilmek iin sonraki admda bir imle oluturmamz gerekir.
mle oluturmak iin cursor() adl bir metottan yararlanacaz:
>>> im = vt.cursor()

mleci oluturduktan sonra artk nmz iyice alyor. Bylece, yukarda oluturduumuz
im nesnesinin execute() metodunu kullanarak SQL komutlarn altrabileceiz. Nasl m?
Hemen bakalm.

826 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

47.8 Tablo Oluturma

nceki blmn sonunda sylediimiz gibi, bir imle nesnesi oluturduktan sonra bunun
execute() metodunu kullanarak SQL komutlarn iletebiliyoruz.
Dilerseniz imdi basit bir rnek yaparak neyin ne olduunu anlamaya alalm.
ncelikle gerekli modl ie aktaralm:
>>> import sqlite3

imdi de yeni bir veritaban dosyas oluturalm (veya varolan bir veritaban dosyasna
balanalm):
>>> vt = sqlite3.connect('veritabani.sqlite')

Bu veritaban zerinde ilem yapabilmek iin ncelikle imlecimizi oluturalm:


>>> im = vt.cursor()

imdi de yukarda oluturduumuz imlecin execute() adl metodunu kullanarak veritaban


iinde bir tablo oluturalm:
>>> im.execute("CREATE TABLE adres_defteri (isim, soyisim)")

Hatrlarsanz, Sqlite veritaban sisteminin tablo benzeri bir yapya sahip olduunu ve bu
sistemdeki her tablonun da bir isminin bulunduunu sylemitik. te burada yaptmz ey,
adres_defteri adl bir tablo oluturup, bu tabloya isim ve soyisim adl iki stun eklemekten
ibarettir. Yani aslnda yle bir ey oluturmu oluyoruz:
isim soyisim

Ayrca oluturduumuz bu tablonun adnn da adres_defteri olduunu unutmuyoruz...


Bu ilemleri nasl yaptmza dikkat edin. Burada CREATE TABLE adres_defteri (isim,
soyisim) tek bir karakter dizisidir. Bu karakter dizisindeki CREATE TABLE ksm bir SQL komutu
olup, bu komut bir tablo oluturulmasn salar.
Burada CREATE TABLE ifadesini byk harerle yazdk. Ancak bu ifadeyi siz isterseniz kk
harerle de yazabilirsiniz. Benim burada byk harf kullanmaktaki amacm SQL komutlarnn,
adres_defteri, isim ve soyisim gibi elerden grsel olarak ayrt edilebilmesini salamak.
Yani CREATE TABLE ifadesinin mesela adres_defteri esinden kolayca ayrt edilebilmesini
istediim iin burada CREATE TABLE ifadesini byk harerle yazdm.
Karakter dizisinin devamnda (isim, soyisim) ifadesini gryoruz. Tahmin edebileceiniz
gibi, bunlar tablodaki stun balklarnn adn gsteriyor. Buna gre, oluturduumuz
tabloda isim ve soyisim adl iki farkl stun bal olacak.
Bu arada, Sqlite tablolar olutururken tablo ad ve stun balklarnda Trke karakter
kullanmaktan kanmak iyi bir kirdir. Ayrca eer tablo ad ve stun balklarnda birden
fazla kelimeden oluan etiketler kullanacaksanz bunlar ya birbirine bititirin ya da trnak
iine aln. rnein:
import sqlite3

vt = sqlite3.connect('perso.sqlite')
im = vt.cursor()

47.8. Tablo Oluturma 827


Python 3 iin Trke Klavuz, Srm 3

im.execute("""CREATE TABLE 'personel dosyasi'


('personel ismi', 'personel soyismi', memleket)""")

Ayrca, execute() metoduna parametre olarak verilen SQL komutlarnn alelade birer
karakter dizisi olduuna da dikkatinizi ekmek isterim. Bunlar Pythondaki karakter dizilerinin
btn zelliklerini tar. Mesela bu karakter dizisini execute() metoduna gndermeden nce
bir deikene atayabilirsiniz:
import sqlite3

vt = sqlite3.connect('perso.sqlite')
im = vt.cursor()

sql = """CREATE TABLE 'personel dosyasi'


('personel ismi', 'personel soyismi', memleket)"""

im.execute(sql)

Bu kodlar kullanarak oluturduunuz perso.sqlite adl veritaban dosyasnn ieriini


Sqlitebrowser program yardmyla grntleyip, gerekten personel ismi, personel soyismi
ve memleket stunlarnn oluup olumadn kontrol edin.
Bu arada, bu kodlar ikinci kez altrdnzda yle bir hata mesaj alacaksnz:
sqlite3.OperationalError: table 'personel dosyasi' already exists

Bu hata mesajn almanz gayet normal. Bunun stesinden nasl geleceinizi renmek iin
okumaya devam edin...

47.9 artl Tablo Oluturma

CREATE TABLE komutunu kullanarak tablo olutururken yle bir problemle karlam
olabilirsiniz. Diyelim ki u kodlar yazdnz:
import sqlite3

vt = sqlite3.connect('vt.sqlite')

im = vt.cursor()
im.execute("CREATE TABLE personel (isim, soyisim, memleket)")

Bu kodlar ilk kez altrdnzda, mevcut dizin altnda vt.sqlite adl bir veritaban dosyas
oluturulacak ve bu veritaban iinde isim, soyisim ve memleket balkl stunlara sahip,
personel adl bir tablo meydana getirilecektir.
Ancak ayn kodlar ikinci kez altrdnzda yle bir hata mesaj ile karlaacaksnz:
sqlite3.OperationalError: table personel already exists

Buradaki sorun, vt.sqlite dosyas iinde personel adl bir tablonun zaten bulunuyor
olmasdr. Bir veritaban zerinde ilem yaparken, ayn ada sahip iki tablo oluturamayz.
Bu hatay nlemek iin artl tablo oluturma ynteminden yararlanacaz. Bunun iin
kullanacamz SQL komutu udur: CREATE TABLE IF NOT EXISTS.
rneimizi bu yeni bilgiye gre tekrar yazalm:

828 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

import sqlite3

vt = sqlite3.connect('vt.sqlite')

im = vt.cursor()

sorgu = """CREATE TABLE IF NOT EXISTS personel


(isim, soyisim, memleket)"""

im.execute(sorgu)

Bu kodlar ka kez altrrsanz altrn, programnz hata vermeden ileyecek; eer


veritabannda personel adl bir tablo yoksa oluturacak, bu adla zaten bir tablo varsa da
sessizce yoluna devam edecektir.

47.10 Tabloya Veri Girme

Buraya kadar, sqlite3 modln kullanarak nasl bir veritaban oluturacamz ve eitli
stnlardan oluan bir tabloyu bu veritabanna nasl yerletireceimizi rendik. imdi de
oluturduumuz bu stun balklarnn altn dolduracaz.
Dikkatlice bakn:
import sqlite3

vt = sqlite3.connect('vt.sqlite')
im = vt.cursor()

tablo_yap = """CREATE TABLE IF NOT EXISTS personel


(isim, soyisim, memleket)"""

deer_gir = """INSERT INTO personel VALUES ('Frat', 'zgl', 'Adana')"""

im.execute(tablo_yap)
im.execute(deer_gir)

Uyar: Bu kodlar altrdktan sonra, eer veritabannn ieriini Sqlitebrowser ile kontrol
ettiyseniz verilerin veritabanna ilenmediini greceksiniz. Endie etmeyin; birazdan
bunun neden byle olduunu aklayacaz.

Burada INSERT INTO tablo_ad VALUES adl yeni bir SQL komutu daha reniyoruz. CREATE
TABLE ifadesi Trkede TABLO OLUTUR anlamna geliyor. INSERT INTO ise ... NE
YERLETR anlamna gelir. Yukardaki karakter dizisi iinde grnen VALUES ise DEERLER
demektir. Yani aslnda yukardaki karakter dizisi u anlama gelir: personel NE Frat,
zgl ve Adana DEERLERN YERLETR. Yani yle bir tablo olutur :
isim soyisim memleket
Frat zgl Adana

Buraya kadar gayet gzel gidiyoruz. sterseniz imdi derin bir nefes alp, u ana kadar
yaptmz eyleri bir gzden geirelim:
ncelikle sqlite3 modln ie aktardk. Bu modln nimetlerinden yararlanabilmek
iin bunu yapmamz gerekiyordu. sqlite3 kelimesini her defasnda yazmak bize

47.10. Tabloya Veri Girme 829


Python 3 iin Trke Klavuz, Srm 3

angarya gibi gelebilecei iin bu modl farkl bir adla ie aktarmay tercih edebiliriz.
Mesela import sqlite3 as sql veya import sqlite3 as lite gibi...
sqlite3 modln ie aktardktan sonra bir veritabanna balanmamz veya
elimizde bir veritaban yoksa yeni bir veritaban oluturmamz gerekiyor.
Bunun iin connect() adl bir fonksiyondan yararlanyoruz. Bu fonksiyonu,
sqlite3.connect(veritaban_ad) eklinde kullanyoruz. Eer iinde
bulunduumuz dizinde, veritaban_ad adl bir veritaban varsa Sqlite bu veritabanna
balanr. Eer bu adda bir veritaban yoksa, alma dizini altnda bu ada sahip yeni
bir veritaban oluturulur. zellikle deneme amal ilemler yapmamz gerektiinde,
sabit disk zerinde bir veritaban oluturmak yerine RAM stnde geici bir veritaban
ile almay da tercih edebiliriz. Bunun iin yukardaki komutu yle yazyoruz:
sqlite3.connect(:memory:). Bu komutla RAM zerinde oluturduumuz veritaban,
balant kesildii anda ortadan kalkacaktr.
Veritabanmz oluturduktan veya varolan bir veritabanna balandktan sonra
yapmamz gereken ey bir imle oluturmak olacaktr. Daha sonra bu imlece ait
metotlardan yararlanarak nemli iler yapabileceiz. Sqliteta bir imle oluturabilmek
iin db.cursor() gibi bir komut kullanyoruz. Tabii ben burada oluturduunuz
veritabanna db adn verdiinizi varsayyorum.
mlecimizi de oluturduktan sonra nmz iyice alm oldu. imdi dir(im) gibi
bir komut kullanarak imlecin metotlarnn ne olduunu inceleyebilirsiniz. Tabii ben
burada imlece im adn verdiinizi varsaydm. Grdnz gibi, listede execute()
adl bir metot da var. Artk imlecin bu execute() metodunu kullanarak SQL komutlarn
iletebiliriz.
Yukarda adet SQL komutu rendik. Bunlardan ilki CREATE TABLE. Bu komut
veritaban iinde bir tablo oluturmamz salyor. kinci komutumuz CREATE
TABLE IF NOT EXISTS. Bu komut da bir tabloyu eer yoksa oluturmamz salyor.
nc komutumuz ise INSERT INTO ... VALUES .... Bu komut, oluturduumuz
tabloya ierik eklememizi salyor. Bunlar una benzer bir ekilde kullandmz
hatrlyorsunuz:
im.execute("CREATE TABLE personel (isim, soyisim, memleket)")
im.execute("INSERT INTO personel VALUES ('Frat', 'zgl', 'Adana')")

Burada bir ey dikkatinizi ekmi olmal. SQL komutlarn yazmaya balarken ift trnakla
baladk. Dolaysyla karakter dizisini yazarken i taraftaki Frat, zgl ve Adana deerlerini
yazmak iin tek trnak kullanmamz gerekti. Karakter dizileri iindeki manevra alannz
geniletmek iin, SQL komutlarn trnak iinde yazmay da tercih edebilirsiniz. Bylece
karakter dizisi iindeki tek ve ift trnaklar daha rahat bir ekilde kullanabilirsiniz. Yani:
im.execute("""CREATE TABLE personel (isim, soyisim, memleket)""")
im.execute("""INSERT INTO personel VALUES ("Frat", "zgl", "Adana")""")

Ayrca trnak kullanmanz sayesinde, uzun satrlar gerektiinde blerek ok daha okunakl
kodlar da yazabileceinizi biliyorsunuz.

47.11 Verilerin Veritabanna lenmesi

Bir nceki blmde bir Sqlite veritabanna nasl veri gireceimizi rendik. Ama aslnda i
sadece veri girmeyle bitmiyor. Verileri veritabanna ileyebilmek iin bir adm daha atmamz

830 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

gerekiyor. Mesela u rnee bir bakalm:


import sqlite3

vt = sqlite3.connect("vt.sqlite")

im = vt.cursor()
im.execute("""CREATE TABLE IF NOT EXISTS
personel (isim, soyisim, sehir, eposta)""")

im.execute("""INSERT INTO personel VALUES


("Orun", "Kunek", "Adana", "okunek@gmail.com")""")

Burada ncelikle vt.sqlite adl bir veritaban oluturduk ve bu veritabanna balandk.


Ardndan, vt.cursor() komutuyla imlecimizi de oluturduktan sonra, SQL komutlarmz
altryoruz. nce isim, soyisim, ehir ve eposta adl stunlardan oluan, personel adl
bir tablo oluturduk. Daha sonra personel tablosunun iine Orun, Kunek, Adana ve
okunek@gmail.com deerlerini yerletirdik.
Ancak her ne kadar veritabanna veri ilemi gibi grnsek de aslnda henz ilenmi bir ey
yoktur. sterseniz bu durumu teyit etmek iin Sqlitebrowser programn kullanabilir, tabloya
verilerin ilenmediini kendi gzlerinizle grebilirsiniz.
Biz henz sadece verileri girdik. Ama verileri veritabanna ilemedik. Bu girdiimiz verileri
veritabanna ileyebilmek iin commit() adl bir metottan yararlanacaz:
>>> vt.commit()

Grdnz gibi, commit() imlecin deil, balant nesnesinin (yani burada vt deikeninin)
bir metodudur. imdi bu satr da betiimize ekleyelim:
import sqlite3

vt = sqlite3.connect("vt.sqlite")

im = vt.cursor()
im.execute("""CREATE TABLE IF NOT EXISTS
personel (isim, soyisim, sehir, eposta)""")

im.execute("""INSERT INTO personel VALUES


("Orun", "Kunek", "Adana", "okunek@gmail.com")""")

vt.commit()

Bu son satr da ekledikten sonra Sqlite veritaban iinde yle bir tablo oluturmu olduk:
isim soyisim ehir eposta
Orun Kunek Adana okunek@gmail.com
Eer vt.commit() satrn yazmazsak, veritaban, tablo ve stun balklar oluturulur, ama
stunlarn ierii veritabanna ilenmez.

47.12 Veritabannn Kapatlmas

Bir veritaban zerinde yapacamz btn ilemleri tamamladktan sonra, prensip olarak, o
veritabann kapatmamz gerekir. Mesela u kodlar ele alalm:

47.12. Veritabannn Kapatlmas 831


Python 3 iin Trke Klavuz, Srm 3

import sqlite3

vt = sqlite3.connect("vt.sqlite")

im = vt.cursor()
im.execute("""CREATE TABLE IF NOT EXISTS
personel (isim, soyisim, sehir, eposta)""")

im.execute("""INSERT INTO personel VALUES


("Orun", "Kunek", "Adana", "okunek@gmail.com")""")

vt.commit()
vt.close()

Burada btn ilemleri bitirdikten sonra veritabann kapatmak iin, close() adl bir metottan
yararlandk:
vt.close()

Bu ekilde, veritabannn ilk ald andan itibaren, iletim sisteminin devreye soktuu
kaynaklar serbest brakm oluyoruz. Esasnda programmz kapandnda, ak olan btn
Sqlite veritabanlar da otomatik olarak kapanr. Ama yine de bu ilemi elle yapmak her zaman
iyi bir kirdir.
Eer zerinde ilem yaptnz veritabannn her ey bittikten sonra otomatik olarak
kapanmasn garantilemek isterseniz, daha nce rendiimiz with szcn
kullanabilirsiniz:
import sqlite3

with sqlite3.connect('vt.sqlite') as vt:


im = vt.cursor()

im.execute("""CREATE TABLE IF NOT EXISTS personel


(isim, soyisim, memleket)""")
im.execute("""INSERT INTO personel VALUES
('Frat', 'zgl', 'Adana')""")

vt.commit()

Bu ekilde with szcn kullanarak bir veritaban balants atmzda, btn iler
bittikten sonra Python bizim iin balanty otomatik olarak sonlandracaktr.

47.13 Parametreli Sorgular

u ana kadar verdiimiz rneklerde, veritabanna girilecek verileri tek tek elle yerine koyduk.
rnein:
im.execute("""INSERT INTO personel VALUES
('Frat', 'zgl', 'Adana')""")

Ancak ou durumda veritabanna girilecek veriler harici kaynaklardan gelecektir. Basit bir
rnek verelim:

832 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

import sqlite3

with sqlite3.connect('vt.sqlite') as vt:


im = vt.cursor()

veriler = [('Frat', 'zgl', 'Adana'),


('Ahmet', 'Sz', 'Bolvadin'),
('Veli', 'Gz', 'skenderun'),
('Mehmet', 'z', 'Kilis')]

im.execute("""CREATE TABLE IF NOT EXISTS personel


(isim, soyisim, memleket)""")

for veri in veriler:


im.execute("""INSERT INTO personel VALUES
(?, ?, ?)""", veri)

vt.commit()

Burada veritabanna ilenecek veriler, veriler adl bir deikenden geliyor. Bu deiken
iindeki verileri veritabanna nasl yerletirdiimize dikkat edin:
for veri in veriler:
im.execute("""INSERT INTO personel VALUES
(?, ?, ?)""", veri)

Ayrca her bir stunun (isim, soyisim, memleket) altna gelecek her bir deer iin (mesela
srasyla Frat, zgl, Adana) bir adet ? iareti yerletirdiimizi de gzden karmayn.

47.14 Tablodaki Verileri Semek

Yukarda, bir veritabanna nasl veri gireceimizi ve bu verileri veritabanna nasl


ileyeceimizi grdk. in asl nemli ksm, bu verileri daha sonra veritabanndan (yani
tablodan) geri alabilmektir. imdi bu ilemi nasl yapacamza bakalm.
Veritabanndan herhangi bir veri alabilmek iin ilk olarak SELECT veri FROM tablo_ad adl
bir SQL komutundan yararlanarak ilgili verileri sememiz gerekiyor.
Dilerseniz nce bir tablo oluturalm:
import sqlite3

vt = sqlite3.connect('vt.sqlite')

im = vt.cursor()

im.execute("""CREATE TABLE IF NOT EXISTS faturalar


(fatura, miktar, ilk_odeme_tarihi, son_odeme_tarihi)""")

imdi bu tabloya baz veriler ekleyelim:


im.execute("""INSERT INTO faturalar VALUES
("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")

Verileri veritabanna ileyelim:

47.14. Tablodaki Verileri Semek 833


Python 3 iin Trke Klavuz, Srm 3

vt.commit()

Yukardaki kodlar bize yle bir tablo verdi:


fatura miktar ilk_odeme_tarihi son_odeme_tarihi
Elektrik 45 23 Ocak 2010 30 Ocak 2010
Buraya kadar olan ksm zaten biliyoruz. Bilmediimiz ise bu veritabanndan nasl veri
alacamz. Onu da yle yapyoruz:
im.execute("""SELECT * FROM faturalar""")

Burada zel bir SQL komutu olan SELECT veri FROM tablo_ad komutundan faydalandk.
Burada joker karakterlerden biri olan * iaretini kullandmza dikkat edin. SELECT * FROM
faturalar ifadesi u anlama gelir: faturalar adl tablodaki btn eleri se!
Burada SELECT kelimesi SEMEK demektir. FROM ise ...DEN/...DAN anlam verir.
Yani SELECT FROM faturalar dediimizde faturalardan se demi oluyoruz. Burada
kullandmz * iareti de her ey anlamna geldii iin, SELECT * FROM faturalar ifadesi
faturalardan her eyi se gibi bir anlama gelmi oluyor.
Verileri setiimize gre, artk setiimiz bu verileri nasl alacamza bakabiliriz. Bunun
iin de fetchone(), fetchall() veya fetchmany() adl metotlardan ya da for dngsnden
yararlanacaz.

47.15 Seilen Verileri Almak

Bu blmde, SELECT sorgusu ile veritabanndan setiimiz verileri farkl yollarla nasl
ekebileceimizi/alabileceimizi inceleyeceiz.

47.15.1 fetchall() Metodu

Biraz nce yle bir program yazmtk:


import sqlite3

vt = sqlite3.connect('vt.sqlite')

im = vt.cursor()

im.execute("""CREATE TABLE IF NOT EXISTS faturalar


(fatura, miktar, ilk_odeme_tarihi, son_odeme_tarihi)""")

im.execute("""INSERT INTO faturalar VALUES


("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")

vt.commit()

im.execute("""SELECT * FROM faturalar""")

Burada vt.sqlite adl bir veritabannda faturalar adl bir tablo oluturduk ve bu tabloya baz
veriler girdik. Daha sonra da SELECT adl SQL komutu yardmyla bu verileri setik. imdi de
setiimiz bu verileri veritabanndan alacaz.
Yukardaki programa u satr ekliyoruz:

834 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

veriler = im.fetchall()

Burada da ilk defa grdmz bir metot var: fetchall(). Grdnz gibi, fetchall()
imlecin bir metodudur. Yukarda grdmz SELECT * FROM faturalar komutu faturalar
adl tablodaki btn verileri seiyordu. fetchall() metodu ise seilen bu verileri alma
ilevi gryor. Yukarda biz fetchall() metoduyla aldmz btn verileri veriler adl bir
deikene atadk.
Artk bu verileri rahatlkla yazdrabiliriz:
print(veriler)

Dilerseniz betiimizi topluca grelim:


import sqlite3

vt = sqlite3.connect('vt.sqlite')

im = vt.cursor()

im.execute("""CREATE TABLE IF NOT EXISTS faturalar


(fatura, miktar, ilk_odeme_tarihi, son_odeme_tarihi)""")

im.execute("""INSERT INTO faturalar VALUES


("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")

vt.commit()

im.execute("""SELECT * FROM faturalar""")

veriler = im.fetchall()

print(veriler)

Bu betii ilk kez altrdmzda yle bir kt alrz:


[('Elektrik', 45, '23 Ocak 2010', '30 Ocak 2010')]

Grdnz gibi, veriler bir liste iinde demet halinde yer alyor. Ama tabii siz bu
verileri istediiz gibi biimlendirecek kadar Python bilgisine sahipsiniz. Ayrca program her
altrdnzda INSERT INTO sorgusu tekrar iletilecei iin verilerin tabloya tekrar tekrar
yazlacan, bu verileri alrken de kt listesinin byyeceini unutmayn. Peki eer siz bir
veritaban dosyasna verilerin yalnzca bir kez yazlmasn istiyorsanz ne yapacaksnz? Yani
mesela yukardaki kodlarda u sorgu yalnzca tek bir kez iletilsin:
im.execute("""INSERT INTO faturalar VALUES
("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")

Bylece veritabann her altrdnzda ("Elektrik", 45, "23 Ocak 2010", "30 Ocak
2010") satr dosyaya tekrar tekrar yazdrlmasn.
Bunu u kodlarla halledebilirsiniz:
import sqlite3, os

dosya = 'vt.sqlite'
dosya_mevcut = os.path.exists(dosya)

47.15. Seilen Verileri Almak 835


Python 3 iin Trke Klavuz, Srm 3

vt = sqlite3.connect(dosya)
im = vt.cursor()

im.execute("""CREATE TABLE IF NOT EXISTS faturalar


(fatura, miktar, ilk_odeme_tarihi, son_odeme_tarihi)""")

if not dosya_mevcut:
im.execute("""INSERT INTO faturalar VALUES
("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")
vt.commit()

im.execute("""SELECT * FROM faturalar""")

veriler = im.fetchall()
print(veriler)

Burada kodlarmzn en banda vt.sqlite adl bir veritabannn mevcut olup olmadn kontrol
ediyoruz (zira eer ortada bir veritaban dosyas yoksa, veri de yok demektir):
dosya_mevcut = os.path.exists(dosya)

Eer byle bir dosya mevcut deilse (dolaysyla veri mevcut deilse) INSERT INTO sorgusu
iletilerek gerekli veriler yerine yerletirilecek:
if not dosya_mevcut:
im.execute("""INSERT INTO faturalar VALUES
("Elektrik", 45, "23 Ocak 2010", "30 Ocak 2010")""")
vt.commit()

Eer byle bir dosya zaten mevcutsa bu sorgu iletilemeyecek, onun yerine dorudan SELECT
sorgusuna geilecek. Bylece deerler veritabanna bir kez ilendikten sonra, programmz
ayn verileri tekrar tekrar veritabanna yerletirmeye almayacak.
Bu arada, daha nce de belirttiimiz gibi, tablo olutururken stun adlarnda boluk
(ve Trke karakter) kullanmak iyi bir kir deildir. Mesela ilk deme tarihi yerine
ilk_odeme_tarihi ifadesini tercih edin. Eer kelimeler arasnda mutlaka boluk brakmak
isterseniz btn kelimeleri trnak iine aln. Mesela: "ilk odeme tarihi" veya "ilk deme
tarihi" gibi.
Yukarda grdnz gibi, fetchall() metodu, bir veritabanndan SELECT ile setiimiz btn
verileri nmze getiriyor. Eer seilen verilerden ka tanesini almak istediinizi kendiniz
belirlemek istiyorsanz fetchall() yerine fetchone() veya fetchmany() metotlarndan o anki
amacnza uygun olann kullanmay tercih edebilirsiniz. Birazdan fetchone() ve fetchmany()
metotlarndan da sz edeceiz.
Gelin isterseniz imdi fetchall() metodunu kullanarak veritabanlarndan veri ekme
konusunda biraz altrma yapalm. Bu altrmalar iin, daha nce sz ettiimiz ve
bilgisayarmza indirdiimiz kitaplar.sqlite adl rnek veritabann kullanacaz.
ncelikle veritabanna balanalm ve bir imle oluturalm:
>>> import sqlite3
>>> vt = sqlite3.connect('kitaplar.sqlite')
>>> im = vt.cursor()

imdi bu veritabanndaki tabloyu seeceiz. Peki ama seeceimiz tablonun adn nereden
bileceiz? Hatrlarsanz, bir tablodaki btn verileri seebilmek iin u SQL sorgusunu

836 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

kullanyorduk:
"SELECT * FROM tablo_ad"

te bu sorguda tablo_ad ksmna ne geleceini bulabilmek iin birka farkl yntemden


yararlanabiliriz.
Bir veritabannda hangi tablolarn olduunu renmek iin Sqlitebrowser programn
kullanabiliriz. Bir veritaban dosyasn Sqlitebrowser ile atktan sonra, Browse Data
sekmesine gidip, Table ifadesinin karsnda ne yazdna bakabiliriz.
Veritabanndaki tablolarn adn renmenin ikinci yolu u komutlar kullanmaktr:
>>> import sqlite3
>>> vt = sqlite3.connect('kitaplar.sqlite')
>>> im = vt.cursor()
>>> im.execute("SELECT name FROM sqlite_master")
>>> im.fetchall()

Burada u satra dikkat edin:


>>> im.execute("SELECT name FROM sqlite_master")

Btn Sqlite veritabanlarnda, ilgili veritabannn emasn gsteren sqlite_master adl bir
tablo bulunur. te bu tabloyu sorgulayarak veritaban hakknda bilgi edinebiliriz. Yukardaki
rnekte, bu sqlite_master tablosunun name (isim) niteliini sorguladk. Bu sorgu bize u
cevab verdi:
>>> im.fetchall()

[('kitaplar',)]

Demek ki kitaplar.sqlite adl veritabannda kitaplar adl tek bir tablo varm.
Gelin imdi bu bu tablodaki btn verileri alalm:
>>> im.execute("SELECT * FROM kitaplar")
>>> im.fetchall()

Bu ekilde tablo iinde ne kadar veri varsa hepsini ekrana yazdrdk. Ancak tabii ki,
bir veritabannn tamamn bir anda yazdrmak her zaman iyi bir kir olmayabilir. Eer
veritabannn iinde milyonlarca girdi varsa btn verilerin seilip yazdrlmas mantkl
olmayacaktr. Gelin o halde imdi bizim seilen verilerin ne kadarn ekeceimizi
belirleyebilmemizi salayacak metotlar inceleyelim.

47.15.2 fetchone() Metodu

fetchone() metodu, bir veritabanndan seilen verilerin tek tek alnabilmesine izin verir.
Bu metodun nasl kullanlacan kitaplar.sqlite adl rnek veritabanmz zerinden
inceleyelim:
nce veritabanna balanalm:
>>> import sqlite3
>>> vt = sqlite3.connect('kitaplar.sqlite')
>>> im = vt.cursor()

47.15. Seilen Verileri Almak 837


Python 3 iin Trke Klavuz, Srm 3

imdi kitaplar adl tablodan btn verileri seelim:


>>> im.execute("""SELECT * FROM kitaplar""")

<sqlite3.Cursor object at 0x003C2D20>

Artk setiimiz verileri tek tek almaya balayabiliriz:


>>> im.fetchone()

('UZMANLAR N PHP', 'Mehmet aml', '33,00 TL')

Bir tane daha alalm:


>>> im.fetchone()

('ADOBE AR', 'Engin Yen', '28,00 TL')

ki tane daha...
>>> im.fetchone()

('WEB TASARIM REHBER', 'Mustafa Aydemir', '38,50 TL')

>>> im.fetchone()

('ORACLE 11g R2', 'Teoman Dinel', '34,00 TL')

fetchone()n gayet faydal bir metot olduu her halinden belli...

47.15.3 fetchmany() Metodu

Bu metot, bir veritabanndan setiiniz verilerin istediiniz kadarn alabilmenize imkan tanr.
Dikkatlice bakn:
>>> im.fetchmany(5)

[('AS 3.0 LE SUNUCU PROGRAMLAMA', 'Engin Yen', '24,00 TL'),


('HACKING INTERFACE', 'Hamza Elbahadr', '25,00 TL'),
('JAVA VE JAVA TEKNOLOJLER', 'Tevfik Kzlren', '45,00 TL'),
('XML VE LER XML TEKNOLOJLER', 'Musa iek', '24,50 TL'),
('GRAFK&ANMASYON', 'Anonim', '18,50 TL')]

Grdnz gibi, be eden oluan bir liste elde ettik.


Bylece bir veritabanndan seilen verileri almann farkl yntemlerini renmi olduk. Bu
metotlarn dnda, eer arzu ederseniz for dngsnden yararlanarak da veri ekebilirsiniz.
Bunun iin herhangi bir metot kullanmanza gerek yok:
>>> for veri in im:
... print(veri)

Grdnz gibi, for dngsn dorudan imle zerinde kuruyoruz.


Eer amacnz alnacak verilerin saysn snrlamaksa yine for dngsnden ve fetchone()
metodundan birlikte yararlanabilirsiniz:

838 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

>>> for i in range(5):


... print(im.fetchone())

Biraz sonra veri szmeyi rendiimizde, bir veritabanndan veri seip almann daha verimli
yollarn greceiz.

47.16 Veri Szme

Daha nce bir Sqlite veritabannda belli bir tablo iindeki btn verileri semek iin u SQL
komutunu kullanmamz gerektiini renmitik:
SELECT * FROM tablo_adi

Ancak amacmz ou zaman bir tablo iindeki btn verileri semek olmayacaktr.
Programclk maceramz boyunca genellikle yalnzca belli ltlere uyan verileri semek
isteyeceiz. Zira iinde milyonlarca veri barndrabilecek olan veritabanlarndaki verilerin
tamamn semek akl kr deildir.
Verileri szme iini WHERE adl bir SQL komutu yardmyla gerekletireceiz. Bu SQL
komutunun szdizimi yle:
SELECT * FROM tablo_ad WHERE stun_bal = aranan_veri

Grdnz gibi, bu sorguyu gerekletirebilmek iin tablodaki stun balklarn bilmemiz


gerekiyor.
nceki sayfalarda, kitaplar.sqlite adl veritabanmzdaki tablolarn adn nasl
renebileceimizi anlatmtk. Hatrlarsanz bu i iin u komutu kullanyorduk:
>>> im.execute("SELECT name FROM sqlite_master")

Bu ekilde, btn Sqlite veritabanlarnda bulunan sqlite_master adl zel bir tablonun name
niteliini sorgulayarak, elimizdeki veritabannda bulunan tablolarn adn elde edebiliyoruz.
Adn rendiimiz tablodaki stun balklarn elde etmek iin yine buna benzer bir komuttan
yararlanacaz. Dikkatlice bakn:
>>> im.execute("SELECT sql FROM sqlite_master").fetchone()

('CREATE TABLE "kitaplar"


(\n\t`KitapAdi`\tTEXT,\n\t`Yazar`\tTEXT,\n\t`Fiyati`\tTEXT\n)',)

sqlite_master adl tablonun sql niteliini sorguladmzda, ilgili tabloyu oluturmak iin
kullanlan SQL komutunu gryoruz. Bu komuta dikkatli bakarsanz, tablonun KitapAdi,
Yazar ve Fiyati olmak zere stundan olutuunu greceksiniz. Elbette stun adlarn
renmek iin Sqlitebrowser programn da kullanabileceinizi artk biliyorsunuz.
Stun adlarn rendiimize gre gelin imdi yazar adna gre veritabannda bir sorgu
yapalm:
>>> im.execute("SELECT * FROM kitaplar WHERE Yazar = 'Frat zgl'")

Burada sorguyu nasl kurduumuza dikkat edin. Bu sorgunun ilk ksm olan SELECT * FROM
kitaplar ifadesini zaten daha nce renmitik. Yeni olan ksm WHERE Yazar = Frat
zgl. Burada da anlalmayacak bir ey yok. Bu ekilde, veritabanndaki kitaplar
tablosunun Yazar stununda Frat zgl bulunan btn kaytlar seiyoruz.

47.16. Veri Szme 839


Python 3 iin Trke Klavuz, Srm 3

imdi de setiimiz bu verileri alalm:


>>> im.fetchall()

('HERYNYLE PYTHON', 'Frat zgl', '34,00 TL')

Gayet baarl... Bu arada, verileri almak iin fetchall() yerine for dngs
kullanabileceinizi de biliyorsunuz:
>>> for s in im:
... print(s)
...
('HERYNYLE PYTHON', 'Frat zgl', '34,00 TL')

mle zerinde for dngs kurabildiimize gre yldzl parametrelerden de


yararlanabileceimizi tahmin etmisinizdir:
>>> print(*im)

('HERYNYLE PYTHON', 'Frat zgl', '34,00 TL')

47.17 Veritaban Gvenlii

Pythonda veritabanlar ve Sqlite konusunda daha fazla ilerlemeden nce ok nemli bir
konudan bahsetmemiz gerekiyor. Tahmin edebileceiniz gibi, veritaban denen ey olduka
hassas bir konudur. Bilgiyi bir araya toplayan bu sistem, ierdeki bilgilerin deerine ve
nemine de bal olarak nc ahslarn itahn kabartabilir. Ancak depoladnz verilerin
ne kadar deerli ve nemli olduundan bamsz olarak veritaban gvenliini salamak, siz
programclarn asli grevidir.
Peki veritaban ynetim sistemleri acaba hangi tehditlerle kar karya?
SQL komutlarn ileten btn veritabanlar iin gnmzdeki en byk tehditlerden birisi
hi kukusuz kt niyetli kiilerin veritabannza SQL komutu szdrma (SQL injection )
giriimleridir.
imdi yle bir ey dnn: Diyelim ki siz bir alveri karl birine 100.000 TLlik bir ek
verdiniz. Ancak eki verdiiniz kii bu ek zerindeki miktar tahrif ederek artrd ve banka
da tahrif edilerek artrlan bu miktar eki getiren kiiye (hamiline) dedi. Byle bir durumda
epey banz aryacaktr.
te byle tatsz bir durumla karlamamak iin, ek veren kii ekin zerindeki miktar hem
rakamla hem de yazyla belirtmeye zen gsterir. Ayrca rakam ve yazlara ekleme yaplmasn
da engellemek iin rakam ve yazlarn sana soluna # gibi iaretler de koyar. Bylece eki
alan kiinin, kendisine izin verilenden daha fazla bir miktar yazmasn engellemeye alr.
Yukardakine benzer bir ey veritaban uygulamalarnda da karmza kabilir. imdi u
rnee bakalm:
import sqlite3

#vt.sqlite adl bir veritaban dosyas oluturup


#bu veritabanna balanyoruz.
db = sqlite3.connect("vt.sqlite")

840 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

#Veritaban zerinde istediimiz ilemleri yapabilmek


#iin bir imle oluturmamz gerekiyor.
im = db.cursor()

#imlecin execute() metodunu kullanarak, veritaban iinde


#"kullanicilar" adl bir tablo oluturuyoruz. Bu tabloda
#kullanc_adi ve parola olmak zere iki farkl stun var.
im.execute("""CREATE TABLE IF NOT EXISTS kullanicilar
(kullanici_adi, parola)""")

#Yukarda oluturduumuz tabloya yerletireceimiz verileri


#hazrlyoruz. Verilerin liste iinde birer demet olarak
#nasl gsterildiine zellikle dikkat ediyoruz.
veriler = [
("ahmet123", "12345678"),
("mehmet321", "87654321"),
("selin456", "123123123")
]

#veriler adl liste iindeki btn verileri kullanicilar adl


#tabloya yerletiriyoruz. Burada tek eli bir demet
#tanmladmza dikkat edin: (i,)
for i in veriler:
im.execute("""INSERT INTO kullanicilar VALUES %s""" %(i,))

#Yaptmz deiikliklerin tabloya ilenebilmesi iin


#commit() metodunu kullanyoruz.
db.commit()

#Kullancdan kullanc ad ve parola bilgilerini alyoruz...


kull = input("Kullanc adnz: ")
paro = input("Parolanz: ")

#Burada yine bir SQL komutu iletiyoruz. Bu komut, kullanicilar


#adl tabloda yer alan kullanici_adi ve parola adl stunlardaki
#bilgileri seiyor.
im.execute("""SELECT * FROM kullanicilar WHERE
kullanici_adi = '%s' AND parola = '%s'"""%(kull, paro))

#Hatrlarsanz daha nce fetchall() adl bir metottan


#sz etmitik. te bu fetchone() metodu da ona benzer.
#fetchall() btn verileri alyordu, fetchone() ise
#verileri tek tek alr.
data = im.fetchone()

#Eer data adl deiken False deilse, yani bu


#deikenin iinde bir deer varsa kullanc ad
#ve parola doru demektir. Kullancy ieri alyoruz.
if data:
print("Programa hogeldin {}!".format(data[0]))

#Aksi halde kullancya olumsuz bir mesaj veriyoruz.


else:
print("Parola veya kullanc ad yanl!")

Bu rnekte henz bilmediimiz baz ksmlar var. Ama siz imdilik bunlar kafanza takmayn.
Nasl olsa bu kodlarda grnen her eyi biraz sonra tek tek reneceiz. Siz imdilik sadece

47.17. Veritaban Gvenlii 841


Python 3 iin Trke Klavuz, Srm 3

iin zne odaklann.


Yukardaki kodlar altrdnzda, eer kullanc ad ve parolay doru girerseniz Programa
hogeldin ktsn greceksiniz. Eer kullanc adnz veya parolanz yanlsa bununla ilgili bir
uyar alacaksnz.
Her ey iyi ho, ama bu kodlarda ok ciddi bir problem var.
Dediimiz gibi, bu kodlar alrken (teoride) eer kullanc, veritabannda varolan bir kullanc
ad ve parola yazarsa sisteme kabul edilecektir. Eer doru kullanc ad ve parola girilmezse
sistem kullancya giri izni vermeyecektir. Ama acaba gerekten yle mi?
imdi yukardaki program tekrar altrn. Kullanc ad ve parola sorulduunda da her ikisi
iin unu yazn:
x' OR '1' = '1

O da ne! Program sizi ieri ald... Hem de kullanc ad ve parola doru olmad halde... Hatta
u kodu sadece kullanc ad ksmna girip parola ksmn bo brakmanz da sisteme giri hakk
elde etmenize yetecektir.:
x' OR '1' = '1' --

te yukarda gsterdiimiz bu ileme SQL szdrma (SQL injection) ad verilir. Kullanc,


tpk en bata verdiimiz tahrif edilmi ek rneinde olduu gibi, sistemin zaaarndan
yararlanarak, elde etmeye hakk olandan daha fazlasna eriim hakk elde ediyor.
Burada en basit ekliyle bool ilelerinden biri olan ordan yararlanyoruz. orun nasl
ilediini gayet iyi biliyorsunuz, ama ben yine de birka rnekle orun ne olduunu ve ne
yaptn size hatrlataym. u rneklere bakn:
>>> a = 21

>>> a == 22

False

>>> b = 13

>>> b == 13

True

>>> if a == 22 and b == 13:


... print("Merhaba!")
...

>>> if a == 22 or b == 13:
... print("Merhaba!")
...
Merhaba!

rneklerden de grdnz gibi, and ilecinin True sonucunu verebilmesi iin her iki
nermenin de doru olmas gerekir. O yzden a == 22 and b == 13 gibi bir ifade False
deeri veriyor. Ancak or ilecinin True sonucu verebilmesi iin iki nermeden sadece birinin
doru olmas yeterlidir. Bu yzden, sadece b == 13 ksm True olduu halde a == 22 or b
== 13 ifadesi True sonucu veriyor... te biz de yukardaki SQL szdrma giriiminde orun bu
zelliinden faydalanyoruz.

842 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

Dilerseniz neler olup bittiini daha iyi anlayabilmek iin, szdrlan kodu dorudan ilgili satra
uygulayalm:
im.execute("""SELECT * FROM kullanicilar WHERE
kullanici_adi = 'x' OR '1' = '1' AND parola = 'x' OR '1' = '1'""")

Sanrm bu ekilde neler olup bittii daha net grlyor. Durumu biraz daha netletirmek iin
Python yardma arabiliriz:
>>> kullanici_adi = 'ahmet123'

>>> parola = '12345678'

>>> kullanici_adi == 'x'

False

>>> '1' == '1'

True

>>> kullanici_adi == 'x' or '1' == '1'

True

>>> parola == 'x'

False

>>> (kullanici_adi == 'x' or '1' == '1') and (parola == 'x' or '1' == '1')

True

1 == 1 ifadesi her zaman True deeri verecektir. Dolaysyla kullanc adnn ve parolann
doru olup olmamas hibir nem tamaz. Yani her zaman True deerini verecei kesin olan
ifadeler yardmyla yukardaki gibi bir szdrma giriiminde bulunabilirsiniz.
Yukarda yaptmz ey, %s ile gsterilen yerlere kt niyetli bir SQL komutu szdrmaktan
ibarettir. Burada zaten balang ve biti trnaklar olduu iin szdrlan kodda balang ve
biti trnaklarn yazmyoruz. O yzden szdrlan kod yle grnyor:
x' OR '1' = '1

Grdnz gibi, xin bandaki ve 1in sonundaki trnak iaretleri koymuyoruz.


Peki yukarda verdiimiz u kod nasl alyor:
x' OR '1' = '1' --

Pythonda yazdmz kodlara yorum eklemek iin # iaretinden yararlandmz


biliyorsunuz. te SQL kodlarna yorum eklemek iin de iaretlerinden yararlanlr. imdi
dilerseniz yukardaki kodu dorudan ilgili satra uygulayalm ve ne olduunu grelim:
im.execute("""SELECT * FROM kullanicilar WHERE
kullanici_adi = 'x' OR '1'='1' --AND parola = '%s'""")

Burada yazdmz iareti AND parola = %s ksmnn sistem tarafndan yorum olarak
alglanmasn salyor. Bu yzden kodlarn bu ksm iletilmiyor. Dolaysyla da sisteme giri
yapabilmek iin sadece kullanc adn girmemiz yeterli oluyor. Burada ayrca kodlarmzn

47.17. Veritaban Gvenlii 843


Python 3 iin Trke Klavuz, Srm 3

almas iin 1in sonuna bir adet trnak yerletirerek kodu kapattmza dikkat edin. nk
normal biti trna yorum tarafnda kald.
Dikkat ederseniz SQL szdrdmzda ahmet123 adl kullancnn hesabn ele geirmi olduk.
Peki neden tekiler deil de ahmet123? Bunun sebebi, ahmet123 hesabnn tablonun en
banda yer almas. Eer tablonun banda admin diye bir hesap olmu olsayd, veritabanna
azami dzeyde zarar verme imkanna kavuacaktnz.
Peki SQL szdrma giriimlerini nasl nleyeceiz? Bu giriime kar alabileceiniz balca
nlem %s iaretlerini kullanmaktan kanmak olacaktr. Bu iaret yerine ? iaretini
kullanacaksnz. Yani yukardaki program yle yazacaz:
import sqlite3

db = sqlite3.connect("vt.sqlite")

im = db.cursor()

im.execute("""CREATE TABLE IF NOT EXISTS kullanicilar


(kullanici_adi, parola)""")

veriler = [
("ahmet123", "12345678"),
("mehmet321", "87654321"),
("selin456", "123123123")
]

for i in veriler:
im.execute("""INSERT INTO kullanicilar VALUES (?, ?)""", i)

db.commit()

kull = input("Kullanc adnz: ")


paro = input("Parolanz: ")

im.execute("""SELECT * FROM kullanicilar WHERE


kullanici_adi = ? AND parola = ?""", (kull, paro))

data = im.fetchone()

if data:
print("Programa hogeldin {}!".format(data[0]))
else:
print("Parola veya kullanc ad yanl!")

Dediimiz gibi, SQL szdrma giriimlerine kar alabileceiniz balca nlem


%s iaretleri yerine ? iaretini kullanmak olmaldr. Bunun dnda, SQL
komutlarn iletmeden nce baz szgeler uygulamak da gvenlik asndan
iinize yarayabilir. rnein kullancdan alnacak verileri alfanmerik karakterlerle
[http://www.istihza.com/blog/alfanumerik-ne-demek.html/] snrlayabilirsiniz:
if kull.isalnum() and paro.isalnum():
im.execute("""SELECT * FROM kullanicilar WHERE
kullanici_adi = '%s' AND parola = '%s'"""%(kull, paro))

Bylece kullancnn baz tehlikeli karakterleri girmesini engelleyebilir, onlar sadece harf ve
say girmeye zorlayabilirsiniz.

844 Blm 47. Sqlite ile Veritaban Programlama


Python 3 iin Trke Klavuz, Srm 3

Her halkarda unutmamamz gereken ey, gvenliin ok boyutlu bir kavram olduudur.
Birka nlemle pek ok gvenlik an engelleyebilirsiniz, ancak btn gvenlik aklarn
bir rpda yamamak pek mmkn deildir. Bir programc olarak sizin greviniz, yazdnz
programlar gvenlik aklarna kar srekli taramak ve herhangi bir ak ortaya ktnda da
bunu derhal kapatmaya almaktr.

47.18 Blm Sorular

1. Bir veritaban dosyasnn var olup olmadn nasl tespit edersiniz?


2. Bir veritaban iinde belli bir tablonun var olup olmadn tespit edin. Eer yoksa o
tabloyu oluturun, varsa herhangi bir ilem yapmayn.
3. Sqlite ile test amal bir veritaban oluturun. Bu veritaban dosyas, programnz
kapanr kapanmaz ortadan kaybolmal.
4. Aadaki kodlarn istenen veritabann, tabloyu, satr ve stunlar oluturup
oluturmadn teyit edin:
import sqlite3

vt = sqlite3.connect('vt.sqlite')

im = vt.cursor()
im.execute("CREATE TABLE kullanclar (ad, soyad, doumtarihi, eposta)")

vt.commit()
vt.close()

Eer veritaban ierii beklediiniz gibi deilse sebebini aklayn.


5. Sqlite ile bir veritabannn oluturulmas ve bu veritabanna birtakm bilgiler
girilebilmesi iin srasyla hangi ilemlerin yaplmas gerekir?
6. Aadaki resimde yaplmaya allan ey nedir?

7. sqlite3.connect(kitaplar.sqlite) bo bir veritabannn m oluturulduunu yoksa


varolan kitaplar.sqlite adl bir veritaban dosyasna m balandnz nasl teyit
edersiniz?
8. Sqlitebrowser programn ne ekilde kurdunuz? Eer Ubuntu dnda bir GNU/Linux
datmna bu program kurduysanz, programn kurulum aamalarn anlatn.
9. cmake komutu ile birlikte kullandmz . (nokta) iaretinin anlam nedir?
10. Yazdnz bir program kullanan kiilerin, programnz ilk kez altrdklarnda
karlarnda grmeleri gereken verileri veritabanna yerletirmek iin nasl bir yntem
takip edebilirsiniz? Kullanclarnz programnz ikinci kez altrdnda bu verileri
grmemeli.
11. Bir nceki soruda uyguladnz yntemin herhangi bir kstlamas var m? Bu yntem
hangi durumlarda ie yaramaz?
12. Bir veritabanndaki btn tablolarn adn nasl listelersiniz?

47.18. Blm Sorular 845


Python 3 iin Trke Klavuz, Srm 3

846 Blm 47. Sqlite ile Veritaban Programlama


BLM 48

nemli Standart Ktphane Modlleri

Daha nce de sylediimiz gibi, modller Python programlama dilinin belkemiini oluturur.
Hatta Python renmek, bir bakma modlleri renmek demektir, diyebiliriz. Biz her
ne kadar bu noktaya gelene kadar Pythondaki btn temel veri tiplerini ve fonksiyonlar
renmi olsak da modlleri renmeden ve bunlar etkili bir ekilde nasl kullanacamz
bilmeden ie yarar programlar yazamayz.
Mesela diyelim ki veritabanna kayt yapan bir program yazacaksnz. te bu i iin eitli
modllerden yararlanmanz gerekir.
Eer MS Excel veya MS Word gibi dosya biimleri zerinde almalar yapacaksanz, bu
dosyalar zerinde ilem yapabilmenizi salayan birtakm modlleri kullanmanz gerekir.
Ayn ekilde grak bir arayze sahip programlar gelitirebilmek iin de baz standart modlleri
veya nc ahs modllerini kullanmalsnz.
Bu durum oyun programlama, tanabilir cihaz programlama, a programlama, web
programlama ve baka programlama alanlar iin de geerlidir.
Geen blmde, modller konusundan sz ederken Pythondaki standart ktphane
modllerine ve nc ahs modllerine yle bir gz gezdirmitik. nmzdeki bir ka
blm boyunca ise baz nemli standart modlleri ve nc ahs modllerini ayrntl olarak
inceleyeceiz. Bu sayede programclk ufkumuz epey bir genilemi olacak.

48.1 os Modl

Bildiiniz gibi, iletim sistemlerinin alma mant birbirinden farkldr. rnein Windows
ve GNU/Linux iletim sistemleri ayn ii birbirlerinden farkl ekillerde yaparlar. Mesela
Windowsta bir dizin iinde hangi klasr ve dosyalarn olduunu renmek iin dir komutunu
kullanrz. GNU/Linuxta ise ayn ilev iin ls adl bir komut vardr.
Ayn ekilde, iki iletim sistemi arasnda dizin ayralar konusunda da farkllk bulunur.
Windowsta dizinleri birbirinden ayrmak iin ters taksim (\) iareti kullanlrken, GNU/Linuxta
ayn i iin dz taksim (/) iareti kullanlr.

Not: Dz taksim iaretini Windows da kabul eder, ancak Windowsun doal dizin ayrac ters
taksimdir.

te biz hem Windowsta, hem de GNU/Linuxta alacak bir program yazmak istediimizde
bu farkllklar gz nnde bulundurmamz ve farkl durumlarn herbiri iin ayr kodlar

847
Python 3 iin Trke Klavuz, Srm 3

yazmamz gerekirken, os modl bizi bu zahmetten kurtarr ve bize ortak bir arayz
zerinden farkl iletim sistemleri ile tutarl bir ekilde iletiim kurabilmemizi salayacak pek
ok fonksiyon ve nitelik sunar.
Bu nitelik ve fonksiyonlarn neler olduunu dir(os) komutuyla grebileceinizi biliyorsunuz.
Bu blmde, os modlnn sunduu bu fonksiyon ve niteliklerin en nemlilerini ve en yaygn
kullanlanlarn olabildiince ayrntl bir ekilde ele almaya alacaz.

Not: Burada os modln import os komutuyla ie aktarm olduunuz varsaylmaktadr.

48.1.1 os.name

os modlnn, nceki derslerde yle bir deinip getiimiz name nitelii, kullanclarmzn,
yazdmz kodlar hangi iletim sisteminde altrd konusunda bize bilgi verir.
Bu nitelii yle kullanyoruz:
>>> os.name

Eer kodlarmz Windows iletim sistemi zerinde altrlmsa buradan u kty alrz:
'nt'

MacOS ve GNU/Linux iletim sistemleri ise bu komuta u cevab verir:


'posix'

Dolaysyla os.name niteliini kullanarak farkl iletim sistemlerinde farkl alan programlar
yazabiliriz.

48.1.2 os.sep

os modlnn sep nitelii, kodlarmzn alt iletim sisteminin dizin ayracnn ne


olduunu bize gsterir.
Eer bu nitelii Windows iletim sistemi zerinde kullanrsak u kty alrz:
>>> os.sep

'\\'

MacOS ve GNU/Linux iletim sistemleri ise bu komuta u cevab verir:


>>> os.sep

'/'

Peki bu nitelik ne ie yarar?


Bu nitelii kullanarak, farkl iletim sistemlerine zg dizin yollar oluturabilirsiniz. Mesela:
>>> liste = ['aylar', 'mays', 'test']
>>> os.sep.join(liste)

848 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

Burada karakter dizilerinin join() metodunu os.sep ile birlikte kullandmza dikkat edin.
Bu komutu Windowsta verdiinizde u kty alrsnz:
'aylar\\mays\\test'

Ayn komutu GNU/Linuxta verdiinizde ise u kty:


'aylar/mays/test'

Yani yukardaki komutu Windowsta verdiinizde Python u komutu alm gibi davranr:
>>> liste = ['aylar', 'mays', 'test']
>>> '\\'.join(liste)

GNU/Linuxta ise u komutu:


>>> liste = ['aylar', 'mays', 'test']
>>> '/'.join(liste)

Bylece yazdnz programlarda hangi iletim sisteminin hangi dizin ayracn kullandn
dnmenize gerek kalmaz; bunu sizin yerinize Python dnr...

48.1.3 os.getcwd()

os modlnn getcwd() fonksiyonu bize o anda iinde bulunduumuz dizinin adn verir:
>>> os.getcwd()

'/home/istihza/Desktop' #GNU/Linux

veya:
>>> os.getcwd()

'C:\\Documents and Settings\\fozgul' #Windows

48.1.4 os.chdir()

os modlnn chdir() fonksiyonu bize bir dizinden baka bir dizine geme imkan verir.
Mesela GNU/Linuxta, o anda bulunduumuz dizinden /usr/bin adl dizine gemek iin u
komutu kullanabiliriz:
>>> os.chdir('/usr/bin/')

veya Windowsta C:\Documents and Settings\fozgul\Desktop adl dizine gemek iin unu:
>>> os.chdir('C:\\Documents and Settings\\fozgul\\Desktop')

Grdnz gibi, gitmek istediimiz dizin adn os.chdir() fonksiyonuna parametre olarak
vermemiz yeterli oluyor.

48.1. os Modl 849


Python 3 iin Trke Klavuz, Srm 3

48.1.5 os.listdir()

os modlnn listdir() fonksiyonu, bize bir dizin iindeki dosya ve klasrleri listeleme
imkan verir. listdir(), os modlnn en kullanl fonksiyonlarndan biridir.
Mesela o anda iinde bulunduumuz dizindeki dosya ve klasrleri listelemek istersek bu
fonksiyonu yle kullanabiliriz:
>>> mevcut_dizin = os.getcwd()
>>> os.listdir(mevcut_dizin)

Eer farkl bir dizinin ieriini listelemek istersek, parametre olarak o dizinin adn yazmamz
yeterli olacaktr:
>>> os.listdir('/var/www')

Grdnz gibi, os.listdir() komutunun kts liste trnde bir veri tipidir. Dolaysyla
listelerle yapabildiiniz her eyi bununla da yababilirsiniz. Mesela bu liste zerinde bir dng
kurabilirsiniz:
>>> for i in os.listdir(os.getcwd()):
... print(i)

Ya da bir dizin iindeki, belli bir uzantya sahip dosyalar szebilirsiniz:


>>> for i in os.listdir(os.getcwd()):
... if i.endswith('.doc'):
... print(i)

Bu kodlar bize, ad .doc ile biten btn dosyalar listeleyecektir.


Bu arada karakter dizilerinin endswith() adl metodunu hatrlyorsunuz, deil mi?

48.1.6 os.curdir

ou iletim sisteminde mevcut dizini gstermek iin . adl karakter dizisi kullanlr. rnein:
>>> os.listdir(os.getcwd())

gibi bir komut yerine u komutu da kullanabilirsiniz:


>>> os.listdir('.')

listdir() fonksiyonuna parametre olarak verdiimiz . karakter dizisi o anda iinde


bulunduumuz dizini temsil eder.
Eer bu karakter dizisini elle yazmak istemiyorsanz os modl iindeki curdir adl nitelikten
de yararlanabilirsiniz:
>>> os.listdir(os.curdir)

Bu arada os.getcwd() ile os.curdir i birbirine kartrmamalsnz. Bu ikisi ayn ey deildir.


os.getcwd() kt olarak o anda iinde bulunduumuz dizinin adn verir. os.curdir ise, bir
iletim sisteminde, o anda iinde bulunulan dizini temsil eden karakter dizisi ne ise onun
deerini barndrr. Bu deer ou iletim sisteminde . adl karakter dizisidir.

850 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

48.1.7 os.pardir

Tpk . karakter dizisi gibi, ou iletim sisteminde bir st dizini gstermek iin .. adl karakter
dizisi kullanlr. rnein:
>>> os.listdir('..')

komutu, o anda iinde bulunduunuz dizindeki deil, bir st dizindeki dosya ve dizin adlarn
listeleyecektir. Yine tpk os.curdir niteliinde olduu gibi, eer bu karakter dizisini kendiniz
elle yazmak istemezseniz, bu karakter dizisini iinde barndran os.pardir adl bir nitelikten
yararlanabilirsiniz:
>>> os.listdir(os.pardir)

Bu komut, os.listdir(..) ile ayn kty verir.

48.1.8 os.startle()

Uyar: Bu fonksiyon yalnzca Windowsta alr. GNU/Linux iletim sistemlerinde bu


fonksiyon tanml deildir.

os modl iindeki startfile() adl fonksiyonun grevi bilgisayarmzda bulunan herhangi


bir dosyay, ilikilendirilmi olduu programla amaktr.
Hemen bir rnek verelim.
O anda iinde bulunduumuz dizinde deneme.txt adl bir dosya olduunu varsayalm. imdi
de u komutu verelim:
>>> os.startfile('deneme.txt')

letim sisteminiz .txt uzantl dosyalar hangi programla ilikilendirmise, startfile()


fonksiyonu deneme.txt adl dosyay o programla aacaktr. Windowsta .txt dosyalar
genellikle Notepad programyla ilikilendirildii iin yukardaki komutu verdiinizde
muhtemelen deneme.txt dosyasnn ierii Notepad program araclyla grntlenecektir.
Ayn ekilde, o anda bulunduuz dizin iinde deneme.docx adl bir dosyann olduunu
varsayalm ve u komutu verelim:
>>> os.startfile('deneme.docx')

Bu komut da deneme.docx dosyasnn Microsoft Word adl yazlmla almasn salayacaktr.


Eer startfile() fonksiyonuna parametre olarak bir dosya deil de dizin ad verecek
olursanz, o dizin Windows Explorer ile alr. Mesela iinde bulunduumuz dizini Windows
Explorer ile aalm:
>>> os.startfile(os.curdir)

Bunun yerine u komutu kullanabileceinizi de biliyorsunuz:


>>> os.startfile('.')

veya:

48.1. os Modl 851


Python 3 iin Trke Klavuz, Srm 3

>>> os.startfile(os.getcwd())

Bu komut da ayn ilevi yerine getirir.


Peki bir st dizini amak istersek ne yapacaz?
Dikkatlice bakn:
>>> os.startfile(os.pardir)

veya:
>>> os.startfile('..')

Her iki komut da Windows Explorer yardmyla bir st dizinin grntlenmesini salayacaktr.
Elbette startfile() fonksiyonuna parametre olarak belirli bir dizinin adn da verebilirsiniz:
>>> os.startfile(r"C:\Documents and Settings\fozgul")

os.startfile() olduka faydal bir fonksiyondur. Hatta bu fonksiyonu sadece dosyalar


amak iin deil, internet sayfalarn amak iin dahi kullanabilirsiniz:
>>> os.startfile('www.istihza.com')

Ancak bu komutun yalnzca Windowsta alacan unutmayn. O yzden bunun yerine, daha
nce rendiimiz webbrowser modln kullanmak daha doru olacaktr.

48.1.9 os.mkdir()

os modlnn mkdir() fonksiyonu yeni dizinler oluturabilmemizi salar.


rnein:
>>> os.mkdir('yenidizin')

Bu komut, o anda iinde bulunduumuz dizin iinde yenidizin adl bir dizin oluturacaktr.
Elbette eer dizini o anda iinde bulunduunuz dizin iinde deil de farkl bir konumda
oluturmak isterseniz, o konumun ak adresini belirtebilirsiniz:
>>> os.mkdir('/home/istihza/Desktop/yenidizin')

veya:
>>> os.mkdir(r'C:\Documents and Settings\fozgul\yenidizin')

Eer oluturmaya altnz dizin zaten varsa os.mkdir() hata verecektir:


>>> os.mkdir(r'C:\Documents and Settings\fozgul\yenidizin')

FileExistsError: [WinError 183] Halen varolan bir


dosya oluturulamaz: 'yenidizin'

852 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

48.1.10 os.makedirs()

os.makedirs() fonksiyonu biraz nce rendiimiz os.mkdir() fonksiyonuna ok benzese de


aralarnda nemli farklar bulunur.
Biraz nce os.mkdir() fonksiyonunu anlatrken yle bir rnek vermitik:
>>> os.mkdir(r'C:\Documents and Settings\fozgul\yenidizin')

Bu komutun alabilmesi iin, bilgisayarmzda halihazrda C:Documents and Settingsfozgul


yolunun varolmas gerekir. Eer bu yolu oluturan dizinlerden herhangi biri mevcut deilse,
mkdir() fonksiyonu yenidizin adl dizini oluturamaz. Bu fonksiyonun alabilmesi iin,
varolmayan btn dizinleri tek tek oluturmanz gerekir.
os.makedirs() ise os.mkdir() fonksiyonunun aksine, varolmayan st ve alt dizinleri de
oluturma yeteneine sahiptir. rnein:
>>> os.makedirs('/home/istihza/Desktop/aylar/mays/deme/')

Bu komut srasyla aylar, mays ve deme adl dizinleri i ie oluturacaktr. Yani


os.makedirs() komutunun deme adl dizini oluturmas iin aylar ve mays adl dizinlerin
nceden varolmas zorunlu deildir. Bu dizinler varolsa da olmasa da os.makedirs() komutu
deme dizinini oluturabilir. Ama os.mkdir() fonksiyonu byle deildir. Eer os.mkdir()
fonksiyonuyla deme dizinini oluturmak isterseniz, ncelikle aylar ve mays adl dizinleri
oluturmanz gerekir.

48.1.11 os.rename()

os modlnn rename() adl fonksiyonunu kullanarak dizinlerin adlarn deitirebiliriz. Bu


fonksiyon iki parametre alr:
>>> os.rename('dizinin_imdiki_ad', 'dizinin_yeni_ad')

Mesela mevcut alma dizininde deneme adl bir dizin varsa, bu dizinin adn test olarak
deitirmek iin u komutu verebiliriz:
>>> os.rename('deneme', 'test')

Eer zaten test adl bir dizin varsa (ve ii bosa), yukardaki komut GNU/Linuxta test adl
dizinin zerine yazacak, Windowsta ise hata verecektir.

48.1.12 os.replace()

os modlnn replace() fonksiyonu biraz nce rendiimiz rename() fonksiyonu gibi


alr:
>>> os.replace('deneme', 'test')

Bu komut, tpk rename() fonksiyonunda olduu gibi, deneme adl dizinin adn test olarak
deitirecektir.
Eer test adl bir dizin zaten varsa, replace() fonksiyonu, hem Windowsta hem de
GNU/Linuxta, varolan bu test dizininin zerine yazmaya alr. GNU/Linuxta ou durumda
bunu baarr, ancak Windowsta yine de eitli izin hatalar ile karlaabilirsiniz.

48.1. os Modl 853


Python 3 iin Trke Klavuz, Srm 3

48.1.13 os.remove()

os modlnn remove() adl fonksiyonu, bilgisayarmzdaki dosyalar silmemizi salar:


>>> os.remove('dosya_ad')

Yalnz bu komutu ok dikkatli kullanmalsnz. nk bu komut, silme ileminden nce


herhangi bir soru sormadan, dosyay dorudan siler.

48.1.14 os.rmdir()

os modlnn rmdir() fonksiyonu, ii bo bir dizini silmek iin kullanlr:


>>> os.rmdir('dizin_ad')

Eer silmeye altnz dizin iinde herhangi bir baka dizin veya dosya varsa bu fonksiyon
hata verecektir.
Mesela yle bir dizin yaps dnelim:
|___ anadizin
|___ dizin1
|___ dizin2
|___ dizin3
|___ dizin4

Bu arada, bu dizin yapsn kolayca oluturmak iin ne yapmanz gerektiini biliyorsunuz:


>>> os.makedirs('anadizin/dizin1/dizin2/dizin3/dizin4')

Anadizin altndayken u komutlar hata verecektir:


>>> os.rmdir('anadizin')
>>> os.rmdir(r'anadizin/dizin1')
>>> os.rmdir(r'anadizin/dizin1/dizin2/dizin3')

nk bu dizinlerinin hibirinin ii bo deil; her birinin iinde birer dizin var. Ama u komut
baarl olacaktr:
>>> os.rmdir(r'anadizin/dizin1/dizin2/dizin3/dizin4')

Bu ekilde yukar doru ilerleyerek srayla btn dizinleri silebilirsiniz:


>>> os.rmdir(r'anadizin/dizin1/dizin2/dizin3/')
>>> os.rmdir(r'anadizin/dizin1/dizin2/')
>>> os.rmdir(r'anadizin/dizin1')
>>> os.rmdir(r'anadizin/')

48.1.15 os.removedirs()

os modlnn removedirs() fonksiyonu, ii bo dizin yollarn silmemizi salar. Peki bu ne


demek?
Diyelim ki elimizde yle bir dizin yaps var:

854 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

|___ anadizin
|___ dizin1
|___ dizin2
|___ dizin3
|___ dizin4

Anadizin altndan u komutu verdiimizde:


>>> os.removedirs('anadizin/dizin1/dizin2/dizin3/dizin4')

Eer btn dizinlerin ii bosa, anadizin den dizin4 e kadar olan btn dizinler (anadizin ve
dizin4 dahil) silinecektir.

48.1.16 os.stat()

os modlnn stat() fonksiyonu dosyalar hakknda bilgi almamz salar. Bu fonksiyonu


kullanarak bir dosyann boyutunu, oluturulma tarihini, deitirilme tarihini ve eriilme
tarihini sorgulayabiliriz.
stat() fonksiyonunu yle kullanyoruz:
>>> dosya = os.stat('dosya_ad')
>>> dosya

Buradan una benzer bir kt alrz:


os.stat_result(st_mode=33279, st_ino=17732923532961356,
st_dev=1745874298, st_nlink=1, st_uid=0, st_gid=0,
st_size=495616, st_atime=1416488851, st_mtime=1415275662,
st_ctime=1415275658)

Bu, kendi iinde birtakm nitelikler barndran zel bir veri tipidir. Bu veri tipinin barndrd
nitelikleri grmek iin, her zaman olduu gibi dir() fonksiyonundan yararlanabilirsiniz:
dir(dosya)

Burada zellikle iimize yarayacak olan nitelikler unlardr:


st_atime dosyaya en son eriilme tarihi
st_ctime dosyann oluturulma tarihi (Windowsta)
st_mtime dosyann son deitirilme tarihi
st_size dosyann boyutu
Mesela bir dosyann boyutunu renmek iin st_size niteliini u ekilde kullanabiliriz:
>>> dosya = os.stat('dosya_ad')
>>> dosya.st_size

Bu fonksiyon bize bayt cinsinden bir kt verir. Bunu kilobayta evirmek iin, bu deeri
1024e blebilirsiniz:
>>> dosya.st_size / 1024

os modlnn stat() fonksiyonunu kullanarak bir dosyann oluturulma, eriilme ve


deitirilme tarihlerini de elde edebilirsiniz:

48.1. os Modl 855


Python 3 iin Trke Klavuz, Srm 3

>>> dosya = os.stat('dosya_ad')


>>> dosya.st_ctime #oluturulma tarihi
>>> dosya.st_atime #eriilme tarihi
>>> dosya.st_mtime #deitirme tarihi

Uyar: GNU/Linuxta bir dosyann ne zaman oluturulduunu renmek mmkn


deildir. Dolaysyla dosya.st_ctime komutu yalnzca Windowsta bir dosyann
oluturulma tarihi verir. Bu komutu GNU/Linuxta verdiimizde elde edeceimiz ey
dosyann son deitirilme tarihidir.

Bu arada, yukardaki komutlarn kts size anlamsz gelmi olabilir. Birazdan, datetime
adl bir modl rendiimizde bu anlamsz grnen saylar anlaml tarih bilgilerine nasl
dntreceimizi de anlatacaz.

48.1.17 os.system()

os modlnn system() fonksiyonu Python iinden sistem komutlarn veya baka


programlar altrabilmemizi salar. Mesela:
>>> os.system('notepad.exe')

48.1.18 os.urandom()

os modlnn urandom() fonksiyonu rastgele bayt dizileri elde etmek iin kullanlabilir:
>>> os.urandom(12)

Bu komut, 12 bayttan oluan rastgele bir dizi oluturur. Buradan elde ettiiniz rastgele deeri
kriptograk almalarda veya rastgele parola retme ilemlerinde kullanabilirsiniz.

48.1.19 os.walk()

Hatrlarsanz nceki sayfalarda os modl iindeki listdir() adl bir fonksiyondan sz


etmitik. Bu fonksiyon, bir dizinin ieriini listeleme imkan veriyordu bize. Mesela o anda
iinde bulunduumuz dizinde hangi dosya ve alt dizinlerin olduunu renmek iin yle bir
komut kullanabiliyorduk:
>>> os.listdir('.')

['build.py', 'gtk', 'kitap', 'make.bat', 'Makefile',


'meta_conf.py', 'py2', 'py3', 'theme', 'tk2', '__pycache__']

Grdnz gibi bu fonksiyon yalnzca kendisine parametre olarak verilen dizinin ieriini
listeliyor. rnein yukardaki ktda grnen gtk, kitap, py2, py3, theme, tk2 ve
__pycache__ birer dizin. Ama listdir() fonksiyonu bu dizinlerin de iine girip buradaki ierii
listelemeye almyor. Eer biz mesela theme dizininin ieriini de listelemek istersek bunu
aka belirtmemiz gerekir:
>>> os.listdir('theme')

856 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

['layout.html', 'localtoc.html', 'pydoctheme',


'sidebar.html', 'static']

Veya theme dizini iindeki static adl dizine de erimek istersek bunu da u ekilde ak ak
ifade etmemiz gerekir:
>>> os.listdir('theme/static')

['basic.css', 'copybutton.js', 'py.png', 'sidebar.js']

Peki ya biz o anda iinde bulunduumuz dizinden itibaren ie doru btn dizinleri otomatik
olarak taramak istersek ne yapacaz?
Bunun iin listdir() fonksiyonunu kullanarak zyinelemeli (recursive) bir fonksiyon
yazabilirsiniz:
import os

def tara(dizin):
balang = os.getcwd()
dosyalar = []
os.chdir(dizin)

for e in os.listdir(os.curdir):
if not os.path.isdir(e):
dosyalar.append(e)
else:
dosyalar.extend(tara(e))

os.chdir(balang)
return dosyalar

Not: Bu kodlarda henz renmediimiz tek ey os.path.isdir() fonksiyonu. Bu fonksiyon,


kendisine parametre olarak verilen bir deerin dizin olup olmadn tespit etmemizi salyor.

Yukardaki kodlarda ncelikle o anda iinde bulunduumuz dizinin konumunu balang adl
bir deikene atyoruz. nk daha sonra buraya dnmemiz gerekecek:
balang = os.getcwd()

Ardndan dosyalar adl bir liste oluturuyoruz:


dosyalar = []

Bu liste, dizinler iindeki btn dosyalar iinde barndracak.


Daha sonra, tara() fonksiyonuna parametre olarak verilen dizin adl dizinin iine giriyoruz:
os.chdir(dizin)

Bu dizinin iine girdikten sonra, mevcut dizin iindeki btn eleri listdir() fonksiyonu ile
tek tek taryoruz:
for e in os.listdir(os.curdir):
...

Eer tarama srasnda karlatmz e bir dizin deil ise:

48.1. os Modl 857


Python 3 iin Trke Klavuz, Srm 3

if not os.path.isdir(e):
...

Bu eyi, dorudan en bata tanmladmz dosyalar adl listeye gnderiyoruz:


dosyalar.append(e)

Ama eer tarama srasnda karlatmz e bir dizin ise:


else:
...

tara() fonksiyonunun en bana dnp, tanmladmz btn ilemleri bu dizin zerine


zyinelemeli olarak uyguluyoruz ve elde ettiimiz eleri dosyalar adl listeye extend()
metodu ile iliyoruz:
dosyalar.extend(tara(e))

Burada neden append() deil de extend() kullandmz anlamak iin, yukardaki kodu bir
de append() ile yazp elde ettiiniz kty deerlendirebilirsiniz.
for dngsnden ktktan sonra da tekrar en bataki konuma dnebilmek iin aadaki
komutu altryoruz:
os.chdir(balang)

Eer bu ekilde baa dnmezsek, dizin yaps iindeki ilk alt dizine girildikten sonra
programmz o konumda takl kalaca iin teki st dizinlerin iini tarayamaz. Bunun ne
demek olduunu anlamak iin kodlar bir de os.chdir(balang) kodu olmadan altrmay
deneyebilirsiniz.
Yukardaki yntem doru olsa da, Pythonda bir dizini en dibe kadar taramann en iyi yolu
deildir. Python bize bu i iin zel bir fonksiyon sunar. te, bu blmde ele alacamz bu
fonksiyonun ad walk().
Walk kelimesi ngilizcede yrmek anlamna gelir. walk() fonksiyonu da, kelimenin bu
anlamna uygun olarak, dizinler iinde yrnmesini salar. Gelin bunu biraz aklayalm.
yle bir durum dnn: Sabit diskinizde, bir dizin iinde pek ok alt dizine dalm bir sr
dosya var. Yani unun gibi:
+anadizin
|dosya.txt
|dosya.doc
|dosya.xls
|dosya.jpeg
+resimler
|resim1.jpeg
|resim2.jpeg
|resim3.jpeg
|resim4.jpeg
+bakadosyalar
|dosya.pdf
|dosya.zip
|dosya.mp3
|dosya.ogg
|dosya.jpeg

858 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

Siz bu i ie gemi dosya yn iinden, sonu .jpeg ile bitenleri tek bir yerde toplamak
istiyorsunuz. Elbette, eer isterseniz bu .jpeg dosyalarn tek tek elle bulup istediiniz yere
tayabilirsiniz. Ama bu yntem bir Python programcsna yakmaz, deil mi?
Python programclar bu tr angaryalar kendi yapmak yerine Pythona yaptrmay tercih eder.
O yzden biz de bu ii yapmak iin Pythondan yararlanacaz.
os modlnn walk() fonksiyonunu kullanarak bu grevi rahatlkla yerine getirebilirsiniz.
Peki ama nasl?
ncelikle u kodlar yardmyla, yukardaki szn ettiimiz dosya-dizin yapsn oluturalm.
Bylece daha somut bir yap zerinde alma imkan elde etmi oluruz:
import os

uzantlar = ['txt', 'doc', 'xls',


'jpeg', 'pdf', 'zip',
'mp3', 'ogg', 'jpeg']

ablon1 = ['{}.{}'.format('dosya', i) for i in uzantlar[:4]]


ablon2 = ['resim{}.{}'.format(i, uzantlar[-1]) for i in range(1, 5)]
ablon3 = ['{}.{}'.format('dosya', i) for i in uzantlar[4:]]

dosyalar = [('anadizin', ablon1),


('resimler', ablon2),
('bakadosyalar', ablon3)]

os.makedirs(os.sep.join([dosya[0] for dosya in dosyalar]))

for dizin, ablon in dosyalar:


for s in ablon:
open(os.sep.join([dizin, s]), 'w')
os.chdir(dizin)

Bu kodlarda, u ana kadar grmediimiz, renmediimiz hibir ey yok. Bu kodlar rahatlkla


anlayabilecek kadar Python bilgisine sahipsiniz.
Dosya-dizin yapmz oluturduumuza gre, os modlnn walk() fonksiyonunu bu yap
zerinde nasl kullanacamza geebiliriz.
imdi anadizin adl klasrn bulunduu dizin iinde etkileimli kabuu balatalm ve u
komutlar verelim:
>>> for i in os.walk('anadizin'):
... print(i)

Buradan u kty alacaz:


('anadizin', ['resimler'], ['dosya.doc', 'dosya.jpeg',
'dosya.txt', 'dosya.xls'])
('anadizin\\resimler', ['bakadosyalar'], ['resim1.jpeg',
'resim2.jpeg', 'resim3.jpeg', 'resim4.jpeg'])
('anadizin\\resimler\\bakadosyalar', [], ['dosya.jpeg',
'dosya.mp3', 'dosya.ogg', 'dosya.pdf', 'dosya.zip'])

nceleme kolayl asndan bu ktnn ilk ksmn ele alalm:

48.1. os Modl 859


Python 3 iin Trke Klavuz, Srm 3

('anadizin', ['resimler'], ['dosya.doc', 'dosya.jpeg',


'dosya.txt', 'dosya.xls'])

Grdnz gibi, burada eli bir demet var. ktnn dier ksmlarn da incelerseniz ayn
yapy greceksiniz. Dolaysyla os.walk() komutu bize u eden oluan bir demet verir:
(kkdizin, altdizinler, dosyalar)

Yukardaki kty incelediinizde bu yapy rahatlkla grebilirsiniz:


kkdizin => 'anadizin'
altdizinler => ['resimler']
dosyalar => ['dosya.doc', 'dosya.jpeg',
'dosya.txt', 'dosya.xls']

kkdizin => 'anadizin\\resimler'


altdizinler => ['bakadosyalar']
dosyalar => ['resim1.jpeg', 'resim2.jpeg',
'resim3.jpeg', 'resim4.jpeg']

kkdizin => 'anadizin\\resimler\\bakadosyalar'


altdizinler => []
dosyalar => ['dosya.jpeg', 'dosya.mp3',
'dosya.ogg', 'dosya.pdf',
'dosya.zip']

Mesela bu eli demet iinden yalnzca dosyalar almak isterseniz yle bir komut
verebilirsiniz:
>>> for kkdizin, altdizinler, dosyalar in os.walk('anadizin'):
... print(dosyalar)

Burada, os.walk(anadizin) komutunun bize sunduu eli demetin herbir esini, u


satr yardmyla tek tek kkdizin, altdizinler ve dosyalar adl deikenlere atyoruz:
>>> for kkdizin, altdizinler, dosyalar in os.walk('anadizin'):
... ...

Sonra da bu l iinden, dosyalar adl deikeni ekrana yazdryoruz:


>>> print(dosyalar)

Bu da bize yle bir kt veriyor:


['dosya.doc', 'dosya.jpeg', 'dosya.txt', 'dosya.xls']
['resim1.jpeg', 'resim2.jpeg', 'resim3.jpeg', 'resim4.jpeg']
['dosya.jpeg', 'dosya.mp3', 'dosya.ogg', 'dosya.pdf', 'dosya.zip']

Grdnz gibi, bu ktda anadizin ve bunun altndaki btn dizinlerde yer alan btn
dosyalar var. Bu konunun banda walk() fonksiyonunu tanmlarken dediimiz gibi, walk()
fonksiyonu gerekten de dizinler iinde yrnmesini salyor.
Bu fonksiyonu daha iyi anlamak iin birka deneme daha yapalm:
>>> for kkdizin, altdizinler, dosyalar in os.walk('anadizin'):
... print(altdizinler)
...

860 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

['resimler']
['bakadosyalar']

Bu da bize anadizin iindeki alt dizinlerin isimlerini veriyor.


Bir de kkdizin deikeninin ne olduuna bakalm:
>>> for kkdizin, altdizinler, dosyalar in os.walk('anadizin'):
... print(yol)
...
anadizin
anadizin\resimler
anadizin\resimler\bakadosyalar

Burada da o l deikenler arasndan kkdizin i yazdrdk ve grdk ki bu deiken bize


btn kk dizinlere ilikin yol bilgilerini, yani dizinlerin adresini veriyor. Dolaysyla kkdizin
deikeni ile dosyalar deikenini birletirerek bir dosyann tam adresini elde edebiliriz.
Dikkatlice bakn:
>>> for kkdizin, altdizinler, dosyalar in os.walk('anadizin'):
... for dosya in dosyalar:
... print(os.sep.join([yol, dosya]))
...
anadizin\dosya.doc
anadizin\dosya.jpeg
anadizin\dosya.txt
anadizin\dosya.xls
anadizin\resimler\resim1.jpeg
anadizin\resimler\resim2.jpeg
anadizin\resimler\resim3.jpeg
anadizin\resimler\resim4.jpeg
anadizin\resimler\bakadosyalar\dosya.jpeg
anadizin\resimler\bakadosyalar\dosya.mp3
anadizin\resimler\bakadosyalar\dosya.ogg
anadizin\resimler\bakadosyalar\dosya.pdf
anadizin\resimler\bakadosyalar\dosya.zip

Bildiiniz gibi, dosya deikeninin bize verdii veri tipi bir listedir. O yzden bu listenin
elerini tek tek alabilmek iin bu liste zerinde de bir for dngs kurduumuza dikkat
edin.
Eer yukardaki dizinler iinde yer alan btn .jpeg dosyalarn listelemek istersek de yle
bir kod yazabiliriz:
>>> for kkdizin, altdizinler, dosyalar in os.walk('anadizin'):
... for dosya in dosyalar:
... if dosya.endswith('.jpeg'):
... print(dosya)
...
dosya.jpeg
resim1.jpeg
resim2.jpeg
resim3.jpeg
resim4.jpeg
dosya.jpeg

Grdnz gibi, os.walk() fonksiyonu gayet pratik ve kullanl bir ara.

48.1. os Modl 861


Python 3 iin Trke Klavuz, Srm 3

48.1.20 os.environ

os modlnn environ adl nitelii, kullandmz iletim sistemindeki evre deikenleri


hakknda bilgi edinmemizi salar.
Bu nitelik alelade bir szlktr. Dolaysyla bu szln iinde neler olduunu u kodlarla
grebilirsiniz:
>>> for k, v in os.environ.items():
... print(k.ljust(10), v)

Szlk iindeki istediiniz bir deere nasl erieceinizi biliyorsunuz:


>>> os.environ['HOMEPATH']

'\\Documents and Settings\\fozgul'

>>> os.environ['USERNAME']

'FOZGUL'

Yalnz, Windows ve GNU/Linux iletim sistemlerinde evre deikenleri ve bunlarn adlar


birbirinden farkl olduu iin, doal olarak environ nitelii de farkl iletim sistemlerinde
farkl ktlar verir. Birden fazla iletim sistemi zerinde alacak ekilde tasarladmz
programlarda bu duruma dikkat etmeliyiz. rnein Windowsta kullanc adn veren evre
deikeni USERNAME iken, GNU/Linuxta bu deiken USER olarak adlandrlr.

48.1.21 os.path

os modl zerinde dir() fonksiyonunu uyguladnzda, orada path adl bir niteliin
olduunu greceksiniz. Bu nitelik, kendi iinde pek ok nemli fonksiyon ve baka nitelik
barndrr.
imdi bu blmde os.path adl bu niteliin ieriini inceleyeceiz.

os.path.abspath()

abspath() fonksiyonu, bir dosyann tam yolunun ne olduunu syler:


>>> os.path.abspath('falanca.txt')

os.path.dirname()

dirname() fonksiyonu, bir dosya yolunun dizin ksmn verir:


>>> os.path.dirname('/home/istihza/Desktop/falanca.txt')

'/home/istihza/Desktop'

Bu fonksiyonu abspath() fonksiyonu ile birlikte kullanabilirsiniz:


>>> os.path.dirname(os.path.abspath('falanca.txt'))

'/home/istihza/Desktop'

862 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

os.path.exists()

exists() fonksiyonu bir dosya veya dizinin varolup olmadn kontrol eder:
>>> os.path.exists('/home/istihza/Desktop/falanca.txt')

Eer byle bir dosya varsa yukardaki kod True kts, yoksa False kts verir.

os.path.expanduser()

expanduser() fonksiyonu bilgisayardaki kullancya ait dizinin adresini verir:


>>> os.path.expanduser('~')

'C:\\Documents and Settings\\fozgul'

veya:
>>> os.path.expanduser('~')

'/home/istihza'

Bu fonksiyonu kullanarak, Windowsta belirli bir kullanc ismi ve dizini de oluturabilirsiniz:


>>> os.path.expanduser('~denizege')

'C:\\Documents and Settings\\denizege'

os.path.isdir()

isdir() fonksiyonu, kendisine parametre olarak verilen enin bir dizin olup olmadn
sorgular:
>>> os.path.isdir('/home/istihza')

Eer parametre bir dizin ise True, eer bir dosya ise False kts alnr.

os.path.isle()

isfile() fonksiyonu, kendisine parametre olarak verilen enin bir dosya olup olmadn
sorgular:
>>> os.path.isfile('/home/istihza/falance.txt')

Eer parametre bir dosya ise True, eer bir dizin ise False kts alnr.

os.path.join()

join() fonksiyonu, kendisine verilen parametrelerden, ilgili iletim sistemine uygun yol
adresleri oluturur:

48.1. os Modl 863


Python 3 iin Trke Klavuz, Srm 3

>>> os.path.join('dizin1', 'dizin2', 'dizin3') #Windows

'dizin1\\dizin2\\dizin3'

>>> os.path.join('dizin1', 'dizin2', 'dizin3')

'dizin1/dizin2/dizin3'

os.path.split()

split() fonksiyonu, bir yol adresinin son ksmn ba ksmndan ayrr:


>>> os.path.split('/home/istihza/Desktop')

('/home/istihza', 'Desktop')

Bu fonksiyonu kullanarak dosya adlarn dizin adlarndan ayrabilirsiniz:


>>> dizin, dosya = os.path.split('/home/istihza/Desktop/falanca.txt')
>>> dizin

'/home/istihza/Desktop'

>>> dosya

'falanca.txt'

os.path.splitext()

splitext() fonksiyonu dosya ad ile uzantsn birbirinden ayrmak iin kullanlr:


>>> dosya, uzant = os.path.splitext('falanca.txt')
>>> dosya

'falanca'

>>> uzant

'.txt'

Grdnz gibi, kendi iinde pek ok nitelik ve fonksiyon barndran os.path, kullandmz
iletim sistemine uygun ekilde dizin ilemleri yapabilmemizi salayan son derece faydal bir
aratr.
Gelin isterseniz imdi biraz bu os.path niteliinin baz nemli zelliklerinden sz edelim.
Hatrlarsanz nceki derslerimizde, modllerin kaynak dosyalarn grmemizi salayan
__file__ adl bir aratan sz etmitik. Mesela bu arac os modl zerinde uyguladmzda
una benzer bir kt alyorduk:
>>> os.__file__

'C:\\Python\\lib\\os.py'

Demek ki os modlnn kaynak kodlar bu dizin iinde yer alyormu...

864 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

Normalde __file__ niteliini yalnzca modl adlarna uygulayabilirsiniz. Modllerin nitelik


ve fonksiyonlar zerinde __file__ arac kullanlamaz:
>>> os.name.__file__

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__file__'

>>> os.walk.__file__

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
AttributeError: 'function' object has no attribute '__file__'

Ama os modlnn path nitelii iin durum biraz farkldr:


>>> os.path.__file__

Eer bu komutu Windowsta verdiyseniz u kty alrsnz:


`C:\Python35\lib\ntpath.py'
Ama eer bu komutu GNU/Linuxta verdiyseniz una benzer bir kt alrsnz:
`/home/python35/lib/python3.5/posixpath.py'
Grdnz gibi, __file__, os.path zerinde kullanlabiliyor. Yukardaki ktlardan
anladmza gre os.path nitelii Windowsta ntpath, GNU/Linuxta ise posixpath adl bir
modle atfta bulunuyor.
Dolaysyla aslnda biz os.path niteliini kullanrken, eer Windowsta isek ntpath adl bir
modl, ama eer GNU/Linuxta isek posixpath adl bir modl ie aktarm oluyoruz.
Eer os.path adl ortak bir arayz olmasayd, yukarda os.path bal altnda incelediimiz
aralar kullanabilmek iin, kullandmz iletim sistemine gre posixpath veya ntpath
modllerinden uygun olann kendimiz elle ie aktarmak zorunda kalacaktk:
if os.name == 'nt':
import ntpath as path

else:
import posixpath as path

Ama Python programlama dilinin bize os.path adl nitelii sunmu olmas sayesinde Windows
iletim sistemi iin ntpath, GNU/Linux iletim sistemi iin ise posixpath modln ayr ayr
ie aktarmamza gerek kalmyor. Btn ii bizim yerimize Python hallediyor. Bylece farkl
iletim sistemlerine ilikin birbirinden farkl ilemleri, os.path adl tek bir arayz zerinden
gerekletirebiliyoruz.

48.2 sys Modl

Tpk os modl gibi, sys de Python programlama dilindeki nemli standart ktphane
modllerinden biridir. Bu modl, kullandnz Python srm ile ilgili bilgi edinmenizi ve
kullandnz Python srm ile eitli ilemler yapabilmenizi salar.
Btn modllerde olduu gibi, bu modl de u komutla ie aktaryoruz:

48.2. sys Modl 865


Python 3 iin Trke Klavuz, Srm 3

>>> import sys

Bu modln iinde hangi nitelik ve fonksiyonlarn olduunu grmek iin u komutu


kullanabileceinizi biliyorsunuz:
>>> dir(sys)

Grdnz gibi bu modl iinde de epeyce fonksiyon ve nitelik var. Biz bu blmde, sys
modlnn en yaygn kullanlan, en nemli fonksiyon ve niteliklerini ele alacaz.
lk olarak exit() fonksiyonu ile balayalm...

48.2.1 sys.exit()

sys modlnn exit() fonksiyonunu kullanarak, programnzn ileyiini durdurabilir,


programnz kapanmaya zorlayabilirsiniz. Basit bir rnek verelim:
import sys

say = input('Bir say girin: ')

if int(say) < 0:
print('klyor...')
sys.exit()

else:
print(say)

Eer kullanc 0dan kk bir say girerse programmz sys.exit() komutunun etkisiyle
almay durdurup kapanacaktr.

48.2.2 sys.argv

sys modlnn argv nitelii, yazdmz program altrlrken kullanlan parametreleri bir
liste halinde tutar.
Gelin isterseniz bunun ne demek olduunu bir rnek zerinde gsterelim.
imdi mesela masastnde deneme.py adl bir dosya oluturun ve iine unlar yazn:
import sys
print(sys.argv)

Bu program u komutla altrn:


python deneme.py

Program altrdnzda una benzer bir kt alacaksnz:


['deneme.py']

Grdnz gibi, sys.argv komutu bize bir liste veriyor. Bu listenin ilk esi, yazdmz
programn ad. Yani deneme.py.
imdi ayn program bir de u ekilde altralm:

866 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

python deneme.py parametre

Bu defa programmz bize u kty verecek:


['deneme.py', 'parametre']

Grdnz gibi, sys.argv komutu, programn ismi ile birlikte, bu programa parametre
olarak verilen deerleri de bir liste halinde saklyor. Bu olduka nemli ve kullanl bir
zelliktir. Bu zellikten pek ok farkl ekillerde yararlanabilirsiniz.
Mesela:
import sys

def k():
print('klyor...')
sys.exit()

if len(sys.argv) < 2:
print('Gerekli parametreleri girmediniz!')
k()

elif len(sys.argv) > 2:


print('ok fazla parametre girdiniz!')
k()

elif sys.argv[1] in ['-v', '-V']:


print('Program srm: 0.8')

else:
mesaj = 'Girdiiniz parametre ({}) anlalamad!'
print(mesaj.format(sys.argv[1]))
k()

Burada ncelikle modlmz ie aktardk:


import sys

Bunu yapmadan, o modl kullanamayacamz biliyorsunuz.


Ardndan k() adl bir fonksiyon tanmladk:
def k():
print('klyor...')
sys.exit()

Program sonlandrmak istediimizde bu fonksiyonu kullanacaz.


Daha sonra yle bir if blou oluturduk:
if len(sys.argv) < 2:
print('Gerekli parametreleri girmediniz!')
k()

Eer sys.argv listesinin uzunluu 2den dkse, programmz herhangi bir parametre
olmadan, yalnzca ismiyle altrlm demektir. Bu durumda kullancya Gerekli
parametreleri girmediniz! mesajn gsterip program sonlandryoruz.
Sonraki kod bloumuz yle:

48.2. sys Modl 867


Python 3 iin Trke Klavuz, Srm 3

elif len(sys.argv) > 2:


print('ok fazla parametre girdiniz!')
k()

Eer sys.argv listesi 2den bykse, programmz birden fazla parametre ile altrlm
demektir. Bu durumda kullancya ok fazla parametre girdiniz! mesajn gsterip yine
program sonlandryoruz.
Bir sonraki kodlarmz yle:
elif sys.argv[1] in ['-v', '-V']:
print('Program srm: 0.8')

Eer sys.argv listesinin ikinci esi -v veya -V ise programmzn srm bilgisini veriyoruz.
Son olarak da u blou yazyoruz:
else:
mesaj = 'Girdiiniz parametre ({}) anlalamad!'
print(mesaj.format(sys.argv[1]))
k()

Kullancnn -v veya -V dnda bir parametre girmesi durumunda ise, girilen parametrenin
anlalamad konusunda kullancy bilgilendirip programdan kyoruz.
Aada, programmzn hangi komutlara hangi karlklar verdiini gryorsunuz:
C:\Users\fozgul\Belgelerim> python deneme.py
Gerekli parametreleri girmediniz!
klyor...

C:\Users\fozgul\Belgelerim> python deneme.py -a


Girdiiniz parametre (-a) anlalamad!
klyor...

C:\Users\fozgul\Belgelerim> python deneme.py -a -b


ok fazla parametre girdiniz!
klyor...

C:\Users\fozgul\Belgelerim> python deneme.py -v


Program srm: 0.8

C:\Users\fozgul\Belgelerim> python deneme.py -V


Program srm: 0.8

48.2.3 sys.executable

Eer, yazdnz bir programda, programnzn alt sistemdeki Pythonn altrlabilir


dosyasnn adn ve yolunu renmeniz gerekirse bu nitelii kullanabilirsiniz:
>>> sys.executable

C:\Python35python.exe

868 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

48.2.4 sys.getwindowsversion()

Bu fonksiyon, kullanlan Windows srmne ilikin bilgi verir:


>>> sys.getwindowsversion()

sys.getwindowsversion(major=5, minor=1, build=2600,


platform=2, service_pack='Service Pack 3')

Uyar: Bu fonksiyon yalnzca Windowsta alr. GNU/Linuxta bu fonksiyon tanml


deildir.

Bu fonksiyon kendi iinde de baz nitelikler barndrr. Bunlar grmek iin u komutu
kullanabilirsiniz:
>>> ver = sys.getwindowsversion()
>>> dir(ver)

['__add__', '__class__', '__contains__', '__delattr__',


'__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__getnewargs__',
'__gt__', '__hash__', '__init__', '__iter__', '__le__',
'__len__', '__lt__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__rmul__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'build', 'count', 'index', 'major', 'minor', 'n_fields',
'n_sequence_fields', 'n_unnamed_fields', 'platform',
'product_type', 'service_pack', 'service_pack_major',
'service_pack_minor', 'suite_mask']

Bu niteliklere erimek iin u sz dizimini kullanabilirsiniz:


>>> ver.service_pack()

48.2.5 sys.path

Modller konusunu ilerken sys modlnn path niteliinden sz etmitik. O yzden orada
sylediklerimizi tekrarlamayacaz.

48.2.6 sys.platform

os modln incelerken rendiimiz name nitelii gibi, sys modlnn platform adl
nitelii de, kodlarmzn alt iletim sistemi hakknda bize bilgi verir:
>>> sys.platform

Eer bu komutu GNU/Linuxta verirsek linux kts, Windowsta verirsek win32 kts, Mac OS
Xte verirsek darvin kts alrz.

48.2.7 sys.prex

sys modlnn prex nitelii Pythonn hangi dizine kurulduunu gsterir:

48.2. sys Modl 869


Python 3 iin Trke Klavuz, Srm 3

>>> sys.prefix

'/home/local/python'

Veya:
>>> sys.prefix

'C:\\Python'

48.2.8 sys.ps1

sys modlnn ps1 nitelii, etkileimli kabuktaki >>> iaretini tutar:


>>> sys.ps1

'>>> '

Eer isterseniz bu iareti deitirebilirsiniz:


>>> sys.ps1 = '+++ '

Bu komutu verdikten sonra >>> iaretinin +++ olarak deitiini greceksiniz.

48.2.9 sys.ps2

Etkileimli kabukta Python bizden girdiimiz kodlarn devamn beklediini gstermek iin ...
iaretini kullanr:
>>> a = 5
>>> if a == 5:
...

sys modlnn ps2 nitelii, ite etkileimli kabuktaki devam satrlarnda grdmz bu ...
iaretini tutar:
>>> sys.ps2

'... '

Eer isterseniz bu iareti deitirebilirsiniz:


>>> sys.ps1 = '--- '

Bu komutu verdikten sonra ... iaretinin olarak deitiini greceksiniz.

48.2.10 sys.version

sys modlnn version nitelii kullandnz Python srmne ilikin ayrntl bilgi verir:
>>> sys.version

`3.5.1 (default, 20.04.2016, 12:24:55)


[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux'

870 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

48.2.11 sys.version_info

sys modlnn version_info nitelii de kullandnz Python srmne ilikin bilgi verir:
>>> sys.version_info

sys.version_info(major=|major3|, minor=|minor3|, micro=|micro3|, releaselevel='final', serial


Bu nitelik kendi iinde birtakm baka nitelikler de barndrr:
>>> dir(sys.version_info)

['count', 'index', 'major', 'micro', 'minor',


'n_fields', 'n_sequence_fields', 'n_unnamed_fields',
'releaselevel', 'serial']

Bu niteliklere nasl ulaacanz biliyorsunuz:


>>> sys.version_info.major #byk srm numaras
>>> sys.version_info.minor #kk srm numaras
>>> sys.version_info.micro #minik srm numaras

48.2.12 sys.winver

sys modlnn winver nitelii Pythonn byk srm numarasyla kk srm numarasn
verir:
>>> sys.winver

3.5

Uyar: Bu nitelik yalnzca Windowsta alr; GNU/Linuxta tanml deildir.

48.2.13 sys.stdout

nceki derslerimizden de bildiiniz gibi stdout, standart kt konumu, yani programlarmzn


ktlarn standart olarak verdikleri konum anlamna geliyor.
Pythonda yazdmz programlar ktlarn standart olarak komut satrna verir. Yani mesela:
>>> print('merhaba zalim dnya')

komutunu verdiimizde, bu komutun kts komut ekrannda grnecektir.


Pythonda standart kt konumununun neresi olaca bilgisi sys modlnn stdout adl
nitelii iinde tutulur:
>>> import sys
>>> sys.stdout

<_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp1254'>

Standart kt konumuna yazmann en yaygn yolunun print() komutunu kullanmak


olduunu biliyoruz. Bu komut, standart kt konumu neresi ise oraya yazacaktr.

48.2. sys Modl 871


Python 3 iin Trke Klavuz, Srm 3

Standart kt konumuma yazmann baka bir yolu da dorudan sys.stdout niteliinin


write() metodunu kullanmaktr.
Dikkatlice bakn:
>>> sys.stdout.write('merhaba zalim dnya')

print() komutundan farkl olarak sys.stdout.write() fonksiyonu yle bir kt verir:


merhaba zalim dnya19

Burada, ktnn sonundaki 19 says merhaba zalim dnya karakter dizisinin uzunluunu
gsteriyor. sys.stdout.write() fonksiyonu etkileimli kabukta kullanldnda byle bir kt
verir. Ama eer bu kodlar bir dosyaya yazp altrrsanz sonraki 19 says grnmez.
Bu arada, her ne kadar print() ve sys.stdout.write() birbirine benzese de aralarnda
nemli farklar bulunur. rnein print() fonksiyonu parametre olarak her trl veri tipini
alabilir. Ancak sys.stdout.write() fonksiyonu parametre olarak yalnzca karakter dizisi
alabilir:
>>> sys.stdout.write(12)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: must be str, not int

Dolaysyla sys.stdout.write() fonksiyonuna parametre olarak vereceiniz deeri ncelikle


karakter dizisine evirmeniz gerekir:
>>> sys.stdout.write(str(12))

122

Not: Sondaki 2 saysnn 12 karakter dizisinin uzunluunu gsterdiini sylemitik. Bu


kodlar dosyaya yazp altrdnzda yalnzca 12 kts alrsnz.

print() ile sys.stdout.write() arasndaki nemli bir fark da, print() fonksiyonu
yazma ileminden sonra bir sonraki satra geerken, sys.stdout.write() fonksiyonunun
gememesidir.

Uyar: sys.stdout.write() fonksiyonu etkileimli kabuktan altrldnda ve dosyadan


altrldnda birbirinden farkl ktlar verir. O yzden aadaki rnekleri dosyaya yazp
altrmanz tavsiye ederim.

Mesela u rnee bakalm:


for i in 'istihza':
print(i)

Bu komut u kty verir:


i
s
t
i
h

872 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

z
a

Grdnz gibi, print() fonksiyonu, dngye giren her eyi yeni satra basyor.
Bir de sys.stdout.write() fonksiyonunun ne yaptna bakalm:
import sys

for i in 'istihza':
sys.stdout.write(i)

Bu komutlar ise u kty verir:


istihza

Grdnz gibi, sys.stdout.write() fonksiyonu elerin hepsini ayn satra bast. Eer
elerin ayr satrlara baslmasn istiyorsanz bunu aka belirtmelisiniz:
import sys

for i in 'istihza':
sys.stdout.write(i+'\n')

sys.stdout.write() fonksiyonunun otomatik olarak satr ba karakterini basmyor oluunu


kullanarak kronometre benzeri bir program yazabilirsiniz:
import sys

saya = 0

while True:
sys.stdout.write(str(saya)+'\r')
saya += 1

Burada, nceki derslerimizde rendiimiz ka dizilerinden \r yi kullanarak, her enin


ekrana baslmasnn ardndan satrn en bana dnlmesini saladk. Bylece eler yan
yana deil de birbirlerinin stne baslm oldu.
Bu arada, eer yukardaki kodlar herhangi bir kt vermeden bekliyorsa, kodlar u ekilde
yazn:
import sys

saya = 0

while True:
sys.stdout.write(str(saya)+'\r')
sys.stdout.flush()
saya += 1

Burada eklediimiz sys.stdout.flush() satr, Pythonn tamponda beklettii verileri ktya


gndermesini salar. Siz bu ush kavramn print() fonksiyonundan hatrlyor olmalsnz
(print() fonksiyonunun ush parametresi).
Hatrlarsanz, ush kavramnn yansra, print() fonksiyonunu ilerken rendiimiz bir
baka kavram da standart kt konumunun deitirilmesi idi. print() fonksiyonuna
verdiimiz le parametresi yardmyla programlarmzn standart olarak kt verdii konumu
deitirebiliyorduk:

48.2. sys Modl 873


Python 3 iin Trke Klavuz, Srm 3

f = open('ktlar.txt', 'w')
print('merhaba zalim dnya', file=f)

Burada ktlar.txt adl bir dosya oluturduk ve bunu print() fonksiyonunun le


parametresine atayarak, ktlar komut satr yerine ktlar.txt adl dosyaya gnderdik.
Ayn ilemi sys.stdout araclyla da yapabileceimizi biliyorsunuz:
import sys

f = open('ktlar.txt', 'w'):
sys.stdout = f
sys.stdout.write('merhaba zalim dnya')

Geri bu sizin bilmediiniz bir ey deil. Zira siz bunu print() Fonksiyonu konusunu ilerken
de grmtnz...

48.2.14 sys.stderr

nceki blmde grdmz u kodlar tekrar nmze alalm:


import sys

f = open('ktlar.txt', 'w')
sys.stdout = f
sys.stdout.write('merhaba zalim dnya')

Bu kodlar, bildiiniz gibi, kt olarak verilmek istenen deerlerin ktlar.txt adl bir dosyaya
ynlendirilmesini salyor. Ancak kodlarmz bu ekilde yazdmzda sadece normal deerler
ynlendirilecektir. Mesela alma esnasnda ortaya kan hatalar yine komut ekranna
baslmaya devam edecektir:
import sys

f = open('ktlar.txt', 'w')
sys.stdout = f
sys.stdout.write(1/0)

Bu kodlar altrdnzda, standart kt konumu ynlendirilmi olmasna ramen, hata


mesaj komut satrna baslacaktr:
Traceback (most recent call last):
File "deneme.py", line 5, in <module>
sys.stdout.write(1/0)
ZeroDivisionError: division by zero

nk Pythonda hata mesajlarnn ntanml olarak basld yer komut satrdr. Nasl
ktlarn standart olarak basld yeri teknik olarak standart kt konumu (Standard Output
- stdout ) olarak adlandryorsak, hatalarn standart olarak basld yeri de teknik olarak
standart hata konumu (Standard Error - stderr ) olarak adlandryoruz.
Tpk stdout u maniple edebildiimiz gibi, stderr i de maniple edebiliriz:
import sys

f =open('hatalar.txt', 'w')

874 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

sys.stderr = f
sys.stderr.write(1/0)

Bu durumda, programmzn ileyii srasnda ortaya kan hatalar hatalar.txt adl bir dosyaya
ynlendirilecektir.
Bu bilgiyi kullanarak yle bir kod da yazabiliriz:
import sys

ktlar = open('ktlar.txt', 'w')


hatalar = open('hatalar.txt', 'w')
sys.stdout = ktlar
sys.stderr = hatalar

print('normal kt')
print('hata mesaj: ', 1/0)

Bu kodlar altrdnzda, hata mesaj retmeden baaryla tamamlanan ktlarn ktlar.txt


adl dosyaya, hata mesajlarnn ise hatalar.txt adl dosyaya ynlendirildiini greceksiniz.

48.2.15 sys.stdin

Pythonda adet standart konum bulunur:


1. Standart kt konumu - stdout
2. Standart hata konumu - stderr
3. Standart girdi konumu - stdin
lk ikisini zaten grmtk. ncsn de imdi ele alacaz.
Bildiiniz gibi Pythonda kullancdan veri almak iin input() fonksiyonunu kullanyoruz:
say = input('Ltfen bir say girin: ')

Bu fonksiyonun grevi, standart girdi konumuna girilen verileri okumaktr. Pythondaki


standart girdi konumu (genellikle) komut satr olduu iin, input() fonksiyonu verileri komut
satrndan okur.
Pythonda standart girdi konumunu tutan deiken sys.stdin dir. Dolaysyla eer isterseniz,
verileri kullancdan input() fonksiyonu yerine dorudan sys.stdin nitelii araclyla da
alabilirsiniz:
>>> import sys
>>> sys.stdin.read()

Bu komutlar verdiinizde, komut satr sizden veri almaya hazr hale gelir. Bu ekilde
istediiniz kadar veriyi komut satrna girebilirsiniz. Veri giriini durdurmak istediinizde
ise Windowsta CTRL+C, GNU/Linuxta ise CTRL+D tularna basmanz gerekir. Bu ekilde
komut satrn terkettiinizde, girmi olduunuz deerler bir karakter dizisi olarak ekrana
baslacaktr.
sys.stdin nitelii, bize veri okumak iin farkl fonksiyon sunar:
1. sys.stdin.read()

48.2. sys Modl 875


Python 3 iin Trke Klavuz, Srm 3

2. sys.stdin.readline()
3. sys.stdin.readlines()
read() fonksiyonu birden fazla satr ieren verilerin girilmesine msaade eder ve kt olarak
bir karakter dizisi verir:
>>> sys.stdin.read()
(Girdi)
Frat
zgl
Adana
(kt)
'Frat\nzgl\nAdana\n'

readline() fonksiyonu tek bir satr ieren verilerin girilmesine msaade eder ve kt olarak
bir karakter dizisi verir:
>>> sys.stdin.readline()
(Girdi)
Frat
(kt)
'Frat\n'

readlines() fonksiyonu birden fazla satr ieren verilerin girilmesine msaade eder ve kt
olarak bir liste verir:
>>> sys.stdin.readlines()
(Girdi)
Frat
zgl
Adana
(kt)
['Frat\n', 'zgl\n', 'Adana\n']

Gelin isterseniz sys.stdin niteliinin nasl kullanlabileceine ilikin birka rnek verelim:
import sys

with open('kaytlar.txt', 'w') as kaytlar:


while True:
satrlar = sys.stdin.readline()
if satrlar.strip() == ':q':
break
else:
kaytlar.write(satrlar)

Burada kaytlar.txt adl bir dosya oluturduk ncelikle. Daha sonra da readline() fonksiyonu
araclyla kullancdan aldmz btn verileri bu dosyaya yazdk. Kullancnn programdan
kabilmesini salamak iin de :q tu kombinasyonunu ayarladk. Bylece komut satrndan
alan basit bir metin dzenleyici yazm olduk!
Tpk sys.stdout ve sys.stderr konumlarn deitirdiimiz gibi, sys.stdin konumunu da
deitirebiliriz. Bylece verileri komut satr araclyla deil, mesela bir dosya araclyla
alabiliriz.
Aadaki rnei dikkatlice inceleyin:

876 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

import sys

f = open('oku.txt')

sys.stdin = f

while True:
satrlar = sys.stdin.readline()
if satrlar.strip() == ':q':
break
else:
sys.stdout.write(satrlar)

Bu kodlar yazdktan sonra, bu kodlarn bulunduu dizinde oku.txt adl bir dosya oluturun.
Ardndan programnz altrn. Programnz u anda sizden veri girmenizi bekliyor. Verileri
oku.txt adl dosyaya gireceksiniz.
oku.txt adl dosyay ap bir eyler yazn. Veri girerken dosyay her kaydediinizde dosya
iindeki verilerin komut satrna dtn greceksiniz. Veri giriini tamamladktan sonra
dosyann en son satrna :q yazp dosyay kaydettiiniz anda da programnz kapanacaktr.

48.3 random Modl

Eer yazdnz programlarda, belirli bir aralkta rastgele saylarn retilmesine ihtiya
duyarsanz Pythonn standart ktphanesinde bulunan random adl bir modl
kullanabilirsiniz.
Tpk teki modllerde olduu gibi, random modl de birtakm faydal nitelik ve fonksiyonlar
barndrr. Biz bu blmde, bu nitelik ve fonksiyonlar arasnda en sk kullanlanlar
inceleyeceiz.
Elbette bu modl kullanabilmek iin ncelikle modlmz ie aktarmamz gerekiyor:
import random

Bu ilemin ardndan, bu modln bize sunduu btn ilevlerden yararlanabiliriz.

48.3.1 random()

random modlnn random() adl fonksiyonunu kullanarak, 0.0 ile 1.0 arasnda rastgele bir
kayan noktal say retebilirsiniz:
>>> random.random()

0.8064301704207291

random() fonksiyonu, kendisini her altrnzda farkl bir kayan noktal say retecektir:
>>> random.random()

0.6825988062501599

retilen saylarn 0 ile 1 arasnda olduunu zellikle dikkatinizi ekmek isterim.

48.3. random Modl 877


Python 3 iin Trke Klavuz, Srm 3

Mesela bu fonksiyonu kullanarak, 0 ile 1 aras 10 tane say retelim. Bu saylar gsterirken
de noktadan sonra yalnzca drt basamak grntlenmesine izin verelim:
>>> for i in range(10):
... print("{:.4f}".format(random.random()))
...
0.3094
0.5277
0.1588
0.2832
0.8742
0.9989
0.6847
0.5672
0.5529
0.9717

48.3.2 uniform()

Biraz nce grdmz random() fonksiyonu, dikkat ederseniz herhangi bir parametre
almyordu. nk bu fonksiyonun tek grevi 0 ile 1 aras saylar retmektir. Peki ya biz
reteceimiz saylarn farkl bir aralkta olmasn istersek ne yapacaz?
te, belirli bir aralkta kayan noktal saylar retmek istediimizde, random() yerine uniform()
adl bir fonksiyon kullanacaz. Dikkatlice inceleyim:
>>> random.uniform(0.5, 1.5)

Bu kod, her altrlnda 0.5 ile 1.5 aras rastgele bir kayan noktal say retecektir:
>>> random.uniform(0.5, 1.5)

0.9624863371746406

>>> random.uniform(0.5, 1.5)

0.900446344810926

48.3.3 randint()

imdiye kadar rendiimiz random() ve uniform() fonksiyonlar bize yalnzca kayan noktal
saylar retme imkan veriyordu. Ancak elbette biz kimi durumlarda kayan noktal saylar
yerine tam saylar retmek de isteyebiliriz. te byle bir durumda, random modlnn
randint() adl baka bir fonksiyonunu kullanabiliriz.
Mesela 45 ile 500 arasnda rastgele bir say retmek isterseniz, randint() fonksiyonunu u
ekilde kullanabilirsiniz:
>>> random.randint(45, 500)

Bu fonksiyon, her altrlnda 45 ile 500 arasnda rastgele bir tam say retecektir.

878 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

48.3.4 choice()

random modlnn choice() adl fonksiyonunu kullanarak, dizi nitelii tayan veri
tiplerinden rastgele eler seebiliriz. Bu tanm biraz anlalmaz gelmi olabilir. O yzden
bunu bir rnekle aklayalm.
Diyelim ki elimizde yle bir liste var:
>>> liste = ['ali', 'veli', 'ahmet',
... 'mehmet', 'celal', 'selin', 'nihat']

Bildiiniz gibi, listeler, dizi nitelii tayan veri tipleridir. Dolaysyla choice() fonksiyonunu
kullanarak bu diziden rastgele bir e seebiliriz:
>>> liste = ['ali', 'veli', 'ahmet', 'mehmet', 'celal', 'selin', 'nihat']

>>> random.choice(liste)

'ali'

>>> random.choice(liste)

'mehmet'

>>> random.choice(liste)

'selin'

Tpk bu rnekte olduu gibi, karakter dizileri de dizi nitelii tayan bir veri tipi olduu iin,
choice() fonksiyonuna cevap verir:
>>> kardiz = 'istihza'
>>> random.choice(kardiz)

'i'

Peki acaba bu i har karakter dizisinin bandaki i har mi, yoksa ortasndaki i har mi?
Sizce bunu nasl anlayabiliriz?

48.3.5 shue()

shuffle() fonksiyonunu kullanarak, dizi nitelii tayan veri tiplerindeki eleri


kartrabilirsiniz (yani elerin srasn kark bir hale getirebilirsiniz). Mesela:
>>> l = list(range(10))

10 eli bir listemiz var. Bu listedeki eler 0 dan 10 a kadar dzgn bir ekilde sralanm:
>>> l

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

imdi biz shuffle() fonksiyonunu kullanarak eleri kartracaz:


>>> random.shuffle(l)
>>> l

48.3. random Modl 879


Python 3 iin Trke Klavuz, Srm 3

[8, 0, 7, 9, 1, 4, 6, 5, 3, 2]

Burada dikkat etmemiz gereken nemli nokta, shuffle() fonksiyonunun, zgn listenin
kendisi zerinde deiiklik yapyor oluudur. Yani liste zerinde shuffle() metodunu
uyguladktan sonra artk zgn listeyi kaybediyoruz. Dolaysyla elimizde artk eleri 0dan
10a kadar dzgn bir ekilde sralanm liste yok. Onun yerine, eleri kartrlm bir liste
var elimizde.
Liste zerine shuffle() fonksiyonunu her uygulaynzda zgn listenin eleri bir daha
kartrlacaktr.
Peki size bir soru...
Elinizde yle bir liste var:
arkadalar = [ali, veli, mehmet, ahmet, serkan, selin]
Grevimiz bu listenin elerini kartrmak. Ama biz ayn zamanda zgn arkadalar
listesindeki e sralamasn da kaybetmek istemiyoruz. Bunu nasl baarabiliriz?

48.3.6 randrange()

randrange() fonksiyonu, yukarda rendiimiz randint() fonksiyonu ile ayn ii yapar. Yani
her iki fonksiyon da, belli bir aralkta rastgele tamsaylar retir. Ancak aralarnda iki ufak fark
bulunur.
lk nce birincisine bakalm...
Dikkatlice inceleyin:
>>> random.randrage(10)

5
Grdnz gibi, randrange() fonksiyonunu tek parametre ile kullanabiliyoruz. Yukardaki
komutu eer randint() ile yazmak istersek unu yapmamz gerekir:
>>> random.randint(0, 10)

randrange() fonksiyonundan farkl olarak, randint() fonksiyonunu iki parametre ile


kullanmamz gerekir. Eer bu fonksiyona tek parametre verirsek hata alrz:
>>> random.randint(10)

Traceback (most recent call last):


File "<stdin>", line 1, in <module>
TypeError: randint() missing 1 required positional argument: 'b'

Elbette, eer istersek randrange() fonksiyonunu da ift parametre ile kullanarak, farkl bir
say aral belirtme imkanna sahibiz:
>>> random.randrange(10, 500)

Bu komut, 10 ile 500 aras rastgele tam saylar retecektir. Ayrca bu komut ununla da
edeerdir:

880 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

>>> random.randint(10, 500)

Bu iki fonksiyon arasndaki ikinci fark ise, rastgele say retilecek araln son deeridir. Bu
mulak ifadeyi bir rnekle anlalr hale getirmeye alalm:
>>> random.randrange(10, 20)

Bu komut, 10 ile 20 arasnda rastgele bir say retir. retilecek en dk say 10 iken, en
byk say ise 19 olacaktr. 20 says asla retilmez.
Bir de una bakalm:
>>> random.randint(10, 20)

Burada da yime 10 ile 20 arasnda rastgele bir say retilir. Tpk randrange() metodunda
olduu gibi, retilecek en dk say 10 dur. Ancak en byk say 20 olacaktr.
Bu iki fonksiyonu kullanrken bu farklla dikkat etmemiz gerekir. Aksi halde yazdmz
programlar hatal alabilir.
Peki size bir soru: Acaba randint() ile randrange() arasndaki bu fark nasl kantlarsnz?

48.3.7 sample()

Sample kelimesi numune anlamna gelir. te kelimenin bu anlamna paralel olarak


sample() fonksiyonu da, dizi nitelii tayan veri tiplerinden belli sayda numune
alnabilmesini salar. Baknz:
>>> liste = range(100)

100 eli bir liste oluturduk. imdi bu listeden 5 tane rastgele numune alalm:
>>> random.sample(liste, 5)

[56, 74, 2, 3, 80]

Grdnz gibi, sample() fonksiyonunun ilk parametresi numune alnacak diziyi, ikinci
parametresi ise bu diziden ka tane numune alnacan gsteriyor.

48.4 datetime Modl

Bu blmde, zaman, saat ve tarihlerle ilgili ilemler yapmamz salayan nemli bir standart
ktphane modlnden sz edeceiz. Bu modln ad datetime.
datetime modl; zaman, saat ve tarihlerle ilgili ilemler yapabilmemiz iin bize eitli
fonksiyon ve nitelikler sunan baz snardan oluur. Bu modl iinde temel olarak farkl
snf bulunur.

Not: Snf kavramna ok taklmayn. lerleyen derslerde snardan ayrntl olarak sz


edeceiz.

datetime modl iinde yer alan bu snf unlardr:

48.4. datetime Modl 881


Python 3 iin Trke Klavuz, Srm 3

1. date snf; tarihle ilgili ilemler yapabilmemizi salayan fonksiyon ve nitelikleri


barndrr.
2. time snf; zamanla/saatle ilgili ilemler yapabilmemizi salayan fonksiyon ve nitelikleri
barndrr.
3. datetime snf; date ve time snarnn birleiminden ve ilave birka nitelik ve
fonksiyondan oluur.
Buna gre, datetime adl snf hem date snfn hem de time snfn kapsad iin, datetime
modl ile ilem yapmak istediinizde, ounlukla yalnzca datetime snfn kullanarak btn
ilerinizi halledebilirsiniz.
Dolaysyla:
>>> from datetime import datetime

Komutunu vererek datetime modl iindeki datetime adl snf ie aktarmay tercih
edebilirsiniz.
Bakalm datetime modlnn datetime snf iinde neler varm:
>>> dir(datetime)

['__add__', '__class__', '__delattr__', '__dir__', '__doc__', '__eq__',


'__forma t__', '__ge__', '__getattribute__', '__gt__', '__hash__',
'__init__', '__le__', '__lt__', '__ne__', '__new__', '__radd__',
'__reduce__', '__reduce_ex__', '__rep r__', '__rsub__', '__setattr__',
'__sizeof__', '__str__', '__sub__', '__subclass hook__', 'astimezone',
'combine', 'ctime', 'date', 'day', 'dst', 'fromordinal', 'fromtimestamp',
'hour', 'isocalendar', 'isoformat', 'isoweekday', 'max', 'microsecond',
'min', 'minute', 'month', 'now', 'replace', 'resolution', 'second',
'strftime', 'strptime', 'time', 'timestamp', 'timetuple', 'timetz', 'today',
'toord inal', 'tzinfo', 'tzname', 'utcfromtimestamp', 'utcnow', 'utcoffset',
'utctimetuple', 'weekday', 'year']

Elbette, eer isterseniz dorudan datetime modln de ie aktarabilirsiniz:


>>> import datetime

Bu durumda, datetime modl iindeki datetime snfna erimek iin modl adn da
kullanmanz gerekir:
>>> dir(datetime.datetime)

te biz bu blmde, yukardaki komutun ktsnda grdmz nitelik ve fonksiyonlar


arasndan en nemli olanlarn inceleyeceiz.

48.4.1 now()

datetime modlnn iindeki datetime snfnn now() adl fonksiyonu, bize iindeki
bulunduumuz andaki tarih, saat ve zaman bilgilerini verir. datetime modln import
datetime eklinde ie aktardmz varsayarsak bunu u ekilde kullanyoruz:
>>> an = datetime.datetime.now()

Bu fonksiyon bize datetime.datetime adl zel bir snf nesnesi verir:

882 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

>>> an

datetime.datetime(2014, 12, 5, 9, 54, 53, 867108)

Bu zel snfn da kendine zg birtakm nitelikleri bulunur.


Mesela year adl nitelii kullanarak iinde bulunduumuz yl sorgulayabiliriz:
>>> an.year

2014

Ayn ekilde aadaki nitelikler de, iinde bulunduumuz ana ilikin eitli bilgiler verir:
>>> an.month #ay

12

>>> an.day #gn

>>> an.hour #saat

10

>>> an.minute #dakika

20

>>> an.second #saniye

33

>>> an.microsecond #mikrosaniye

337309

48.4.2 today()

Bu fonksiyon now() ile ayn ierie ve ileve sahiptir. today() fonksiyonunu now fonksiyonunu
kullandnz gibi kullanabilirsiniz:
>>> bugn = datetime.datetime.today()

>>> bugn.year

2014

>>> bugn.month

12

>>> bugn.minute

35

48.4. datetime Modl 883


Python 3 iin Trke Klavuz, Srm 3

>>> bugn.second

24

>>> bugn.microsecond

669774

48.4.3 ctime()

ctime() fonksiyonu, iinde bulunduumuz ana ilikin tarih ve zaman bilgilerini ieren
okunakl bir karakter dizisi verir. Bu fonksiyona, parametre olarak biraz nce
oluturduumuza benzer bir datetime.datetime snf vermemiz gerekir. Yani:
>>> an = datetime.datetime.now()
>>> tarih = datetime.datetime.ctime(an)
>>> tarih

'Fri Dec 5 10:30:35 2014'

Bu fonksiyon tarihleri ngilizce olarak gsterir. Yukardaki ktya gre tarih 5 Aralk Cuma
2014 saat 10:30:35.

48.4.4 strftime()

strftime() fonksiyonu, size tarih ve zaman bilgilerini ihtiyalarnz dorultusunda


biimlendirme imkan sunar.
Bu fonksiyon toplam iki parametre alr. lk parametre, tpk ctime() fonksiyonunda olduu
gibi, bir datetime.datetime snfdr. kinci parametre ise, tarih/zaman bilgisini ieren karakter
dizisini nasl biimlendirmek istediimizi gsteren bir biimlendiricidir. Yani:
>>> an = datetime.datetime.now()
>>> tarih = datetime.datetime.strftime(an, '%c')
>>> tarih

'Fri 05 Dec 2014 12:53:21 PM '

Burada ilk parametre olarak an deikeninin tuttuu datetime.datetime snfn, ikinci


parametre olarak ise %c adl biimlendiriciyi kullandk.
%c dnda baka tarih biimlendiricileri de bulunur:
%a hafta gnnn ksaltlm ad
%A hafta gnnn tam ad
%b ayn ksaltlm ad
%B ayn tam ad
%c tam tarih, saat ve zaman bilgisi
%d say deerli bir karakter dizisi olarak gn
%j belli bir tarihin, yln kanc gnne denk geldiini gsteren 1-366 aras bir say
%m say deerli bir karakter dizisi olarak ay

884 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

%U belli bir tarihin yln kanc haftasna geldiini gsteren 0-53 aras bir say
%y yln son iki rakam
%Y yln drt haneli tam hali
%x tam tarih bilgisi
%X tam saat bilgisi
Yukardaki biimlendiricilerle ilgili birka rnek verelim:
>>> datetime.datetime.strftime(an, '%Y') # Yl

'2014'

>>> datetime.datetime.strftime(an, %'X') # Saat

'12:26:32'

>>> datetime.datetime.strftime(an, '%d') # Gn

'05'

strftime() fonksiyonu ntanml olarak ngilizce kt verecektir:


>>> datetime.datetime.strftime(an, '%A')

'Friday'

>>> datetime.datetime.strftime(an, '%B')

'December'

Eer isterseniz, locale adl baka bir modl kullanarak, strftime() modlnn,
sisteminizdeki tanml dili kullanmasn salayabilirsiniz.
Bunun iin ncelikle locale modln ie aktaralm:
>>> import locale

Ardndan Pythonn kullanmasn istediimiz yerel/dil bilgisini, sistemdeki ntanml yerel/dil


olarak ayarlayalm:
>>> locale.setlocale(locale.LC_ALL, '')

'Turkish_Turkey.1254'

Bu kt bize sistemimizdeki tanml dilin/yerelin Trke olduunu sylyor. Bu komutu


verdikten sonra, artk strftime() fonksiyonu, ilgili dile/yerele uygun bir kt verecektir:
>>> datetime.datetime.strftime(an, '%B')

'Aralk'

>>> datetime.datetime.strftime(an, '%A')

'Cuma'

Eer isterseniz, dili kendiniz de seebilirsiniz. Mesela talyanca yapalm:

48.4. datetime Modl 885


Python 3 iin Trke Klavuz, Srm 3

>>> locale.setlocale(locale.LC_ALL, 'italian')

'Italian_Italy.1252'

>>> datetime.datetime.strftime(an, '%B')

'dicembre'

>>> datetime.datetime.strftime(an, '%A')

'venerd'

Ayrca bkz.:
Yerel dil adlar iin Windowsta http://msdn.microsoft.com/en-us/library/39cwe7zf%28vs.71%29.aspx
adresine bakabilirsiniz. GNU/Linuxta ise, desteklenen yerel/dil adlarn grmek iin sistem
komut satrnda locale - a komutunu verebilirsiniz.
Yukarda grdnz tarih biimlendiricileri kullanarak istediiniz karmaklktaki tarihleri
oluturabilirsiniz. Mesela:
>>> datetime.datetime.strftime(an, '%d %B %Y')

'05 Aralk 2014'

Veya:
>>> datetime.datetime.strftime(an, '%d.%m.%Y tarihinde bulualm.')

05.12.2014 tarihinde bulualm.


Grdnz gibi, strftime() fonksiyonu, tarihler zerinde istediimiz karakter dizisi
biimlendirme ilemini uygulayabilmemizi salyor.

48.4.5 strptime()

Diyelim ki elimizde, herhangi bir kaynaktan gelmi yle bir karakter dizisi var:
>>> t = '27 Mays 2014'

Amacmz, tarih bilgisi ieren bu karakter dizisini gn, ay ve yl elerine ayrmak. Bunun iin
basite yle bir kod yazabiliriz:
>>> gn, ay, yl = t.split()
>>> gn

'27'

>>> ay

'Mays'

>>> yl

'2014'

Peki eer elimizdeki karakter dizisi yle bir eyse ne yapacaz?

886 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

>>> t = '27 Mays 2014 saat 12:34:44'

Bunun iin de t deikeni zerine split() metodunu uyguladktan sonra saat kelimesini
listeden atmay tercih edebiliriz:
>>> gn, ay, yl, saat = [i for i in t.split() if 'saat' not in i]
>>> gn

'27'

>>> ay

'Mays'

>>> yl

'2014'

>>> saat

'12:34:44'

Yukardaki yntemler, tarih bilgisi ieren karakter dizilerini ayklamak iin geerli ve uygun
olsa da epey meakkatlidir. stelik bu ekilde aykladmz verilerin kullanm alan da olduka
kstl olacaktr. Mesela bu verileri datetime.datetime trnde verileri bekleyen uygulamalar
iinde kullanamayz.
te byle bir durumda strptime() adl fonksiyon devreye girerek, tarih/zaman bilgisi ieren
herhangi bir karakter dizisini datetime.datetime trnde bir nesneye dntrebilmemiz iin
bize bir yol sunar.
imdi dikkatlice bakn:
Elimizdeki karakter dizisi u:
>>> t = '27 Mays 2014 saat 12:34:44'

imdi bu karakter dizisini strptime() fonksiyonunu kullanarak ayklyoruz:


>>> z = datetime.datetime.strptime(t, '%d %B %Y saat %H:%M:%S')

datetime.datetime(2014, 5, 27, 0, 34, 44)

Grdnz gibi, strptime() fonksiyonu iki parametre alyor. lk parametre, ayklamak


istediimiz, tarih-zaman bilgisi ieren karakter dizisi. kinci parametre ise, bu karakter
dizisinin yapsn temsil eden tarih biimlendiricilerden oluan baka bir karakter dizisi. Bu
karakter dizisi, 27 Mays 2014 saat 12:34:44 adl karakter dizisinin iindeki, tarih ve saati
gsteren ksmlarn her biri iin bir biimlendirici ieriyor:
27 ==> %d
Mays ==> %B
2014 ==> %Y
12 ==> %H
34 ==> %M
44 ==> %S

Bu ekilde bir datetime.datetime nesnesi oluturduktan sonra, artk bu nesnenin elerine,


herhangi bir datetime.datetime nesnesi gibi eriebiliriz:

48.4. datetime Modl 887


Python 3 iin Trke Klavuz, Srm 3

>>> z.month #ay

>>> z.day #gn

27

>>> z.year #yl

2014

>>> z.hour #saat

12

>>> z.minute #dakika

34

>>> z.second #saniye

44

48.4.6 fromtimestamp()

Hatrlarsanz os modln anlatrken stat() adl bir fonksiyondan sz etmitik. Bu


fonksiyonun, dosyalar hakknda bilgi almamz saladn biliyorsunuz:
>>> os.stat('dosya_ad')

Mesela bir dosyann son deitirilme tarihi renmek iin yle bir kod kullanyorduk:
>>> os.stat('dosya_ad').st_mtime

st_mtime nitelii bize una benzer bir kt veriyor:


1417784445.8881965

Bu, iinde ayrntl tarih bilgisi barndran bir zaman damgasdr (timestamp). te bu zaman
damgasn anlaml bir tarih bilgisine dntrebilmek iin datetime modlnn datetime
snf iindeki fromtimestamp() adl fonksiyondan yararlanacaz:
>>> zaman_damgas = os.stat('dosya_ad').st_mtime
>>> tarih = datetime.datetime.fromtimestamp(zaman_damgas)
>>> tarih

datetime.datetime(2014, 12, 5, 15, 0, 45, 888196)

Bu ekilde bir datetime.datetime nesnesi elde ettikten sonra artk bu nesneyi istediimiz
ekilde maniple edebiliriz. Mesela:
>>> datetime.datetime.strftime(tarih, '%c')

'12/05/14 15:00:45'

888 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

Demek ki 1417784445.8881965 zaman damgas, iinde 12/05/14 15:00:45 tarihini


barndryormu.

48.4.7 timestamp()

Eer datetime.datetime nesnelerinden bir zaman damgas retmek isterseniz timestamp()


fonksiyonunu kullanabilirsiniz:
>>> tarih = datetime.datetime.now()
>>> zaman_damgas = datetime.datetime.timestamp(tarih)
>>> zaman_damgas

1417790594.558625

Eer daha sonra bu zaman damgasn anlaml bir tarihe dntrmeniz gerekirse
fromtimestamp() fonksiyonunu kullanabileceinizi biliyorsunuz:
>>> tarih = datetime.datetime.fromtimestamp(zaman_damgas)

48.4.8 Tarihlerle lgili Aritmetik lemler

datetime modln kullanarak, tarihler arasnda karma-toplama gibi eitli aritmetik


ilemler de yapabilirsiniz. Bu blmde bu ilemleri nasl yapacamz anlatacaz.

Belirli Bir Tarihi Kaydetmek

Pythonda datetime modln kullanarak bugnn tarihini bir datetime.datetime snf


olarak nasl alabileceimizi biliyoruz:
>>> datetime.datetime.now()

veya:
>>> datetime.datetime.today()

Peki biz mesela bugnn deil de, gemiteki veya gelecekteki belirli bir tarihi almak istersek
ne yapacaz?
Bu i iinde yine datetime modlnn datetime adl snfndan yararlanacaz.
Diyelim ki 16 ubat 2016, saat 13:45:32yi bir datetime snf olarak kaydetmek istiyoruz.
Bunun iin yle bir kod kullanacaz:
>>> tarih = datetime.datetime(2016, 2, 16, 13, 45, 32)

Grdnz gibi, belirli bir tarihi bir datetime.datetime nesnesi olarak kaydetmek
istediimizde datetime snfna parametre olarak srasyla ilgili tarihin yl, ay, gn, saat, dakika
ve saniye ksmlarn giriyoruz.
Bu arada, eer isterseniz bu tarih iin bir mikrosaniye de belirtebilirsiniz:
>>> tarih = datetime.datetime(2016, 2, 16, 13, 45, 32, 5)

48.4. datetime Modl 889


Python 3 iin Trke Klavuz, Srm 3

Bylece belirli bir tarihi bir datetime snf olarak kaydetmi olduk. Bu snf,
datetime.datetime nesnelerinin btn zelliklerine sahiptir:
>>> tarih.year #yl

2016

>>> tarih.day #gn

16

>>> tarih.month #ay

ki Tarih Arasndaki Fark Bulmak

Size yle bir soru sormama izin verin: Diyelim ki bugnn tarihi 9 Aralk 2014. Doum
tarihimizin 27 Mays olduunu varsayarsak, acaba 2015 ylndaki doum gnmze ka gn
kaldn nasl bulabiliriz?
Bunun iin ncelikle bugnn tarihini bir datetime.datetime nesnesi olarak alalm:
>>> bugn = datetime.datetime.today()

imdi de doumgnmze denk gelen tarihi bir datetime.datetime nesnesi olarak


kaydedelim:
>>> doumgn = datetime.datetime(2015, 5, 27)

imdi de bu iki tarih arasndaki fark bulalm:


>>> fark = doumgn - bugn
>>> fark

datetime.timedelta(168, 34694, 719236)

Buradan elde ettiimiz ey bir timedelta nesnesi. Bu nesne, tarihler arasndaki fark gn,
saniye ve mikrosaniye olarak tutan zel bir veri tipidir. Yukardaki ktdan anladmza
gre, 27 Mays 2015 tarihi ile 9 Aralk 2014 tarihi arasnda 168 gn, 34694 saniye ve 719236
mikrosaniye varm...
Yukardaki timedelta nesnesinin niteliklerine u ekilde ulaabilirsiniz:
>>> fark.days #gn

168

>>> fark.seconds #saniye

34694

>>> fark.microseconds #mikrosaniye

719236

890 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

leri Bir Tarihi Bulmak

Diyelim ki 200 gn sonra hangi tarihte olacamz bulmak istiyoruz. Tpk bir nceki balkta
tarttmz gibi, bu isteimizi yerine getirmek iin de timedelta nesnesinden yararlanacaz.
nce bugnn tarihini bulalm:
>>> bugn = datetime.datetime.today()

imdi 200 gnlk fark bir timedelta nesnesi olarak kaydedelim:


>>> fark = datetime.timedelta(days=200)

Burada datetime modlnn timedelta() fonksiyonunun days adl parametresini 200


deeri ile ardmza dikkat edin. days adl parametrenin dnda, timedelta() fonksiyonu
u parametrelere de sahiptir:
>>> fark = datetime.timedelta(days=200, seconds=40, microseconds=30)

Grdnz gibi, gn dnda saniye (seconds) ve mikrosaniye (microseconds) ayarlarn da


yapabiliyoruz. Yukardaki belirlediimiz timedelta nesnesi dorultusunda 200 gn, 40 saniye
ve 30 mikrosaniye gelecee gidelim:
>>> gelecek = bugn + fark

>>> gelecek

datetime.datetime(2015, 6, 27, 14, 47, 32, 826771)

Bu tarihi anlaml bir karakter dizisine dntrelim:


>>> gelecek.strftime('%c')

'27.06.2015 14:47:32'

Demek ki bugnden 200 gn, 40 saniye ve 30 mikrosaniye sonras 27 Haziran 2015, saat
14:47:32ye denk geliyormu...

Gemi Bir Tarihi Bulmak

Gemi bir tarihi bulmak da, tahmin edebileceiniz gibi, ileri bir tarihi bulmaya ok benzer.
Basit bir rnek verelim:
>>> bugn = datetime.datetime.today()

Bugnden 200 gn geriye gidelim:


>>> fark = datetime.timedelta(days=200)
>>> gemi = bugn - fark
>>> gemi

datetime.datetime(2014, 5, 23, 15, 5, 11, 487643)

>>> gemi.strftime('%c')

'23.05.2014 15:05:11'

Demek ki 200 gn ncesi 23 Mays 2014 imi...

48.4. datetime Modl 891


Python 3 iin Trke Klavuz, Srm 3

48.5 time Modl

time modl, bir nceki blmde rendiimiz datetime modlne benzer. Hatta bu iki
modln ayn ii yapan ortak nitelik ve fonksiyonlar vardr. Ancak datetime modlnden
farkl olarak time modln daha ok saatle ilgili ilemleri yapmak iin kullanacaz.
Her zaman olduu gibi, bu modl kullanabilmek iin de ncelikle modl ie aktarmamz
gerekiyor:
>>> import time

Modl ie aktardmza gre, artk modln ieriinden yararlanabiliriz.

48.5.1 gmtime()

Pythonda (ve baka programlama dillerinde), zaman-tarih hesaplamalarnda zamann


balangc (EPOCH) diye bir kavram bulunur. Zamann balangc, bir iletim sisteminin, tarih
hesaplamalarnda sfr noktas olarak ald tarihtir. Kullandnz iletim sisteminin hangi
tarihi zamann balangc olarak kabul ettiini bulmak iin u komutu verebilirsiniz:
>>> time.gmtime(0)

Buradan u kty alyoruz:


time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0,
tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)

Bu, struct_time adl zel bir veri tipidir. Bu veri tipi iindeki niteliklere u ekilde
ulaabilirsiniz:
>>> epoch = time.gmtime(0)
>>> epoch.tm_year #yl

1970

>>> epoch.tm_mon #ay

>>> epoch.tm_mday #gn

Demek ki zamann balangc 1 Ocak 1970 tarihi olarak alnyormu... te bilgisayarmz,


iinde bulunduumuz zaman ve saati, bu balang zamanndan bu yana geen saniyeleri
hesaplayarak bulur.
gmtime() fonksiyonunu parametresiz olarak kullandnzda, o anda iinde bulunduunuz
tarih ve saat bilgisini elde edersiniz.
time.struct_time(tm_year=2014, tm_mon=12, tm_mday=10, tm_hour=12,
tm_min=5, tm_sec=33, tm_wday=2, tm_yday=344, tm_isdst=0)
Ancak bu kt, zellikle saat ksm konusunda her zaman doru olmayabilir. ktnn birka
saat saptn grebilirsiniz.

892 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

48.5.2 time()

time() fonksiyonu, zamann balangcndan, o anda iinde bulunduumuz ana kadar geen
toplam saniye miktarn verir:
>>> time.time()

1418213083.726988

Elde ettiiniz bu deeri, gmtime() fonksiyonunu kullanarak anlaml bir tarih deerine
dntrebilirsiniz:
>>> time.gmtime(time.time())

time.struct_time(tm_year=2014, tm_mon=12, tm_mday=10,


tm_hour=12, tm_min=9, tm_sec=19, tm_wday=2, tm_yday=344,
tm_isdst=0)

Ancak bu kt da zellikle saat ksmnda sapmalara urayabilir.

48.5.3 localtime()

Tpk gmtime() fonksiyonundan olduu gibi, anlk tarih ve zaman bilgisini bir struct_time
nesnesi olarak almak iin localtime() fonksiyonunu da kullanabiliriz. Bu fonksiyon bize yerel
saati doru bir ekilde verecektir:
>>> time.localtime()

time.struct_time(tm_year=2014, tm_mon=12, tm_mday=10,


tm_hour=14, tm_min=24, tm_sec=21, tm_wday=2, tm_yday=344, tm_isdst=0)

Bu nesnenin iindeki yl, ay ve gn gibi bilgilere tek tek nasl eriebileceinizi biliyorsunuz.

48.5.4 asctime()

Bata da sylediimiz gibi, time modl, datetime modlne benzer. Bunlarn ayn ii gren
eitli fonksiyonlar vardr. Bir rnek verelim.
Hatrlarsanz, bugnn tarihini bir karakter dizisi olarak almak iin datetime modln u
ekilde kullanabiliyorduk:
>>> import datetime
>>> an = datetime.datetime.now()
>>> datetime.datetime.ctime(an)

'Wed Dec 10 13:56:22 2014'

Yukardaki ilemi time modlnn asctime() fonksiyonunu kullanarak da yapabiliriz:


>>> import time
>>> time.asctime()

'Wed Dec 10 13:58:31 2014'

asctime() fonksiyonu tercihe bal bir parametre de alabilir. sterseniz bu fonksiyona 9 eli
bir demet veya bir struct_time nesnesi verebilirsiniz.

48.5. time Modl 893


Python 3 iin Trke Klavuz, Srm 3

Yukarda, gmtime() fonksiyonunun bir struct_time nesnesi rettiini renmitik. Dolaysyla


bu nesneyi asctime() fonksiyonuna parametre olarak verebilirsiniz:
>>> time.asctime(time.gmtime())

'Wed Dec 10 12:14:29 2014'

>>> time.asctime(time.gmtime(0))

'Thu Jan 1 00:00:00 1970'

Ayn ekilde localtime() fonksiyonunun da bize bir struct_time() nesnesi verdiini biliyoruz.
Dolaysyla bu fonksiyon da asctime() fonksiyonuna parametre olarak verilebilir:
>>> time.asctime(time.localtime())

'Wed Dec 10 14:28:05 2014'

Veya, srasyla yl, ay, gn, saat, dakika, saniye, haftann gn, yln gn, gn ndan
yararlanma durumu deerini ieren bir demet de oluturabilir, daha sonra bunu asctime()
fonksiyonuna parametre olarak verebilirsiniz:
>>> demet = (2014, 5, 27, 13, 45, 23, 0, 0, 0)
>>> time.asctime(demet)

Ancak zellikle haftann gn, yln gn ve gn ndan yararlanma durumu bilgilerini


doru tahmin etmek zor olduu iin, bu demeti elle oluturmanz pek tavsiye etmem.

48.5.5 strftime()

Hatrlarsanz datetime modln anlatrken, datetime snf iindeki strftime() adl bir
fonksiyondan sz etmitik. Bu fonksiyonun, tarih-saat bilgisi ieren karakter dizilerini
maniple edebilmemizi saladn biliyorsunuz.
Bu fonksiyonu yle kullanyorduk:
>>> import datetime
>>> an = datetime.datetime.now()
>>> datetime.datetime.strftime(an, '%c')

'10.12.2014 14:57:48'

te yukardaki ilemi, time modlnn strftime() fonksiyonunu kullanarak biraz daha


pratik bir ekilde gerekletirebiliriz:
>>> import time
>>> time.strftime('%c')

'10.12.2014 14:58:02'

datetime modln incelerken grdmz tarih biimlendiricileri time modl iin de


geerlidir:
%a hafta gnnn ksaltlm ad
%A hafta gnnn tam ad
%b ayn ksaltlm ad

894 Blm 48. nemli Standart Ktphane Modlleri


Python 3 iin Trke Klavuz, Srm 3

%B ayn tam ad
%c tam tarih, saat ve zaman bilgisi
%d say deerli bir karakter dizisi olarak gn
%j belli bir tarihin, yln kanc gnne denk geldiini gsteren 1-366 aras bir say
%m say deerli bir karakter dizisi olarak ay
%U belli bir tarihin yln kanc haftasna geldiini gsteren 0-53 aras bir say
%y yln son iki rakam
%Y yln drt haneli tam hali
%x tam tarih bilgisi
%X tam saat bilgisi

Uyar: Sistem yerelinin locale modl araclyla Trkeye ayarlanm olmas gerektiini
unutmuyoruz:

import locale
locale.setlocale(locale.LC_ALL, 'turkish')

48.5.6 strptime()

time modlnn strptime() fonksiyonunun yapt i, datetime modlnn datetime


snfnn strptime() fonksiyonunun yapt ie ok benzer:
>>> import datetime
>>> t = '27 Mays 1980'
>>> tarih = datetime.datetime.strptime(t, '%d %B %Y')
>>> tarih

datetime.datetime(1980, 5, 27, 0, 0)

Burada 27 Mays 1980 tarihini, strptime() fonksiyonu yardmyla bir datetime nesnesine
dntrdk. Ayn eyi u ekilde de yapabiliriz:
>>> import time
>>> t = '27 Mays 1980'
>>> tarih = time.strptime(t, '%d %B %Y')
>>> tarih

time.struct_time(tm_year=1980, tm_mon=5, tm_mday=27,


tm_hour=0, tm_min=0, tm_sec=0, tm_wday=1, tm_yday=148,
tm_isdst=-1)

Grdnz gibi, time modlnn strptime() fonksiyonu datetime modl iindeki


strptime() fonksiyonunun aksine bir struct_time nesnesi veriyor.

48.5.7 sleep()

sleep() fonksiyonu, time modlnn en sk kullanlan aralarndan bir tanesidir. Bu


fonksiyonu kullanarak kodlarmzn ileyiini belli srelerle kesintiye uratabiliriz.

48.5. time Modl 895


Python 3 iin Trke Klavuz, Srm 3

Basit bir rnek verelim:


>>> for i in range(10):
... time.sleep(1)
... print(i)

Bu kodlar altrdnzda, 0dan 10a kadar olan saylar ekrana baslrken her bir say
arasna 1er saniyelik duraklamalar eklendiini greceksiniz. Eer arzu ederseniz bu sreyi
1 saniyenin de altna ekebilirsiniz:
>>> for i in range(10):
... time.sleep(0.5)
... print(i)

Grdnz gibi, sleep() fonksiyonuna 0.5 parametresini vererek, duraklama sresinin 500
milisaniye olmasn saladk.
time modlnn sleep() fonksiyonunu, kodlarnz arasna duraklama eklemek istediiniz her
durumda kullanabilirsiniz.

896 Blm 48. nemli Standart Ktphane Modlleri


BLM 49

Katkda Bulunanlar

Yeterince gzbebeinin olduu yerde tm hatalar sdadr.


Linus Torvalds
Bu sayfada, Python3 belgelerine herhangi bir ekilde katkda bulunanlarn isimleri bir liste
halinde yer alyor.
Ltfen siz de belgelerde grdnz hatalar ozgulrat@gmail.com adresine iletmekten
ekinmeyin. Katklarnz, bu belgelerin hem daha az hata iermesini hem de daha ok kiiye
ulamasn salayacaktr.

897
Python 3 iin Trke Klavuz, Srm 3

Barbaros Akkurt
ebnem Duyar
Onur Eker
Emre Erzgn
Tayfun Yaar
Metin Hrn
Ahmet ztekin
Mesut diz
Levent Civa
Frat Ekinci
Talha Kesler
mer Gk
Yunus Emre Bulut
Erhan Paaolu
Cemre Efe Karaka
Salim Yldrm
aatay Genlik
Valeh Asadl
Halit Turan Arcan
Levent Gler
Yaar Celep
Uur Uyar
Serdar alar
Ahmet Onur Yldrm
Anl lginolu
Hseyin Ula Yeltrk
Nuri Acar
Azat Frat imen
Aykut Karda
Sezer Bozkr
Alican Uzunhan
zgr zer
Kerim Yldz
Muhammed Ylmaz
Ahmet Erdoan
Abdurrahman Dursun
Tahir Uzelli
Mehmet Akbay
Mehmet elikyontar
Sava Zengin
Tuncay Gven
Cafer Ulu
Nikita Trkmen
Axolotl Axolotl

49.1 Barbaros Akkurt

echo $HOME komutunun, C:\Users\falanca eklinde gsterilen kts /home/istihza


olarak dzeltildi.

898 Blm 49. Katkda Bulunanlar


Python 3 iin Trke Klavuz, Srm 3

49.2 ebnem Duyar

dahtaa eklinde yazlan daha kelimesi dzeltildi.


Blme ileminde 30 olarak gsterilen deer 3 olarak deitirildi.
23 + 5 ileminin 27 olarak gsterilen sonucu 28 olarak dzeltildi.

49.3 Onur Eker

Satrdaki kayma dzeltildi.


b deikeninin 23 olarak verilen deeri 10 olarak dzeltildi.
count() rneinin aklamasnda 2 olarak belirtilen karakter says 1 olarak dzeltildi.

49.4 Emre Erzgn

type() ile yazlan rnek int() ile yeniden yazld.


Tamsayya evrilmesi unutulan eler sayya evrildi.
Hatal kt veren count() rnei dzeltildi.

49.5 Tayfun Yaar

Koyulmas unutulan kme parantezleri karakter dizisi iine yerletirildi.

49.6 Metin Hrn

etkileimli kabul eklinde yazlan ifade etkileimli kabuk olarak dzeltildi.


iidnde eklinde yazlan ifade iinde olarak dzeltildi.
grnmyr eklinde yazlan ifade grnmyor olarak dzeltildi.
rendikce eklinde yazlan ifade rendike olarak dzeltildi.
dizilerinne eklinde yazlan ifade dizilerine olarak dzeltildi.
Birbirinden , iareti ile ayrlan anahtar-deer iftleri : iareti ile ayrld.
yannra eklinde yazlan ifade yansra olarak dzeltildi.

49.7 Ahmet ztekin

yukar eklinde yazlan ifade yukarda olarak dzeltildi.


rjust() metodunun yanl yazlan kts dzeltildi.
l1 eklinde yazlan deiken ad li1 olarak dzeltildi.

49.2. ebnem Duyar 899


Python 3 iin Trke Klavuz, Srm 3

49.8 Mesut diz

farkedemezsiniz eklinde yazlan kelime farkedemezseniz olarak dzeltildi.


Unutulan bir a har eklendi.
Cmle iinde = ileci ifadesinden sonra yazlan say2 ifadesi doru yerine
yerletirildi.
farldr eklinde yazlan kelime farkldr olarak dzeltildi.

49.9 Levent Civa

ayrntllaryla eklinde yazlan kelime ayrntlaryla olarak dzeltildi.


Toplam karakter uzunluuna ilikin rnek koddaki mantk hatas giderildi.

49.10 Frat Ekinci

rnekte ters yazlan Osman ve Mehmet isimlerinin sras dzeltildi.

49.11 Talha Kesler

Kontrol mekanizmal eval() kodlarndaki hata dzeltildi.


Hesap makinesi kodlarndaki eksik karakter dizisi dzeltildi.

49.12 mer Gk

Dosya karlatrma kodlarndaki deiken hatalar giderildi.

49.13 Yunus Emre Bulut

nclelikle olarak yazlan kelime ncelikle olarak dzeltildi.


Krk balant dzeltildi.
8 bit yerine yanllkla 7 bit olarak belirtilen say dzeltildi.

49.14 Erhan Paaolu

Bunun sebebi bir say ile (45) karakter dizisini (45) birbiriyle toplamaya almamzdr
cmlesi Bunun sebebi bir say (45) ile bir karakter dizisini (45) birbiriyle toplamaya
almamzdr eklinde dzeltilerek daha berrak bir hale getirildi.

900 Blm 49. Katkda Bulunanlar


Python 3 iin Trke Klavuz, Srm 3

49.15 Cemre Efe Karaka

split() olarak yazlan metot ad strip() olarak dzeltildi.

49.16 Salim Yldrm

falanca.png olarak yazlan karakter dizisi falanca.png olarak dzeltildi.


tatlilar eklinde yazlan kelime tatllar olarak dzeltildi.
"{:,}.format(1234567890) olarak yazlan kod "{:,}".format(1234567890) olarak
dzeltildi.
"{:b}.format(2) olarak yazlan kod "{:b}".format(2) olarak dzeltildi.
Belge gncellemesi esnasnda yanllkla paragraftan silinen ksm tekrar eklendi.

49.17 aatay Genlik

(50087).bit_length() kodunun 2 olarak gsterilen kts 16 olarak dzeltildi.

49.18 Valeh Asadl

liste olarak belirtilen liste adlar yeler olarak dzeltildi.


Demet iinde mehmet eklinde yazlan karakter dizisi mehmet olarak dzeltildi.
TBMM olarak belirtilen karakter dizisi TBMM olarak dzeltildi.
\n olarak yazlan karakter dizisi \n olarak dzeltildi.

49.19 Halit Turan Arcan

Burada ikinci sradaki saylar ilk sradaki saylarn ikili sistemdeki karlklardr. nc
sradaki saylar ise her bir saynn ka bit olduunu, yani bir bakma ikili sayma
sisteminde ka basamaa sahip olduunu gsteriyor, cmlesinde sra kelimeleri
stun kelimeleri ile deitirilerek ifade tarznn daha anlalr olmas saland.

49.20 Levent Gler

PDF iin kapak tasarm [bkz. http://istihza.com/forum/viewtopic.php?f=40&t=2487]


Komutun, uzak ok uzak... olarak gsterilen kts uzak ok uzak... olarak
dzeltildi.
C:\\aylar\\nisan\\toplam masraf eklinde gsterilen dizin yolu C:\aylar\nisan\toplam
masraf eklinde dzeltildi.
\\n olarak yazlan ka dizisi \n olarak dzeltildi.

49.15. Cemre Efe Karaka 901


Python 3 iin Trke Klavuz, Srm 3

ki kez ayn ekilde yazlan kodlar dzeltildi.


Yanllkla st_size yerine yazlan st_mtime nitelii deitirildi.
Karakter dizisinin sonuna eklenmesi unutulan satr ba karakteri (\n ) eklendi.

49.21 Yaar Celep

onlu, sekizli ve onaltl eklinde yazlmas gerekirken onlu ve onaltl olarak belirtilen
ifade dzeltildi.

49.22 Uur Uyar

print() fonksiyonu, kendisine verilen parametreler arasna birer nokta yerletirir,


cmlesi print() fonksiyonu, kendisine verilen parametreler arasna birer boluk
yerletirir, olarak dzeltildi.

49.23 Serdar alar

Program sonunda kapatlmas unutulan bir dosya kapatld.


Liste iinde yer alan saylarn bazlarndaki, hataya yol aan biim bozukluu giderildi.
print(eviri_tablosu[i]) yerine hatal olarak print(i) eklinde yazlan kod
dzeltildi.
Uyar zerine, belge Pythonn en son srmne gre gzden geirildi.

49.24 Ahmet Onur Yldrm

{:o}.format(1980) yerine hatal olarak :o.format(1980) eklinde yazlan kod


dzeltildi.
closed() olarak belirtilen nitelik closed olarak dzeltildi.
szlk = harfler.index(i) olarak yazlan kod szlk[i] = harfler.index(i) olarak
dzeltildi.
ifaye olarak yazlan kelime ifadeye olarak dzeltildi.
aktarmadamz olarak yazlan kelime aktarmadmz olarak dzeltildi
ktya eklenmesi unutulan fonk8_ fonksiyonu eklendi.
Baz GNU/Linux datmlarnda webbrowser modlnn open() fonksiyonuna verilen
websitesi adreslerinin http nekiyle yazlmas gerektiine dair bir not eklendi.
ayna olarak yazlan kelime ayn olarak dzeltildi.
Yanllkla prezantabl olarak yazlan liste esi konukan olarak dzeltildi.
mimtarisi olarak yazlan kelime mimarisi olarak dzeltildi.

902 Blm 49. Katkda Bulunanlar


Python 3 iin Trke Klavuz, Srm 3

%PROCESSOR_ARCHITECTURE olarak yazlan evre deikeni


%PROCESSOR_ARCHITECTURE% olarak dzeltildi.

49.25 Anl lginolu

denene olarak yazlan kelime deneme olarak dzeltildi.

49.26 Hseyin Ula Yeltrk

listedindeki olarak yazlan kelime listesindeki olarak dzeltildi.


Yanllkla ift yazlan teknik kelimesi dzeltildi.
nitelii olarak yazlan kelime niteliin olarak dzeltildi.

49.27 Nuri Acar

nitelin olarak yazlan kelime niteliin olarak dzeltildi.

49.28 Azat Frat imen

gn_says olarak yazlan deiken ad gn olarak dzeltildi.

49.29 Aykut Karda

n eklinde yazlan ka dizisi, \n olarak dzeltildi.

49.30 Sezer Bozkr

derini eklinde yazlan kelime deerini olarak dzeltildi.

49.31 Alican Uzunhan

if bloundaki girinti kaymas dzeltildi.


gzde eklinde yazlan kelime gze olarak dzeltildi.
rnek bir koddaki deiken ve ile hatas dzeltildi.
kullanmasnz eklinde yazlan kelime kullanmasanz olarak dzeltildi.
programmmzn eklinde yazlan kelime programmzn olarak dzeltildi.
self.__personel olarak yazlan deiken self._personel olarak dzeltildi.

49.25. Anl lginolu 903


Python 3 iin Trke Klavuz, Srm 3

mekanizmasnna olarak yazlan kelime mekanizmasna olarak dzeltildi.


konular de olarak yazlan ifade konular da olarak dzeltildi.
akrarrken olarak yazlan kelime aktarrken olarak dzeltildi.
sa\*t olarak grnen dzenli ifade sa*t olarak dzeltildi.
print(im) eklinde yazlan print(veri) olarak dzeltildi.
yardnyla olarak yazlan kelime yardmyla olarak dzeltildi.
Burada kadar olarak yazlan ifade buraya kadar olarak dzeltildi

49.32 zgr zer

Flemenke olarak yazlan kelime Felemenke olarak dzeltildi.


komutunun olarak yazlan kelime komutun olarak dzeltildi.
Yanllkla iki kez yazlan bir kelimesi teke indirildi.
fonksiyonun olarak yazlan kelime fonksiyonunun olarak dzeltildi.

49.33 Kerim Yldz

yime olarak yazlan kelime yine olarak dzeltildi.

49.34 Muhammed Ylmaz

randrage olarak yazlan fonksiyon ad randrange olarak dzeltildi.

49.35 Ahmet Erdoan

print(a, b, end=) komutunun kt grnm dzeltildi.

49.36 Abdurrahman Dursun

Cmlede yanl yerde kullanlan end ve sep kelimeleri dzeltildi.


Yanllkla alnmz dik olarak yazlan ifade bamz dik olarak dzeltildi.
Kendisinden nceki cmlede ifade edilen kri tekrar eden gereksiz bir cmle
paragraftan karld.
Karakter dizisinin, unutulan kapatma trna yerine koyuldu.

904 Blm 49. Katkda Bulunanlar


Python 3 iin Trke Klavuz, Srm 3

49.37 Tahir Uzelli

Yanllkla 8 adet bir eklinde yazlan ifade 8 adet bit olarak dzeltildi.

49.38 Mehmet Akbay

Yanllkla a1.txt olarak belirtilen dosya ad hakknda.txt olarak dzeltildi.

49.39 Mehmet elikyontar

Yanllkla sat1 olarak yazlan kelime satr1 olarak dzeltildi.

49.40 Sava Zengin

Kodlardaki eksik parantez dzeltildi.


[^A-Z-a-z_] dzenli ifadesi [^A-Za-z0-9_] olarak dzeltildi.
Kodlara yanllkla fazladan eklenen \ iareti kaldrld.

49.41 Tuncay Gven

python3.pdf adl belgenin yanl yazlan indirme adresi dzeltildi.

49.42 Cafer Ulu

GNU-d ifadesi GNU d olarak dzeltildi.


websitesi kelimesi web sitesi olarak dzeltildi.

49.43 Nikita Trkmen

Kodlardaki bir adet fazla boluk karakteri kaldrld.


Yanllkla 3 milisaniye olarak belirtilen deer 300 milisaniye olarak dzeltildi.
alan.personel olarak belirtilmesi gerekirken personel olarak belirtilen deiken ad
dzeltildi.

49.44 Axolotl Axolotl

Yanllkla yukar olarak yazlan kelime yukarda olarak dzeltildi.


Kodlardaki yanl girintileme dzeltildi.

49.37. Tahir Uzelli 905


Python 3 iin Trke Klavuz, Srm 3

Gereksiz bir virgl iareti kaldrld.


Yanllkla olmadn olarak yazlan kelime olumadn olarak dzeltildi.
Srm bilgisini gsteren ktdaki Python ifadesi kaldrld.
metodununa olarak yazlan kelime metoduna olarak dzeltildi.
Gereksiz bir virgl iareti kaldrld.
ilermeye olarak yazlan kelime ilerlemeye olarak dzeltildi.
Kodun hatal kts dzeltildi.
< iareti > olarak dzeltildi.
Kodlardaki gereksiz bir parantez kaldrld.
Cmledeki gereksiz bir virgl iareti kaldrld.
Kk hare balanan cmle dzeltildi.
isim 5 karakterden kkse ifadesi isim 5 karakterse veya bundan kkse olarak
dzeltildi.
Unutulan bir a har eklendi.
Cmle sonunda unutulan nokta iareti eklendi.
metodunu olarak yazlan kelime metodu olarak dzeltildi.
ASCII tablosu ile ilgili bir hata dzeltildi.
Kullanc ad ve parola ile ilgili kodlardaki bir hata giderildi.
Yanl yere koyulan nokta iareti kaldrld.
Cmlede farkl nesne gruplar birbirinden ayrlrken virgl yerine noktal virgl iareti
kullanld.
ilemini olarak yazlan kelime ilemi olarak dzeltildi.
iare olarak yazlan kelime iareti olarak dzeltildi.
Unutulan kod kts eklendi.
ki nokta iaretinden sonra byk hare balamas gereken cmle dzeltildi.
istemiyorsanuz olarak yazlan kelime istemiyorsanz olarak dzeltildi.
oyununun olarak yazlan kelime oyunun olarak dzeltildi.
O olarak yazlmas gerekirken Y olarak yazlan karakter dzeltildi.
programmn olarak yazlan kelime programn olarak dzeltildi.

906 Blm 49. Katkda Bulunanlar

You might also like