forked from yazbel/python-istihza
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhata_yakalama.html
953 lines (894 loc) · 88.5 KB
/
hata_yakalama.html
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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
<!DOCTYPE html>
<html lang="tr">
<html lang="tr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<meta content="Bu bölümde hata yakalama konusunu inceleyeceğiz" name="description" />
<meta content="python, hata, try, except, exception, error" name="keywords" />
<title>Hata Yakalama — Python 3 için Türkçe Kılavuz</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/pyramid.css" />
<script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/translations.js"></script>
<link rel="search" title="Ara" href="search.html" />
<link rel="next" title="Karakter Dizileri" href="karakter_dizileri.html" />
<link rel="prev" title="Döngüler (Loops)" href="donguler.html" />
<!--[if lte IE 6]>
<link rel="stylesheet" href="_static/ie6.css" type="text/css" media="screen" charset="utf-8" />
<![endif]-->
</head><body>
<div class='header'><a href='https://yazbel.com'><img src="_static/logo.png"></a></div>
<ul class='navbar'>
<li><a href="#"><del>pdf desteği sonlanmıştır</del></a></li>
<li class="forum"><a href="http://forum.yazbel.com">forum</a></li>
</ul>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Gezinti</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="karakter_dizileri.html" title="Karakter Dizileri"
accesskey="N">sonraki</a></li>
<li class="right" >
<a href="donguler.html" title="Döngüler (Loops)"
accesskey="P">önceki</a> |</li>
<li class="nav-item nav-item-0"><a href=".">⌂</a></li>
<li class="nav-item nav-item-this"><a href="">Hata Yakalama</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="body" role="main">
<section id="hata-yakalama">
<h1>Hata Yakalama<a class="headerlink" href="#hata-yakalama" title="Bu başlık için kalıcı bağlantı">¶</a></h1>
<p>Şimdiye kadar yazdığımız bütün programlar, dikkat ettiyseniz tek bir ortak
varsayım üzerine kurulu. Buna göre biz, yazdığımız programın kullanıcı
tarafından nasıl kullanılmasını istiyorsak, her zaman o şekilde kullanılacağını
varsayıyoruz. Örneğin sayıları toplayan bir program yazdığımızda, kullanıcının
her zaman sayı değerli bir veri gireceğini düşünüyoruz. Ancak bütün iyi
niyetimize rağmen, yazdığımız programlarda işler her zaman beklediğimiz gibi
gitmeyebilir. Örneğin, dediğimiz gibi, yazdığımız programı, kullanıcının bir
sayı girmesi temeli üzerine kurgulamışsak, kullanıcının her zaman sayı değerli
bir veri gireceğinden emin olamayız.</p>
<p>Mesela şöyle bir program yazdığımızı düşünün:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">veri1</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Karekökünü hesaplamak istediğiniz sayı: "</span><span class="p">)</span>
<span class="n">karekök</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">veri1</span><span class="p">)</span> <span class="o">**</span> <span class="mf">0.5</span>
<span class="nb">print</span><span class="p">(</span><span class="n">veri1</span><span class="p">,</span> <span class="s2">"sayısının karekökü: "</span><span class="p">,</span> <span class="n">karekök</span><span class="p">)</span>
<span class="n">veri2</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Karesini hesaplamak istediğiniz sayı: "</span><span class="p">)</span>
<span class="n">kare</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">veri2</span><span class="p">)</span> <span class="o">**</span> <span class="mi">2</span>
<span class="nb">print</span><span class="p">(</span><span class="n">veri2</span><span class="p">,</span> <span class="s2">"sayısının karesi: "</span><span class="p">,</span> <span class="n">kare</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu kodlardaki sorunu anlamaya çalışmadan önce dilerseniz kodları şöyle bir
inceleyelim.</p>
<p>Gördüğünüz gibi, burada kullanıcının gireceği sayılara göre karekök ve kare alma
işlemleri yapıyoruz. Bu kodlarda gördüğümüz <cite>**</cite> işleci yardımıyla bir sayının
herhangi bir kuvvetini hesaplayabileceğimizi biliyorsunuz. Mesela 21<sup>7</sup>’nin kaç ettiğini hesaplamak için <cite>**</cite> işlecini kullanabiliyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="mi">21</span> <span class="o">**</span> <span class="mi">7</span>
<span class="go">1801088541</span>
</pre></div>
</div>
<p>Yine bildiğiniz gibi, bu işleçten, bir sayının karesini hesaplamak için de
yararlanabiliyoruz. Çünkü neticede bir sayının karesi, o sayının 2. kuvvetidir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="mi">12</span> <span class="o">**</span> <span class="mi">2</span>
<span class="go">144</span>
</pre></div>
</div>
<p>Aynı şekilde, eğer bir sayının, 0.5’inci kuvvetini hesaplarsak o sayının
karekökünü bulmuş oluyoruz. (Bu bilgileri önceki konulardan hatırlıyor
olmalısınız):</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="mi">144</span> <span class="o">**</span> <span class="mf">0.5</span>
<span class="go">12</span>
</pre></div>
</div>
<p>Kodlarımızı incelediğimize göre, bu programdaki aksaklıkları irdelemeye
başlayabiliriz.</p>
<p>Bu program, kullanıcı sayı değerli bir veri girdiği müddetçe sorunsuz bir
şekilde çalışacaktır. Peki ya kullanıcı sayı değerli bir veri yerine başka bir
şey girerse ne olur?</p>
<p>Örneğin kullanıcı yukarıdaki programa bir sayı yerine, (bilerek veya bilmeyerek)
içinde harf barındıran bir veri girerse şuna benzer bir hata alır:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">2</span><span class="p">,</span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="n">karekök</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">veri1</span><span class="p">)</span> <span class="o">**</span> <span class="mf">0.5</span>
<span class="ne">ValueError</span><span class="p">:</span> <span class="n">invalid</span> <span class="n">literal</span> <span class="k">for</span> <span class="nb">int</span><span class="p">()</span> <span class="k">with</span> <span class="n">base</span> <span class="mi">10</span><span class="p">:</span> <span class="s1">'fds'</span>
</pre></div>
</div>
<p>Yazdığınız programların bu tür hatalar vermesi normaldir. Ancak son kullanıcı
açısından düşündüğümüzde, kullanıcının yukarıdaki gibi bir hata mesajı görmesi
yerine, hatanın neden kaynaklandığını ya da neyi yanlış yaptığını daha açık bir
şekilde ifade eden bir mesaj alması çok daha mantıklı olacaktır. Zira yukarıdaki
hata mesajı programcılar açısından anlamlı olabilir, ancak son kullanıcı
açısından büsbütün anlaşılmazdır!</p>
<p>Dediğimiz gibi, programınızın çalışma esnasında bu tür hatalar vermesi normal.
Çünkü yapmaya çalıştığınız işlem, kullanıcının belli tipte bir veri girmesine
bağlı. Burada sizin bir programcı olarak göreviniz, yazdığınız programın çalışma
esnasında vermesi muhtemel hataları önceden kestirip, programınızda buna göre
bazı önlemler almanızdır. İşte biz de bu bölümde bu önlemleri nasıl alacağımızı
anlamaya çalışacağız.</p>
<section id="hata-turleri">
<h2>Hata Türleri<a class="headerlink" href="#hata-turleri" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Biz bu bölümde hatalardan bahsedeceğimizi söylemiştik. Ancak her şeyden önce
‘hata’ kavramının çok boyutlu olduğunu hatırlatmakta fayda var. Özellikle
programcılık açısından hata kavramının ne anlama geldiğini biraz incelememiz
gerekiyor.</p>
<p>Biz bu bölümde hataları üç farklı başlık altında ele alacağız:</p>
<ol class="arabic simple">
<li><p>Programcı Hataları (<em>Error</em>)</p></li>
<li><p>Program Kusurları (<em>Bug</em>)</p></li>
<li><p>İstisnalar (<em>Exception</em>)</p></li>
</ol>
<p>Öncelikle programcı hatalarından bahsedelim.</p>
<p>Programcıdan kaynaklanan hatalar doğrudan doğruya programı yazan kişinin
dikkatsizliğinden ötürü ortaya çıkan bariz hatalardır. Örneğin şu kod bir
programcı hatası içerir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span> <span class="s2">"Merhaba Python!"</span>
</pre></div>
</div>
<p>Bu kodu çalıştırdığınızda şöyle bir hata mesajı görürsünüz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="nb">print</span> <span class="s2">"Merhaba Python!"</span>
<span class="go">File "<stdin>", line 1</span>
<span class="go"> print "Merhaba Python!"</span>
<span class="go"> ^</span>
<span class="go">SyntaxError: invalid syntax</span>
</pre></div>
</div>
<p>Bu hata mesajında bizi ilgilendiren kısım son cümlede yer alıyor:
<code class="docutils literal notranslate"><span class="pre">SyntaxError</span></code>, yani Söz dizimi hatası.</p>
<p>Bu hatalar, programlama diline ilişkin bir özelliğin yanlış kullanımından veya
en basit şekilde programcının yaptığı yazım hatalarından kaynaklanır.
Programcının hataları genellikle <code class="docutils literal notranslate"><span class="pre">SyntaxError</span></code> şeklinde ortaya çıkar. Bu
hatalar çoğunlukla programcı tarafından farkedilir ve program kullanıcıya
ulaşmadan önce programcı tarafından düzeltilir. Bu tür hataların tespiti diğer
hatalara kıyasla kolaydır. Çünkü bu tür hatalar programınızın çalışmasını
engellediği için bunları farketmemek pek mümkün değildir…</p>
<p>Program kusurları, başka bir deyişle <em>bug</em>’lar ise çok daha karmaşıktır. Kusurlu
programlar çoğu zaman herhangi bir hata vermeden çalışır. Ancak programın
ürettiği çıktılar beklediğiniz gibi değildir. Örneğin yazdığınız programda bir
formül hatası yapmış olabilirsiniz. Bu durumda programınız hiçbir şey yokmuş
gibi çalışır, ancak formül hatalı olduğu için hesaplamaların sonuçları
yanlıştır. Örneğin daha önceki derslerimizde yazdığımız şu program yukarıdaki
gibi bir kusur içerir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">sayı1</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Toplama işlemi için ilk sayıyı girin: "</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Toplama işlemi için ikinci sayıyı girin: "</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"+"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">+</span> <span class="n">sayı2</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu programda kullanıcı veri girdiği zaman, programımız toplama işlemi değil
karakter dizisi birleştirme işlemi yapacaktır. Böyle bir program çalışma
sırasında hata vermeyeceği için buradaki sorunu tespit etmek, özellikle büyük
programlarda çok güçtür. Yani sizin düzgün çalıştığını zannettiğiniz program
aslında gizliden gizliye bir <em>bug</em> barındırıyor olabilir.</p>
<p>Aynı şekilde, mesela <code class="docutils literal notranslate"><span class="pre">eval()</span></code> fonksiyonunun dikkatsizce kullanıldığı
programlar da güvenlik açısından kusurludur. Yani bu tür programlar bir güvenlik
kusuru (<em>security bug</em> veya <em>security flaw</em>) barındırır.</p>
<p>Dediğimiz gibi, program kusurları çok boyutlu olup, burada anlattığımızdan çok
daha karmaşıktır.</p>
<p>Gelelim üçüncü kategori olan istisnalara (<em>exceptions</em>)…</p>
<p>İstisnalar, adından da az çok anlaşılacağı gibi, bir programın çalışması
sırasında ortaya çıkan, normalden farklı, istisnai durumlardır. Örneğin şu
programa bakalım:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı: "</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">ikinci_sayı</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">ilk_sayı</span> <span class="o">/</span> <span class="n">ikinci_sayı</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada ilk sayıyı ikinci sayıya bölen bir program yazdık. Bu program her türlü
bölme işlemini yapabilir. Ama burada hesaba katmamız gereken iki şey var:</p>
<ol class="arabic simple">
<li><p>Kullanıcı sayı yerine, sayı değerli olmayan bir veri tipi girebilir. Mesela
ilk sayıya karşılık <cite>23</cite>, ikinci sayıya karşılık ‘fdsfd’ gibi bir şey yazabilir.</p></li>
<li><p>Kullanıcı bir sayıyı <cite>0</cite>’a bölmeye çalışabilir. Mesela ilk sayıya karşılık
<cite>23</cite>, ikinci sayıya karşılık <cite>0</cite> yazabilir.</p></li>
</ol>
<p>İlk durumda programımız şöyle bir hata verir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk</span> <span class="n">sayı</span><span class="p">:</span> <span class="mi">23</span>
<span class="n">ikinci</span> <span class="n">sayı</span><span class="p">:</span> <span class="n">fdsfd</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">5</span><span class="p">,</span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="ne">ValueError</span><span class="p">:</span> <span class="n">invalid</span> <span class="n">literal</span> <span class="k">for</span> <span class="nb">int</span><span class="p">()</span> <span class="k">with</span> <span class="n">base</span> <span class="mi">10</span><span class="p">:</span> <span class="s1">'fdsfd'</span>
</pre></div>
</div>
<p>Buradaki sorun, sayı değerli olmayan bir verinin, <code class="docutils literal notranslate"><span class="pre">int()</span></code> fonksiyonu
aracılığıyla sayıya çevrilmeye çalışılıyor olması.</p>
<p>İkinci durumda ise programımız şöyle bir hata verir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk</span> <span class="n">sayı</span><span class="p">:</span> <span class="mi">23</span>
<span class="n">ikinci</span> <span class="n">sayı</span><span class="p">:</span> <span class="mi">0</span>
<span class="n">Traceback</span> <span class="p">(</span><span class="n">most</span> <span class="n">recent</span> <span class="n">call</span> <span class="n">last</span><span class="p">):</span>
<span class="n">File</span> <span class="s2">"deneme.py"</span><span class="p">,</span> <span class="n">line</span> <span class="mi">7</span><span class="p">,</span> <span class="ow">in</span> <span class="o"><</span><span class="n">module</span><span class="o">></span>
<span class="nb">print</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">ikinci_sayı</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">ilk_sayı</span> <span class="o">/</span> <span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="ne">ZeroDivisionError</span><span class="p">:</span> <span class="n">division</span> <span class="n">by</span> <span class="n">zero</span>
</pre></div>
</div>
<p>Buradaki sorun ise, bir sayının <cite>0</cite>’a bölünmeye çalışılıyor olması. Matematikte
sayılar <cite>0</cite>’a bölünemez…</p>
<p>İşte bu iki örnekte gördüğümüz <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> ve <code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> birer
istisnadır. Yani kullanıcıların, kendilerinden sayı beklenirken sayı değerli
olmayan veri girmesi veya bir sayıyı 0’a bölmeye çalışması istisnai birer
durumdur ve yazdığımız programların <em>exception</em> (istisna) üretmesine yol açar.</p>
<p>Böylece hata (<em>error</em>), kusur (<em>bug</em>) ve istisna (<em>exception</em>) arasındaki
farkları şöyle bir gözden geçirmiş olduk. Yalnız burada şunu söylemekte yarar
var: Bu üç kavram arasındaki fark belli belirsizdir. Yani bu kavramların çoğu
yerde birbirlerinin yerine kullanıldığını da görebilirsiniz. Örneğin <em>exception</em>
kavramı için Türkçe’de çoğu zaman ‘hata’ kelimesini kullanıyoruz. Zaten dikkat
ederseniz bu bölümün başlığı da ‘İstisna Yakalama’ değil, ‘Hata Yakalama’dır.
Aynı şekilde, İngilizcede de bu kavramların çoğu yerde birbirlerinin yerine
kullanıldığını görebilirsiniz. Dolayısıyla, konuya karşı özel bir ilginiz yoksa,
hata, kusur ve istisna kavramlarını birbirinden ayırmak için kendinizi
zorlamanıza gerek yok. Bu üç kavram çoğu zaman birbirinin yerine kullanılıyor da
olsa, aslında aralarında bazı farklar olduğunu öğrenmişseniz bu bölüm amacına
ulaşmış demektir.</p>
<p>Konuyla ilgili temel bilgileri edindiğimize göre asıl meseleye geçebiliriz…</p>
</section>
<section id="try-except">
<h2>try… except…<a class="headerlink" href="#try-except" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Bir önceki bölümde hatalardan ve hataları yakalamaktan söz ettik. Peki bu
hataları nasıl yakalayacağız?</p>
<p>Python’da hata yakalama işlemleri için <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span></code> bloklarından
yararlanılır. Hemen bir örnek verelim:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı: "</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sayı1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">/</span> <span class="n">sayı2</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Lütfen sadece sayı girin!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Biliyoruz ki, bir veriyi sayıya dönüştürmek istediğimizde eğer kullanıcı sayı
değerli bir veri yerine harf değerli bir veri girerse programımız çöker.
Dolayısıyla <code class="docutils literal notranslate"><span class="pre">int(ilk_sayı)</span></code> ve <code class="docutils literal notranslate"><span class="pre">int(ikinci_sayı)</span></code> kodları, kullanıcının
gireceği veri türüne göre hata üretme potansiyeline sahiptir. O yüzden, burada
hata vereceğini bildiğimiz o kodları <code class="docutils literal notranslate"><span class="pre">try</span></code> bloğu içine aldık.</p>
<p>Yine bildiğimiz gibi, veri dönüştürme işlemi sırasında kullanıcının uygun
olmayan bir veri girmesi halinde üretilecek hata bir <code class="docutils literal notranslate"><span class="pre">ValueError</span></code>’dır.
Dolayısıyla <code class="docutils literal notranslate"><span class="pre">except</span></code> bloğu içine yazacağımız hata türünün adı da
<code class="docutils literal notranslate"><span class="pre">ValueError</span></code> olacaktır. O yüzden <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> adlı hatayı yakalayabilmek
için şu satırları yazdık:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Lütfen sadece sayı girin!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada bu kodlarla Python’a şu emri vermiş olduk:</p>
<blockquote>
<div><p>Eğer <code class="docutils literal notranslate"><span class="pre">try</span></code> bloğu içinde belirtilen işlemler sırasında bir <code class="docutils literal notranslate"><span class="pre">ValueError</span></code>
ile karşılaşırsan bunu görmezden gel ve normal şartlar altında kullanıcıya
göstereceğin hata mesajını gösterme. Onun yerine kullanıcıya <code class="docutils literal notranslate"><span class="pre">Lütfen</span> <span class="pre">sadece</span>
<span class="pre">sayı</span> <span class="pre">girin!</span></code> uyarısını göster.</p>
</div></blockquote>
<p>Yukarıda Türkçeye çevirdiğimiz emri Pythoncada nasıl ifade ettiğimize dikkat
edin. Temel olarak şöyle bir yapıyla karşı karşıyayız:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">hata</span> <span class="n">verebileceğini</span> <span class="n">bildiğimiz</span> <span class="n">kodlar</span>
<span class="k">except</span> <span class="n">HataAdı</span><span class="p">:</span>
<span class="n">hata</span> <span class="n">durumunda</span> <span class="n">yapılacak</span> <span class="n">işlem</span>
</pre></div>
</div>
<p>Gelin isterseniz bir örnek daha verelim.</p>
<p>Hatırlarsanız bir sayının <cite>0</cite>’a bölünmesinin mümkün olmadığını, böyle bir
durumda programımızın hata vereceğini söylemiştik. Bu durumu teyit etmek için
etkileşimli kabukta şu kodu deneyebilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="mi">2</span> <span class="o">/</span> <span class="mi">0</span>
</pre></div>
</div>
<p>Bu kod şöyle bir hata mesajı verecektir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="mi">2</span> <span class="o">/</span> <span class="mi">0</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">"<stdin>"</span>, line <span class="m">1</span>, in <span class="n"><module></span>
<span class="gr">ZeroDivisionError</span>: <span class="n">division by zero</span>
</pre></div>
</div>
<p>Daha önce de söylediğimiz gibi, bu hata mesajında bizi ilgilendiren kısım
<code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code>. Demek ki bir sayı <cite>0</cite>’a bölündüğünde Python
<code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> veriyormuş. O halde şöyle bir kod yazabiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı: "</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sayı1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">/</span> <span class="n">sayı2</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Bir sayıyı 0'a bölemezsiniz!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, Python’ın <code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> vereceğini bildiğimiz durumlara
karşı bu hata türünü yakalama yoluna gidiyoruz. Böylece kullanıcıya anlamsız ve
karmaşık hata mesajları göstermek ve daha da kötüsü, programımızın çökmesine
sebep olmak yerine daha anlaşılır mesajlar üretiyoruz.</p>
<p>Yukarıdaki kodlarda özellikle bir nokta dikkatinizi çekmiş olmalı: Dikkat
ederseniz yukarıdaki kodlar aslında bir değil iki farklı hata üretme
potansiyeline sahip. Eğer kullanıcı sayı değerli veri yerine harf değerli bir
veri girerse <code class="docutils literal notranslate"><span class="pre">ValueError</span></code>, eğer bir sayıyı <cite>0</cite>’a bölmeye çalışırsa da
<code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> hatası alıyoruz. Peki aynı kodlarda iki farklı hata türünü
nasıl yakalayacağız?</p>
<p>Çok basit:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı: "</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sayı1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">/</span> <span class="n">sayı2</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Bir sayıyı 0'a bölemezsiniz!"</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Lütfen sadece sayı girin!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Gördüğünüz gibi çözüm gayet mantıklı. Birden fazla hata türü üreteceğini
bildiğimiz kodları yine tek bir <code class="docutils literal notranslate"><span class="pre">try</span></code> bloğu içine alıyoruz. Hata türlerini ise
ayrı <code class="docutils literal notranslate"><span class="pre">except</span></code> blokları içinde ele alıyoruz.</p>
<p>Bir program yazarken, en iyi yaklaşım, yukarıda yaptığımız gibi, her hata türü
için kullanıcıya ayrı bir uyarı mesajı göstermektir. Böylece kullanıcılarımız
bir hatayla karşılaştıklarında sorunu nasıl çözebilecekleri konusunda en azından
bir fikir sahibi olabilirler.</p>
<p>Dediğimiz gibi, her hata için ayrı bir mesaj göstermek en iyisidir. Ama tabii
dilerseniz hata türlerini gruplayıp hepsi için tek bir hata mesajı göstermeyi de
tercih edebilirsiniz. Bunu nasıl yapacağımızı görelim:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı: "</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sayı1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">/</span> <span class="n">sayı2</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">ZeroDivisionError</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Bir hata oluştu!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, burada <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> ve <code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> adlı hata
türlerini tek bir parantez içinde topladık. Burada dikkat edeceğimiz nokta, bu
hata türlerini gruplarken bunları parantez içine almak ve birbirlerinden
virgülle ayırmaktır.</p>
<p>Bu arada, gördüğünüz gibi yukarıdaki programlar sadece bir kez çalışıp
kapanıyor. Ama biz bu programları tekrar tekrar nasıl çalıştırabileceğimizi
gayet iyi biliyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">while</span> <span class="kc">True</span><span class="p">:</span>
<span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı (Programdan çıkmak için q tuşuna basın): "</span><span class="p">)</span>
<span class="k">if</span> <span class="n">ilk_sayı</span> <span class="o">==</span> <span class="s2">"q"</span><span class="p">:</span>
<span class="k">break</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sayı1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">/</span> <span class="n">sayı2</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">ZeroDivisionError</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Bir hata oluştu!"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Lütfen tekrar deneyin!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Python’da hata yakalamanın en yaygın yolu yukarıda gösterdiğimiz gibi kodları
<code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except</span></code> blokları içine almaktır. Programcılık maceranızın büyük
bölümünde bu yapıyı kullanacaksınız. Ama bazen, karşı karşıya olduğunuz duruma
veya ihtiyacınıza göre <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except</span></code> bloklarının farklı varyasyonlarını
kullanmanız gerekebilir. İşte şimdi biz de bu farklı varyasyonların neler
olduğunu incelemeye çalışacağız.</p>
</section>
<section id="try-except-as">
<h2>try… except… as…<a class="headerlink" href="#try-except-as" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Bildiğiniz gibi, Python bir programın çalışması esnasında hata üretirken çıktıda
hata türünün adıyla birlikte kısa bir hata açıklaması veriyor. Yani mesela şöyle
bir çıktı üretiyor:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="ne">ValueError</span><span class="p">:</span> <span class="n">invalid</span> <span class="n">literal</span> <span class="k">for</span> <span class="nb">int</span><span class="p">()</span> <span class="k">with</span> <span class="n">base</span> <span class="mi">10</span><span class="p">:</span> <span class="s1">'f'</span>
</pre></div>
</div>
<p>Burada ‘ValueError’ hata türünün adı, ‘invalid literal for int() with base 10:
‘f’’ ise hatanın açıklamasıdır. Eğer istersek, yazdığımız programda bu hata
açıklamasına erişebiliriz. Dikkatlice bakın:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı: "</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sayı1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">/</span> <span class="n">sayı2</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">hata</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">hata</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu programı çalıştırıp sayı değerli olmayan bir veri girersek hata çıktısı şöyle
olacaktır:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">invalid</span> <span class="n">literal</span> <span class="k">for</span> <span class="nb">int</span><span class="p">()</span> <span class="k">with</span> <span class="n">base</span> <span class="mi">10</span><span class="p">:</span> <span class="s1">'f'</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, bu defa çıktıda hata türünün adı (<code class="docutils literal notranslate"><span class="pre">ValueError</span></code>) görünmüyor.
Onun yerine sadece hata açıklaması var.</p>
<p>Diyelim ki kullanıcıya olası bir hata durumunda hem kendi yazdığınız hata
mesajını, hem de özgün hata mesajını göstermek istiyorsunuz. İşte yukarıdaki
yapı böyle durumlarda işe yarayabilir:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı: "</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sayı1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">/</span> <span class="n">sayı2</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span> <span class="k">as</span> <span class="n">hata</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Sadece sayı girin!"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"orijinal hata mesajı: "</span><span class="p">,</span> <span class="n">hata</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu arada, biraz önce yaptığımız gibi, hata türlerini grupladığınızda da bu
yöntemi kullanabilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">ilk_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ilk sayı: "</span><span class="p">)</span>
<span class="n">ikinci_sayı</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"ikinci sayı: "</span><span class="p">)</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">sayı1</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ilk_sayı</span><span class="p">)</span>
<span class="n">sayı2</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">ikinci_sayı</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="n">sayı1</span><span class="p">,</span> <span class="s2">"/"</span><span class="p">,</span> <span class="n">sayı2</span><span class="p">,</span> <span class="s2">"="</span><span class="p">,</span> <span class="n">sayı1</span> <span class="o">/</span> <span class="n">sayı2</span><span class="p">)</span>
<span class="k">except</span> <span class="p">(</span><span class="ne">ValueError</span><span class="p">,</span> <span class="ne">ZeroDivisionError</span><span class="p">)</span> <span class="k">as</span> <span class="n">hata</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Bir hata oluştu!"</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"orijinal hata mesajı: "</span><span class="p">,</span> <span class="n">hata</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">falancaHata</span> <span class="pre">as</span> <span class="pre">filanca</span></code> yapısını kullanarak <code class="docutils literal notranslate"><span class="pre">falancaHata</span></code>’yı
<cite>filanca</cite> olarak isimlendiriyor ve daha sonra bu ismi istediğimiz gibi
kullanabiliyoruz. Böylece bütün hata türleri için hem kendi yazdığınız mesajı
görüntüleyebiliyor, hem de özgün hata mesajını da çıktıya eklediğimiz için,
kullanıcıya hata hakkında en azından bir fikir sahibi olma imkanı vermiş
oluyoruz.</p>
</section>
<section id="try-except-else">
<h2>try… except… else…<a class="headerlink" href="#try-except-else" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Daha önce de dediğimiz gibi, Python’da hata yakalama işlemleri için çoğunlukla
<code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span></code> bloklarını bilmek yeterli olacaktır. İşlerimizin büyük
kısmını sadece bu blokları kullanarak halledebiliriz. Ancak Python bize bu
konuda, zaman zaman işimize yarayabilecek başka araçlar da sunmaktadır. İşte
<code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span> <span class="pre">else...</span></code> blokları da bu araçlardan biridir. Bu bölümde
kısaca bu blokların ne işe yaradığından söz edeceğiz.</p>
<p>Öncelikle <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span> <span class="pre">else...</span></code> bloğunun ne işe yaradığına bakalım.
Esasında biz bu <code class="docutils literal notranslate"><span class="pre">else</span></code> deyimini daha önce de ‘koşullu ifadeler’ konusunu
işlerken görmüştük. Buradaki kullanımı da zaten hemen hemen aynıdır. Diyelim ki
elimizde şöyle bir şey var:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">bölünen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölünecek sayı: "</span><span class="p">))</span>
<span class="n">bölen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölen sayı: "</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">bölünen</span><span class="o">/</span><span class="n">bölen</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"hata!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada eğer kullanıcı sayı yerine harf girerse <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> hatası alırız. Bu
hatayı <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">ValueError:</span></code> ifadesiyle yakalıyoruz ve hata verildiğinde
kullanıcıya bir mesaj göstererek programımızın çökmesini engelliyoruz. Ama
biliyoruz ki, bu kodları çalıştırdığımızda Python’ın verebileceği tek hata
<code class="docutils literal notranslate"><span class="pre">ValueError</span></code> değildir. Eğer kullanıcı bir sayıyı 0’a bölmeye çalışırsa Python
<code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> adlı hatayı verecektir. Dolayısıyla bu hatayı da yakalamak
için şöyle bir şey yazabiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">bölünen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölünecek sayı: "</span><span class="p">))</span>
<span class="n">bölen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölen sayı: "</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">bölünen</span><span class="o">/</span><span class="n">bölen</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Lütfen sadece sayı girin!"</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Bir sayıyı 0'a bölemezsiniz!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu şekilde hem <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> hatasını hem de <code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> hatasını
yakalamış oluruz. Bu kodların özelliği, <code class="docutils literal notranslate"><span class="pre">except...</span></code> bloklarının tek bir
<code class="docutils literal notranslate"><span class="pre">try...</span></code> bloğunu temel almasıdır. Yani biz burada bütün kodlarımızı tek bir
<code class="docutils literal notranslate"><span class="pre">try...</span></code> bloğu içine tıkıştırıyoruz. Bu blok içinde gerçekleşen hataları da
daha sonra tek tek <code class="docutils literal notranslate"><span class="pre">except...</span></code> blokları yardımıyla yakalıyoruz. Ama eğer biz
istersek bu kodlarda verilebilecek hataları gruplamayı da tercih edebiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">bölünen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölünecek sayı: "</span><span class="p">))</span>
<span class="n">bölen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölen sayı: "</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Lütfen sadece sayı girin!"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">bölünen</span><span class="o">/</span><span class="n">bölen</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Bir sayıyı 0'a bölemezsiniz!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada yaptığımız şey şu: İlk <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span></code> bloğu yardımıyla öncelikle
<code class="docutils literal notranslate"><span class="pre">int(input())</span></code> fonksiyonu ile kullanıcıdan gelecek verinin sayı olup
olmadığını denetliyoruz. Ardından bir <code class="docutils literal notranslate"><span class="pre">else...</span></code> bloğu açarak, bunun içinde
ikinci <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span></code> bloğumuzu devreye sokuyoruz. Burada da bölme
işlemini gerçekleştiriyoruz. Kullanıcının bölme işlemi sırasında <cite>0</cite> sayısını
girmesi ihtimaline karşı da <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">ZeroDivisionError</span></code> ifadesi yardımıyla
olası hatayı göğüslüyoruz. Bu şekilde bir kodlamanın bize getireceği avantaj,
hatalar üzerinde belli bir kontrol sağlamamıza yardımcı olmasıdır. Yukarıdaki
kodlar sayesinde hatalara bir nevi ‘teker teker gelin!’ mesajı vermiş oluyoruz.
Böylelikle her blok içinde sadece almayı beklediğimiz hatayı karşılıyoruz.
Mesela yukarıda ilk <code class="docutils literal notranslate"><span class="pre">try...</span></code> bloğu içindeki dönüştürme işlemi yalnızca
<code class="docutils literal notranslate"><span class="pre">ValueError</span></code> hatası verebilir. <code class="docutils literal notranslate"><span class="pre">else:</span></code> bloğundan sonraki <code class="docutils literal notranslate"><span class="pre">try...</span></code> bloğunda
yer alan işlem ise ancak <code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> verecektir. Biz yukarıda
kullandığımız yapı sayesinde her bir hatayı tek tek ve yeri geldiğinde
karşılıyoruz. Bu durumun aksine, bölümün ilk başında verdiğimiz <code class="docutils literal notranslate"><span class="pre">try...</span>
<span class="pre">except</span></code> bloğunda hem <code class="docutils literal notranslate"><span class="pre">ValueError</span></code> hem de <code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> hatalarının
gerçekleşme ihtimali bulunuyor. Dolayısıyla biz orada bütün hataları tek bir
<code class="docutils literal notranslate"><span class="pre">try...</span></code> bloğu içine sıkıştırmış oluyoruz. İşte <code class="docutils literal notranslate"><span class="pre">else:</span></code> bloğu bu sıkışıklığı
gidermiş oluyor. Ancak sizi bir konuda uyarmak isterim: Bu yapı, her akla
geldiğinde kullanılacak bir yapı değildir. Büyük programlarda bu tarz bir
kullanım kodlarınızın darmadağın olmasına, kodlarınız üzerindeki denetimi
tamamen kaybetmenize de yol açabilir. Sonunda da elinizde bölük pörçük bir kod
yığını kalabilir. Zaten açıkça söylemek gerekirse <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span> <span class="pre">else...</span></code>
yapısının çok geniş bir kullanım alanı yoktur. Bu yapı ancak çok nadir
durumlarda kullanılmayı gerektirebilir. Dolayısıyla bu üçlü yapıyı hiç
kullanmadan bir ömrü rahatlıkla geçirebilirsiniz.</p>
</section>
<section id="try-except-finally">
<h2>try… except… finally…<a class="headerlink" href="#try-except-finally" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p><code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span> <span class="pre">else...</span></code> yapılarının dışında, Python’ın bize sunduğu bir
başka yapı da <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except...</span> <span class="pre">finally...</span></code> yapılarıdır. Bunu şöyle
kullanıyoruz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="o">...</span><span class="n">bir</span> <span class="n">takım</span> <span class="n">işler</span><span class="o">...</span>
<span class="k">except</span> <span class="n">birHata</span><span class="p">:</span>
<span class="o">...</span><span class="n">hata</span> <span class="n">alınınca</span> <span class="n">yapılacak</span> <span class="n">işlemler</span><span class="o">...</span>
<span class="k">finally</span><span class="p">:</span>
<span class="o">...</span><span class="n">hata</span> <span class="n">olsa</span> <span class="n">da</span> <span class="n">olmasa</span> <span class="n">da</span> <span class="n">yapılması</span> <span class="n">gerekenler</span><span class="o">...</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">finally..</span></code> bloğunun en önemli özelliği, programın çalışması sırasında
herhangi bir hata gerçekleşse de gerçekleşmese de işletilecek olmasıdır. Eğer
yazdığınız programda mutlaka ama mutlaka işletilmesi gereken bir kısım varsa, o
kısmı <code class="docutils literal notranslate"><span class="pre">finally...</span></code> bloğu içine yazabilirsiniz.</p>
<p><code class="docutils literal notranslate"><span class="pre">finally...</span></code> bloğu özellikle dosya işlemlerinde işimize yarayabilir. Henüz
Python’da dosyalarla nasıl çalışacağımızı öğrenmedik, ama ben şimdilik size en
azından dosyalarla çalışma prensibi hakkında bir şeyler söyleyeyim.</p>
<p>Genel olarak Python’da dosyalarla çalışabilmek için öncelikle bilgisayarda
bulunan bir dosyayı okuma veya yazma kipinde açarız. Dosyayı açtıktan sonra bu
dosyayla ihtiyacımız olan birtakım işlemler gerçekleştiririz. Dosyayla işimiz
bittikten sonra ise dosyamızı mutlaka kapatmamız gerekir. Ancak eğer dosya
üzerinde işlem yapılırken bir hata ile karşılaşılırsa dosyamızı kapatma işlemini
gerçekleştirdiğimiz bölüme hiç ulaşılamayabilir. İşte <code class="docutils literal notranslate"><span class="pre">finally...</span></code> bloğu böyle
bir durumda işimize yarayacaktır:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">dosya</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"dosyaadı"</span><span class="p">,</span> <span class="s2">"r"</span><span class="p">)</span>
<span class="o">...</span><span class="n">burada</span> <span class="n">dosyayla</span> <span class="n">bazı</span> <span class="n">işlemler</span> <span class="n">yapıyoruz</span><span class="o">...</span>
<span class="o">...</span><span class="n">ve</span> <span class="n">ansızın</span> <span class="n">bir</span> <span class="n">hata</span> <span class="n">oluşuyor</span><span class="o">...</span>
<span class="k">except</span> <span class="ne">IOError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"bir hata oluştu!"</span><span class="p">)</span>
<span class="k">finally</span><span class="p">:</span>
<span class="n">dosya</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
</div>
<p>Burada <code class="docutils literal notranslate"><span class="pre">finally...</span></code> bloğu içine yazdığımız <code class="docutils literal notranslate"><span class="pre">dosya.close()</span></code> ifadesi dosyamızı
güvenli bir şekilde kapatmaya yarıyor. Bu blok, yazdığımız program hata verse de
vermese de işletilecektir.</p>
</section>
<section id="raise">
<h2>raise<a class="headerlink" href="#raise" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Bazen, yazdığımız bir programda, kullanıcının yaptığı bir işlem normal şartlar
altında hata vermeyecek olsa bile biz ona ‘Python tarzı’ bir hata mesajı
göstermek isteyebiliriz. Böyle bir durumda ihtiyacımız olan şey Python’ın bize
sunduğu <code class="docutils literal notranslate"><span class="pre">raise</span></code> adlı deyimdir. Bu deyim yardımıyla duruma özgü hata mesajları
üretebiliriz. Bir örnek verelim:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">bölünen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölünecek sayı: "</span><span class="p">))</span>
<span class="k">if</span> <span class="n">bölünen</span> <span class="o">==</span> <span class="mi">23</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">"Bu programda 23 sayısını görmek istemiyorum!"</span><span class="p">)</span>
<span class="n">bölen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölen sayı: "</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">bölünen</span><span class="o">/</span><span class="n">bölen</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada eğer kullanıcı <cite>23</cite> sayısını girerse, kullanıcıya bir hata mesajı
gösterilip programdan çıkılacaktır. Biz bu kodlarda <code class="docutils literal notranslate"><span class="pre">Exception</span></code> adlı genel
hata mesajını kullandık. Burada <code class="docutils literal notranslate"><span class="pre">Exception</span></code> yerine her istediğimizi yazamayız.
Yazabileceklerimiz ancak Python’da tanımlı hata mesajları olabilir. Örneğin
<code class="docutils literal notranslate"><span class="pre">NameError</span></code>, <code class="docutils literal notranslate"><span class="pre">TypeError</span></code>, <code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code>, <code class="docutils literal notranslate"><span class="pre">IOError</span></code>, vb…</p>
<p>Bir örnek verelim:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">tr_karakter</span> <span class="o">=</span> <span class="s2">"şçğüöıİ"</span>
<span class="n">parola</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Parolanız: "</span><span class="p">)</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">parola</span><span class="p">:</span>
<span class="k">if</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">tr_karakter</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">TypeError</span><span class="p">(</span><span class="s2">"Parolada Türkçe karakter kullanılamaz!"</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">pass</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Parola kabul edildi!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu kodlar çalıştırıldığında, eğer kullanıcı, içinde Türkçe karakter geçen bir
parola yazarsa kendisine <code class="docutils literal notranslate"><span class="pre">TypeError</span></code> tipinde bir hata mesajı gösteriyoruz.
Eğer kullanıcının parolası Türkçe karakter içermiyorsa hiçbir şey yapmadan
geçiyoruz ve bir sonraki satırda kendisine ‘Parola kabul edildi!’ mesajını
gösteriyoruz.</p>
<p><code class="docutils literal notranslate"><span class="pre">raise</span></code> deyimini, bir hata mesajına ek olarak bir işlem yapmak istediğimizde
de kullanabiliriz. Örneğin:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">bölünen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölünecek sayı: "</span><span class="p">))</span>
<span class="n">bölen</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="nb">input</span><span class="p">(</span><span class="s2">"bölen sayı: "</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">bölünen</span><span class="o">/</span><span class="n">bölen</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"bir sayıyı 0'a bölemezsiniz"</span><span class="p">)</span>
<span class="k">raise</span>
</pre></div>
</div>
<p>Burada, eğer kullanıcı bir sayıyı <cite>0</cite>’a bölmeye çalışırsa, normal bir şekilde
<code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> hatası verilecek ve programdan çıkılacaktır. Ama bu hata
mesajıyla birlikte kullanıcıya ‘bir sayıyı 0’a bölemezsiniz,’ uyarısını da
gösterme imkanını elde edeceğiz. Yani burada <code class="docutils literal notranslate"><span class="pre">except</span> <span class="pre">ZeroDivisionError</span></code>
bloğunu herhangi bir hatayı engellemek için değil, hataya ilave bilgi eklemek
için kullanıyoruz. Bunu yapmamızı sağlayan şey tabii ki bu kodlar içinde görünen
<code class="docutils literal notranslate"><span class="pre">raise</span></code> adlı deyimdir…</p>
</section>
<section id="assert">
<h2>assert<a class="headerlink" href="#assert" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Bazen programımızda bir hata yaptığımızda bu hatayı bulmakta zorlanabiliriz.
<code class="docutils literal notranslate"><span class="pre">print</span></code> fonksiyonunu kullanarak bu hatamızı bulmaya çalışabiliriz ancak
bu da programımız ekrana çok fazla yazdırma işlemi yapıyorsa gözden kaçabilir.
Böyle durumlarda <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadesini kullanabiliriz. <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadesi
aynı zamanda hata yükseltmenin kısa bir yoludur. Ancak <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadesini
kullanarak sadece <code class="docutils literal notranslate"><span class="pre">AssertionError</span></code> türünde bir hata yükseltebiliriz. Normalde
<code class="docutils literal notranslate"><span class="pre">raise</span></code> kullanmamız daha doğru olacaktır. Dediğimiz gibi <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadesi
hızlı bir şekilde kodumuzdaki hataları belirlemek için kullanılır.
Şimdi şöyle bir kodumuz olduğunu düşünelim:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">giriş</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Merhaba! Adın ne? "</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">giriş</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">AssertionError</span><span class="p">(</span><span class="s2">"İsim bölümü boş."</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Hoşgeldiniz."</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu kodu <code class="docutils literal notranslate"><span class="pre">assert</span></code> kullanarak şu şekilde de yazabilirdik:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">giriş</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Merhaba! Adın ne? "</span><span class="p">)</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">giriş</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">,</span> <span class="s2">"İsim bölümü boş."</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Hoşgeldiniz."</span><span class="p">)</span>
</pre></div>
</div>
<p>Dikkat ederseniz <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadesinin şu şekilde kullanıldığını görebilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">assert</span> <span class="n">ifade</span> <span class="p">,</span> <span class="n">mesaj</span>
</pre></div>
</div>
<p>Burada <code class="docutils literal notranslate"><span class="pre">ifade</span></code> bir <code class="docutils literal notranslate"><span class="pre">bool</span></code> yani <code class="docutils literal notranslate"><span class="pre">True</span></code> veya <code class="docutils literal notranslate"><span class="pre">False</span></code> olabileceği gibi, (aynı <code class="docutils literal notranslate"><span class="pre">if</span></code>’deki gibi)
<code class="docutils literal notranslate"><span class="pre">bool</span></code> fonksiyonu ile birlikte kullanılabilecek bir nesne de olabilir. Sonuç olarak
eğer <code class="docutils literal notranslate"><span class="pre">ifade</span></code>’nin değeri <code class="docutils literal notranslate"><span class="pre">True</span></code> ise <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifademiz çalışmayacak, <code class="docutils literal notranslate"><span class="pre">False</span></code> ise
çalışacaktır. Yani <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifademizin içine doğru olmasını istediğimiz durumu yazmalıyız ki
eğer yanlış olursa hata yükseltsin. Zaten <code class="docutils literal notranslate"><span class="pre">assert</span></code> kelimesi <em>“iddia etmek”</em> anlamına gelir. Yani biz <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadesini kullanarak bir ifadenin doğru olduğunu iddia ediyoruz, bu iddiamız yanlış ise Python bir hata yükseltiyor. Ayrıca <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifademiz çalıştığında bir hata yükseleceği için program da sonlanacaktır, yani bu özelliği istemediğimiz bir durum gerçekleştiğinde
programı sonlandırmak için de kullanabiliriz. <code class="docutils literal notranslate"><span class="pre">mesaj</span></code> ise hata verildiğinde ekrana yazılmasını
istediğimiz mesajdır. Tabii ki <code class="docutils literal notranslate"><span class="pre">raise</span></code> ifadesinde olduğu gibi burada da bir mesaj vermek zorunda
değiliz. Yani <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadesini şu şekilde de kullanabiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">assert</span> <span class="n">ifade</span>
</pre></div>
</div>
<p>Şimdi baştaki örneğimize geri dönersek:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">giriş</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Merhaba! Adın ne? "</span><span class="p">)</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">giriş</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">0</span> <span class="p">,</span> <span class="s2">"İsim bölümü boş."</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Hoşgeldiniz."</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu kodumuzu çalıştırdığımızda:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span>Merhaba! Adın ne? Ali
Hoşgeldiniz.
>>>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">giriş</span></code> değişkenimizin uzunluğu <code class="docutils literal notranslate"><span class="pre">0</span></code> olmadığı için bir hata verilmedi. Şimdi
aynı kodu çalıştırıp hiçbir şey yazmadan <code class="docutils literal notranslate"><span class="pre">enter</span></code> tuşuna basalım:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span>Merhaba! Adın ne?
Traceback (most recent call last):
File "C:\Users\Kullanıcı\Desktop\assert_ifadesi.py", line 2, in <module>
assert len(giriş) != 0 , "İsim bölümü boş."
AssertionError: İsim bölümü boş.
</pre></div>
</div>
<p>Gördüğünüz gibi <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadesini de bu şeklide kullanıyoruz. Burada bir şeye
dikkat etmek lazım ki <code class="docutils literal notranslate"><span class="pre">assert</span></code> bir fonksiyon değildir, bu yüzden parantezler
ile şu şekilde <strong>kullanılmamalıdır</strong>:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">assert</span><span class="p">(</span><span class="n">ifade</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu kullanım hata vermeyecek olsa da farkında olmadan -ileride öğreneceğimiz
bir konu- bir demet oluşturmuş oluyoruz.</p>
<p>Son olarak büyük bir proje yazdığımızda, şu örnekteki gibi:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">giriş</span> <span class="o">=</span> <span class="nb">input</span><span class="p">(</span><span class="s2">"Merhaba! Adın ne? "</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">giriş</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">AssertionError</span><span class="p">(</span><span class="s2">"İsim bölümü boş."</span><span class="p">)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Hoşgeldiniz."</span><span class="p">)</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">if</span></code> ve <code class="docutils literal notranslate"><span class="pre">raise</span></code> ifadesi kullanmak yerine <code class="docutils literal notranslate"><span class="pre">assert</span></code> kullanmamızın iki avantajından bahsedelim. Öncelikle istediğiniz zaman geliştirme arayüzünüzün <strong>“Bul (Find)”</strong> özelliğini kullanarak bu anahtar kelimeleri
bulup silebilir veya yorum satırı haline getirebilirsiniz. Bu özellik uzun bir kod yazdığımızda zaman kazanmamızı sağlar.
İkinci olarak da python yorumlayıcısını komut satırından <code class="docutils literal notranslate"><span class="pre">-O</span></code> parametresi (<em>optimize</em> anlamına gelir) ile şu şekilde çağırdığımızda:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="n">C</span><span class="p">:</span>\<span class="n">Users</span>\<span class="n">User</span><span class="o">></span> <span class="n">python</span> <span class="o">-</span><span class="n">O</span> <span class="n">kod_dosyası</span>
</pre></div>
</div>
<p><code class="docutils literal notranslate"><span class="pre">kod_dosyası</span></code> programımızdaki bütün <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadeleri python yorumlayıcısı tarafından yok sayılır ve hiçbiri çalıştırılmaz. Yani <code class="docutils literal notranslate"><span class="pre">assert</span></code> ifadelerinin hepsini yorum satırı haline getirmek istediğimizde bunun ile uğraşmak yerine bu özelliği kullanabiliriz.</p>
<p>Konu ile alakalı daha çok örnek için <a class="reference external" href="https://forum.yazbel.com/t/assert-deyimi-nasil-kullanilir/231">buraya</a> bakabilirsiniz.</p>
</section>
<section id="butun-hatalari-yakalamak">
<h2>Bütün Hataları Yakalamak<a class="headerlink" href="#butun-hatalari-yakalamak" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Şimdiye kadar yaptığımız bütün örneklerde <code class="docutils literal notranslate"><span class="pre">except...</span></code> bloğunu bir hata mesajı
adıyla birlikte kullandık. Yani örneklerimiz şuna benziyordu:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="o">....</span><span class="n">birtakım</span> <span class="n">işler</span><span class="o">...</span>
<span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="o">...</span><span class="n">hata</span> <span class="n">mesajı</span><span class="o">...</span>
</pre></div>
</div>
<p>Yukarıdaki kod yardımıyla sadece <code class="docutils literal notranslate"><span class="pre">ZeroDivisionError</span></code> adlı hatayı
yakalayabiliriz. Eğer yazdığımız program başka bir hata daha veriyorsa, o hata
mesajı yukarıdaki blokların kapsamı dışında kalacaktır. Ama eğer istersek
yukarıdaki kodu şu şekilde yazarak olası bütün hataları yakalayabiliriz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="o">....</span><span class="n">birtakım</span> <span class="n">işler</span><span class="o">...</span>
<span class="k">except</span><span class="p">:</span>
<span class="o">...</span><span class="n">hata</span> <span class="n">mesajı</span><span class="o">...</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, burada herhangi bir hata adı belirtmedik. Böylece Python,
yazdığımız programda hangi hata oluşursa oluşsun hepsini yakalayabilecektir.</p>
<p>Bu yöntem gözünüze çok pratik görünmüş olabilir, ama aslında hiç de öyle
sayılmaz. Hatta oldukça kötü bir yöntem olduğunu söyleyebiliriz bunun. Çünkü bu
tarz bir kod yazımının bazı dezavantajları vardır. Örneğin bu şekilde bütün hata
mesajlarını aynı kefeye koyarsak, programımızda ne tür bir hata oluşursa
oluşsun, kullanıcıya hep aynı mesajı göstermek zorunda kalacağız. Bu da,
herhangi bir hata durumunda kullanıcıyı ne yapması gerektiği konusunda doğru
düzgün bilgilendiremeyeceğimiz anlamına geliyor. Yani kullanıcı bir hataya sebep
olduğunda tersliğin nereden kaynaklandığını tam olarak kestiremeyecektir.</p>
<p>Ayrıca, eğer kendimiz bir program geliştirirken sürekli olarak bu tarz bir
yazımı benimsersek, kendi kodlarımızdaki hataları da maskelemiş oluruz.
Dolayısıyla, Python yukarıdaki geniş kapsamlı <code class="docutils literal notranslate"><span class="pre">except...</span></code> bloğu nedeniyle
programımızdaki bütün hataları gizleyeceği için, programımızdaki potansiyel
aksaklıkları görme imkanımız olmaz. Dolayısıyla bu tür bir yapıdan olabildiğince
kaçınmakta fayda var. Ancak elbette böyle bir kod yazmanızı gerektiren bir
durumla da karşılaşabilirsiniz. Örneğin:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="k">try</span><span class="p">:</span>
<span class="n">birtakım</span> <span class="n">kodlar</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Yanlış değer"</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">ZeroDivisionError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Sıfıra bölme hatası"</span><span class="p">)</span>
<span class="k">except</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"Beklenmeyen bir hata oluştu!"</span><span class="p">)</span>
</pre></div>
</div>
<p>Burada olası bütün hata türlerini yakaladıktan sonra, bunların dışında bizim o
anda öngöremediğimiz bir hatanın oluşması ihtimaline karşı <code class="docutils literal notranslate"><span class="pre">except:</span></code> kodunu
kullanarak kullanıcıya genel bir hata mesajı göstermeyi tercih edebiliriz.
Böylece beklenmeyen bir hata meydana gelmesi durumunda da programımız çökmek
yerine çalışmaya devam edebilecektir.</p>
</section>
<section id="ornek-uygulama">
<h2>Örnek Uygulama<a class="headerlink" href="#ornek-uygulama" title="Bu başlık için kalıcı bağlantı">¶</a></h2>
<p>Hata yakalama konusunu bütün ayrıntılarıyla inceledik. Gelin şimdi isterseniz
ufak bir örnek yapalım.</p>
<p>Hatırlarsanız bir kaç bölüm önce şöyle bir uygulama yazmıştık:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sys</span>
<span class="n">_2x_metni</span> <span class="o">=</span> <span class="s2">"""</span>
<span class="s2">Python'ın 2.x sürümlerinden birini kullanıyorsunuz.</span>
<span class="s2">Programı çalıştırabilmek için sisteminizde Python'ın</span>
<span class="s2">3.x sürümlerinden biri kurulu olmalı."""</span>
<span class="n">_3x_metni</span> <span class="o">=</span> <span class="s2">"Programa hoşgeldiniz."</span>
<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">major</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">_2x_metni</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">_3x_metni</span><span class="p">)</span>
</pre></div>
</div>
<p>Bu programın ne iş yaptığını biliyorsunuz. Bu program yardımıyla,
kullanıcılarımızın bilgisayarlarındaki Python sürümünü kontrol edip,
programımızın kullanılan sürüme göre tepki vermesini sağlıyoruz.</p>
<p>Ancak burada çok ciddi bir problem var. Python’ın 2.7 öncesi sürümlerinde <cite>sys</cite>
modülünün <code class="docutils literal notranslate"><span class="pre">version_info()</span></code> metodu farklı çıktılar verir. Mesela Python’ın 2.7
öncesi sürümlerinde <code class="docutils literal notranslate"><span class="pre">version_info()</span></code> metodunun <cite>major</cite>, <cite>minor</cite> veya <cite>micro</cite>
gibi nitelikleri bulunmaz. Bu nitelikler Python programlama diline 2.7 sürümüyle
birlikte geldi. Dolayısıyla yukarıdaki programı Python’ın 2.7 öncesi
sürümlerinden biriyle çalıştıran kullanıcılarınız istediğiniz çıktıyı
alamayacak, Python bu kullanıcalara şuna benzer bir hata mesajı göstererek
programın çökmesine sebep olacaktır:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="ne">AttributeError</span><span class="p">:</span> <span class="s1">'tuple'</span> <span class="nb">object</span> <span class="n">has</span> <span class="n">no</span> <span class="n">attribute</span> <span class="s1">'major'</span>
</pre></div>
</div>
<p>Python’ın 2.7 öncesi sürümlerinin kurulu olduğu bilgisayarlarda da programınızın
en azından çökmemesi ve makul bir çıktı verebilmesi için yukarıdaki kodlar şöyle
yazabilirsiniz:</p>
<div class="highlight-py3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">sys</span>
<span class="n">_2x_metni</span> <span class="o">=</span> <span class="s2">"""</span>
<span class="s2">Python'ın 2.x sürümlerinden birini kullanıyorsunuz.</span>
<span class="s2">Programı çalıştırabilmek için sisteminizde Python'ın</span>
<span class="s2">3.x sürümlerinden biri kurulu olmalı."""</span>
<span class="n">_3x_metni</span> <span class="o">=</span> <span class="s2">"Programa hoşgeldiniz."</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">sys</span><span class="o">.</span><span class="n">version_info</span><span class="o">.</span><span class="n">major</span> <span class="o"><</span> <span class="mi">3</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">_2x_metni</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">_3x_metni</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="nb">print</span><span class="p">(</span><span class="n">_2x_metni</span><span class="p">)</span>
</pre></div>
</div>
<p>Gördüğünüz gibi, <code class="docutils literal notranslate"><span class="pre">AttributeError</span></code> adlı hatayı vereceğini bildiğimiz kısmı bir
<code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except</span></code> bloğu içine aldık. Eğer programımız <code class="docutils literal notranslate"><span class="pre">AttributeError</span></code>
hatasını veriyorsa, programımızın çalıştırıldığı sistem Python’ın 2.7 sürümünden
daha düşük bir sürümü kullanıyor demektir. O yüzden kullanıcıya <cite>_2x_metni</cite>’ni
gösteriyoruz.</p>
<p>Elbette yukarıdaki programı yazmanın çok daha düzgün yolları vardır. Ama biz
hata yakalama yöntemlerinin buna benzer durumlarda da bir alternatif olarak
kullanılabileceğini bilelim. Ayrıca, dediğimiz gibi, <code class="docutils literal notranslate"><span class="pre">try...</span> <span class="pre">except</span></code> blokları
yukarıdaki sorunun çözümü için en uygun araçlar olmasa da, bazı durumlarda
hatayı önlemenin makul tek yoludur.</p>
</section>
</section>
<div class='glyph'><a href='https://yazbel.com'>♣</a></div>
<div class='extrarelbar'>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Gezinti</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="karakter_dizileri.html" title="Karakter Dizileri"
>sonraki</a></li>
<li class="right" >
<a href="donguler.html" title="Döngüler (Loops)"
>önceki</a> |</li>
<li class="nav-item nav-item-0"><a href=".">⌂</a></li>
<li class="nav-item nav-item-this"><a href="">Hata Yakalama</a></li>
</ul>
</div> </div>
<div class='addcomment'>Yorumlar</div>
<div class='how-to-use'>
<h3>Önemli Not</h3>
Eğer yazdığınız yorum içinde kod kullanacaksanız, kodlarınızı
<span class='tag'><pre><code></span> etiketleri içine alın. Örneğin:
<pre>
<span class='tag'><pre><code class="python"></span>
<span class='keyword'>print</span>(<span class='string'>"Merhaba Dünya!"</span>)
<span class='tag'></code></pre></span>
</pre>
</div>
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES * * */
var disqus_shortname = 'istihza';
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="https://disqus.com/?ref_noscript" rel="nofollow">comments powered by Disqus.</a></noscript>
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-4eca48eb2d83faf9" async="async"></script>
<div class="clearer"></div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Gezinti</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="karakter_dizileri.html" title="Karakter Dizileri"
>sonraki</a></li>
<li class="right" >
<a href="donguler.html" title="Döngüler (Loops)"
>önceki</a> |</li>
<li class="nav-item nav-item-0"><a href=".">⌂</a></li>
<li class="nav-item nav-item-this"><a href="">Hata Yakalama</a></li>
</ul>
</div>
<div class="footer">
© Copyright 2007-2021, Fırat Özgül | <a href="https://yazbel.com">yazbel.com</a>.
Son güncelleme: 30.09.2021.
Created using <a href="http://sphinx-doc.org/">Sphinx</a> 4.2.0.
<br>
<br>
<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/"><img
alt="Creative Commons License" style="border-width:0"
src="https://i.creativecommons.org/l/by-nc-sa/3.0/88x31.png" /></a><br />
<br>
</div>
<!-- Start of StatCounter Code for Default Guide -->
<script type="text/javascript">
var sc_project=10396326;
var sc_invisible=1;
var sc_security="fb5cd679";
var scJsHost = (("https:" == document.location.protocol) ?
"https://secure." : "http://www.");
document.write("<sc"+"ript type='text/javascript' src='" +
scJsHost+
"statcounter.com/counter/counter.js'></"+"script>");
</script>
<noscript><div class="statcounter"><a title="hit counter"
href="http://statcounter.com/" target="_blank"><img
class="statcounter"
src="http://c.statcounter.com/10396326/0/fb5cd679/1/"
alt="hit counter"></a></div></noscript>
<!-- End of StatCounter Code for Default Guide -->
</body>
</html>