Skip to content

6. İşlevler

Image

6.1. [fonc_01] komut dosyası: değişkenlerin kapsamı

[fonc_01] komut dosyası, işlevler arasında değişkenlerin kapsamına ilişkin örnekler gösterir:


# değişkenlerin kapsamı
def f1():
    # Küresel değişkenlerin kullanımı kaçınılmalıdır
    # i küresel değişkeni
    global i
    i += 1
    # yerel j değişkeni
    j = 10
    print(f"f1[i,j]=[{i},{j}]")


def f2():
    # global değişkenlerin kullanımı kaçınılmalıdır
    # i küresel değişkeni
    global i
    i += 1
    # yerel değişken j
    j = 20
    print(f"f2[i,j]=[{i},{j}]")


def f3():
    # yerel değişken i
    i = 1
    # yerel değişken j
    j = 30
    print(f"f3[i,j]=[{i},{j}]")


# ana program
i = 0
j = 0
# bu iki değişken, f işlevi tarafından ancak
# bu değişkenleri kullanmak istediğini global komutuyla açıkça belirtmesi durumunda
# ya da fonksiyon küresel değişkeni yalnızca okuma amacıyla kullanıyorsa
f1()
f2()
f3()
# j değişmedi, ancak i değişti
print(f"[i,j]=[{i},{j}]")

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_01.py
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[1,30]
[i,j]=[2,0]

Process finished with exit code 0

Notlar:

  • Bu komut dosyası, f1 ve f2 işlevlerinde küresel olarak tanımlanan i değişkeninin kullanımını göstermektedir. Bu durumda, ana program ile f1 ve f2 işlevleri aynı i değişkenini paylaşmaktadır.

6.2. [fonc_02] komut dosyası: değişkenlerin kapsamı

[fonc_03] komut dosyası, [fonc_02] komut dosyasını temel alır ve küresel değişkenlerin kullanımından nasıl kaçınılacağını gösterir:


# değişkenlerin kapsamı
def f1(i):
    # yerel değişken i
    i += 1
    # yerel j değişkeni
    j = 10
    print(f"f1[i,j]=[{i},{j}]")
    # değiştirilen değeri geri veriyoruz
    return i


def f2(i):
    # yerel i değişkeni
    i += 1
    # yerel j değişkeni
    j = 20
    print(f"f2[i,j]=[{i},{j}]")
    # değiştirilen değeri geri veriyoruz
    return i


def f3():
    # yerel değişken i
    i = 1
    # yerel j değişkeni
    j = 30
    print(f"f3[i,j]=[{i},{j}]")


# ana program
i = 0
j = 0
# bu iki değişken, f işlevi tarafından
# fonksiyonu, global komutuyla bunları kullanmak istediğini açıkça belirtirse
# ya da fonksiyon küresel değişkeni yalnızca okuma amacıyla kullanıyorsa
i = f1(i)
i = f2(i)
f3()
# j değişmemiştir, ancak i değişmiştir
print(f"[i,j]=[{i},{j}]")

Açıklamalar:

    1. ve 12. satırlar: [i] değişkeni, küresel olarak tanımlanmak yerine f1 ve f2 işlevlerine parametre olarak aktarılır;
    1. ve 19. satırlar: f1 ve f2 fonksiyonları, [i] değişkenindeki değişiklikleri ana programa geri aktarır. Ana program bu değişkeni 36. ve 37. satırlarda alır;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_02.py
f1[i,j]=[1,10]
f2[i,j]=[2,20]
f3[i,j]=[1,30]
[i,j]=[2,0]

Process finished with exit code 0

6.3. [fonc_03] betiği: değişkenlerin kapsamı

[fonc_03] komut dosyası, bir fonksiyonda ve bu fonksiyonu çağıran kodda aynı anda kullanılan değişkenlerin, fonksiyon içinde bu değişkenin yalnızca okuma amaçlı kullanılıp kullanılmadığına bağlı olarak gösterdiği bir özelliği ortaya koymaktadır.


def f1():
    # burada küresel i değişkeni bilinmektedir
    print(f"[f1] i={i}")
    # burada j küresel değişkeni bilinmektedir
    print(f"[f1] j={j}")


def f2():
    # burada küresel i değişkeni bilinmiyor
    # çünkü f2 fonksiyonu aynı isimde bir yerel değişken tanımlıyor
    # bu durumda öncelik ona aittir
    try:
        # daha ileride tanımlanan yerel i değişkenini görüntüleme denemesi
        print(f"[f2] i={i}")
        # Aşağıdaki komut, i'yi f2 işlevinin yerel bir değişkeni haline getirir
        i = 7
    except BaseException as erreur:
        print(f"[f2] erreur={erreur}")


def f3():
    # burada küresel i değişkeni bilinmemektedir
    # çünkü f3 fonksiyonu aynı isimde bir yerel değişken tanımlamaktadır
    # bu durumda öncelik ona aittir

    # Aşağıdaki komut, i'yi yerel bir değişken haline getirir
    i = 7
    # görüntüleme - burada i değişkeni bilinmektedir
    print(f"[f3] i={i}")


# main -----------
# fonksiyonlara ait küresel değişkenler
i = 10
j = 20
# f1 işlevinin çağrılması
f1()
print(f"[main] i={i}, j={j}")
# f2 çağrısı
f2()
print(f"[main] i={i}")
# f3 çağrısı
f3()
print(f"[main] i={i}")

Notlar

    1. satır: ana kod, [i] değişkenini tanımlar;
  • 1-5. satırlar: f1 fonksiyonu da [i] değişkenini kullanır, ancak ona bir değer atamaz. Bu, [i] değişkeninin okunmasıdır. Bu durumda, kullanılan [i] değişkeni, 34. satırdaki çağıran kodun değişkenidir;
  • satır 8-18: f2 fonksiyonu da [i] değişkenini kullanır, ancak 16. satırda ona bir değer atar. f2 içinde [i] değişkenine bir değer atanması, [i]'i otomatik olarak [f2] fonksiyonuna ait bir yerel değişken haline getirir. Bu da, çağıran koddaki [i] değişkenini "gizler";
    1. satır: Yerel değişken [i]'e yazma işlemi başarısız olacaktır, çünkü 14. satıra gelindiğinde bu değişkenin bir değeri yoktur. Değeri 16. satırda atanır. Bir istisna oluşacaktır. Bu nedenle, 14. satır bir try / catch bloğuna eklenmiştir;
  • 21-29. satırlar: f3 fonksiyonu, f2 fonksiyonuyla aynı işlevi görür, ancak yerel değişkeni [i]'i daha erken tanımlar;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_03.py
[f1] i=10
[f1] j=20
[main] i=10, j=20
[f2] erreur=local variable 'i' referenced before assignment
[main] i=10
[f3] i=7
[main] i=10

Process finished with exit code 0

6.4. [fonc_04] betiği: parametre aktarım yöntemi

Komut dosyası şu şekildedir:


# f1 fonksiyonu
def f1(a):
    a = 2


# f2 fonksiyonu
def f2(a, b):
    a = 2
    b = 3
    return a, b


# ------------------------ ana işlev
x = 1
f1(x)
print(f"x={x}")
(x, y) = (-1, -1)
(x, y) = f2(x, y)
print(f"x={x}, y={y}")

Sonuçlar

1
2
3
4
5
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_04.py
x=1
x=2, y=3

Process finished with exit code 0

Notlar:

  • Python'da her şey bir nesnedir. Bazı nesneler "değişmez" (İngilizce) olarak adlandırılır: bunlar değiştirilemez. Sayılar, karakter dizileri ve tuple'lar bu kategoriye girer. Python nesneleri fonksiyonlara parametre olarak aktarıldığında, bu nesneler "değişmez" olmadıkça referansları aktarılır; "değişmez" nesneler söz konusu olduğunda ise nesnenin değeri aktarılır;
  • f1 (2. satır) ve f2 (7. satır) fonksiyonları, bir çıktı parametresinin aktarımını göstermeyi amaçlamaktadır. Bir fonksiyonun gerçek parametresinin fonksiyon tarafından değiştirilmesini istiyoruz;
  • 2-3. satırlar: f1 işlevi, a adlı biçimsel parametresini değiştirir. Gerçek parametrenin de değiştirilip değiştirilmeyeceğini öğrenmek istiyoruz;
  • satır 14-15: Gerçek parametre x=1'tir. Sonuçların 2. satırı, gerçek parametrenin değiştirilmediğini göstermektedir. Dolayısıyla, gerçek parametre x ile biçimsel parametre a birbirinden farklı iki nesnedir;
  • satır 8-10: f2 fonksiyonu, biçimsel parametreleri a ve b'yi değiştirir ve bunları sonuç olarak döndürür;
  • 17-18. satırlar: f2 işlevine geçerli parametreler (x, y) aktarılır ve f2 işlevinin sonucu (x, y) değişkenlerine atanır. Sonuçların 3. satırı, geçerli parametrelerin (x, y) değiştirildiğini göstermektedir.

Buradan şu sonuç çıkar: "değiştirilemez" nesneler çıktı parametreleri olduğunda, bunların fonksiyon tarafından döndürülen sonuçların bir parçası olması gerekir.

6.5. [fonc_05] komut dosyası: komut dosyasında fonksiyonların yazılma sırası

[fonc_05] komut dosyası, kodda daha önce karşımıza çıkmamış bir fonksiyonun çağrılamayacağını göstermektedir:


# ------------------------ main
print(f2(100, 200))

# f1 fonksiyonu
def f1(a):
    return a + 10


# f2 fonksiyonu
def f2(a, b):
    return f1(a + b)

Notlar

    1. satır, komut dosyasında henüz tanımlanmamış olan f2 işlevini kullandığı için bir hataya neden olacaktır;

Sonuçlar

1
2
3
4
5
6
7
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_05.py
Traceback (most recent call last):
  File "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_05.py", line 2, in <module>
    print(f2(100, 200))
NameError: name 'f2' is not defined

Process finished with exit code 1

6.6. [fonc_06] komut dosyası: komut dosyasında fonksiyonların yazılma sırası

[fonc_06] komut dosyası, çağıran kod için geçerli olan kuralın işlevler için geçerli olmadığını göstermektedir:


# f2 fonksiyonu
def f2(a, b):
    return f1(a + b)


# f1 fonksiyonu
def f1(a):
    return a + 10


# ------------------------ ana
print(f2(100, 200))

Notlar

    1. satır: [f2] işlevi, komut dosyasının ilerleyen kısımlarında tanımlanan [f1] işlevini kullanır. Ancak bu durum bir hataya yol açmaz. Dolayısıyla, bir Python komut dosyasında işlevlerin tanımlanma sırasının önemi olmadığı sonucuna varılabilir;

Sonuçlar

1
2
3
4
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_06.py
310

Process finished with exit code 0

6.7. [fonc_07] betiği: modüllerin kullanımı

[fonc_07] betiği, fonksiyonları bir modül içinde nasıl izole edileceğini gösterir.

Image

Yeniden kullanılabilir işlevleri bir modülde ayırıyoruz. Bunları bir komut dosyasından diğerine taşımak yerine:

  • bunları, belirli bir şekilde tanımladığımız ayrı bir dosyaya yerleştiriyoruz;
  • bu işlevlere ihtiyaç duyan komut dosyaları, bunları içeren modülü 'içe aktarır';

[fonctions_module_01] betiği şöyledir:


# f2 fonksiyonu
def f2(a, b):
    return f1(a + b)

# f1 fonksiyonu
def f1(a):
    return a + 10

[fonctions_module_01] betiğindeki işlevlerin diğer betikler tarafından çağrılabilmesi için çeşitli yöntemler vardır. Bu yöntemler, betiğin [PyCharm] içinde çalıştırılıp çalıştırılmamasına göre farklılık gösterir.

[PyCharm] altında, içe aktarılan modüller [Sources Root] adlı belirli klasörlerde aranır. Bir klasörü [Sources Root] haline getirmenin iki yolu vardır:

Image

  • [4]'te klasörün rengi değişir;

Bu işlemden sonra, [fonctions/modules] klasörü kaynak klasör olarak tanınır. Ardından bir komut dosyasına şunu yazabilirsiniz:

from fonctions_module_01 import f2

[fonctions_module_01.py] modülünde tanımlanan f2 işlevini içe aktarmak / kullanmak için.

Başka bir yöntem ise proje özelliklerini kullanmaktır:

  • Yukarıda, [1-6] dizisi, [shared] klasörünü içe aktarılacak modüllerin depolandığı bir klasör haline getirir;

Şu an için, projenin kök dizini dışında [Sources Root] gibi herhangi bir klasör tanımlamayacağız:

Image

Bu işlem tamamlandıktan sonra, aşağıdaki [fonc-07] komut dosyasını yazabiliriz:


# modüllerin kullanımı
import sys

# ------------------------ ana
print(f"Python path={sys.path}")
from fonctions.shared.fonctions_module_01 import f2

print(f2(100, 200))
    1. satır: 5. satırda, [sys] nesnesini içe aktararak, [path] özniteliğini kullanabiliyoruz; bu öznitelik, [Python Path] olarak adlandırılan şeyi verir: içe aktarılan modülleri aramak üzere taranacak klasörlerin listesi;
    1. satır: [fonctions_module_01] modülünden f2 işlevi içe aktarılır. Bu modülü belirtmek için, projenin kök dizininden modüle giden yol kullanılır. Pycharm'da, bir komut dosyasında içe aktarılan bir modül arandığında projenin kök dizini her zaman taranan klasörler arasında yer alır. Dolayısıyla bu klasör, projenin [Python Path] listesinin bir parçasıdır. 5. satır, bunu doğrulamamızı sağlayacaktır;
    1. satır: Projenin kök dizininden [fonctions_module_01] klasörüne giden yolu yazacak olursak, [fonctions/shared/fonctions_module_01] yazılır. Bir modülün yolunda / işareti nokta ile değiştirilir. Dolayısıyla [fonctions.modules.fonctions_module_01] yazılır;
    1. satırdan sonra f2 fonksiyonu bilinmektedir. Bu fonksiyon 8. satırda kullanılır;

Sonuçlar


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_07.py
Python path=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions\\shared', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages']
310

Process finished with exit code 0

Yukarıda:

  • yeşil renkle vurgulanan kısımdan, projenin kök dizininin [Python Path]'in bir parçası olduğu görülüyor;
  • sarı renkle vurgulanmış kısımdan, çalıştırılan komut dosyasının klasörünün de [Python Path]'in bir parçası olduğu görülmektedir;
  • [Python Path]'in diğer öğeleri doğrudan Python kurulum klasöründen gelmektedir;

PyCharm kullanılarak [fonc-07] çalıştırılmadığında ne olur?

Image

Image

  • [1]'te, [fonc-07] betiği çalıştırılır. [fonctions] klasöründe bulunuruz;
  • [2]'te, yürütme klasörünün [Python Path]'in bir parçası olduğu görülür. Bu her zaman böyledir. Ayrıca, kök klasör olan [C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020]'in [Python Path]'in bir parçası olmadığı da görülebilir;
  • [3]'te, Python yorumlayıcısı [fonctions] modülünü bulamadığını bildirir;

İçe aktarılan [fonctions.shared.fonctions_module_01] modülünü aramak için Python yorumlayıcısı, [Python Path] klasörlerinde [fonctions] adlı bir alt klasör arar. Bu alt klasörü hiçbir yerde bulamaz. Aslında [fonctions] alt klasörü, [C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020] klasörünün altındadır ve bu klasör [Python Path]'in bir parçası değildir.

[fonc-08] komut dosyası bu soruna olası bir çözüm sunuyor.

6.8. [fonc_08] komut dosyası: [Python Path]'e klasör ekleme

[fonc-08] komut dosyasında gösterildiği gibi, [Python Path] dosyasını programlama yoluyla değiştirmek mümkündür:


# modüllerin kullanımı
import os
import sys

# komut dosyası dizini
script_dir = os.path.dirname(os.path.abspath(__file__))
# Değişiklikten önceki Python Yolu
print(f"Python path avant={sys.path}")
# [shared] klasörü Python Yolu'na ekleniyor
sys.path.append(f"{script_dir}/shared")
# Değişiklikten sonra Python Yolu
print(f"Python path après={sys.path}")

# f2'yi içe aktarma
from fonctions_module_01 import f2

# ------------------------ main
print(f2(100, 200))

Notlar

    1. satır: [__file__] özel değişkeni, çalıştırılan komut dosyasının adıdır. Çalıştırma ortamına göre bu ad mutlak (Pycharm) veya göreceli (konsol) olabilir. [os.path.abspath] işlevi, kendisine adı verilen dosyanın mutlak adını verir. [os.path.dirname] işlevi ise, kendisine adı verilen dosyayı içeren klasörün mutlak adını verir;
    1. satır: [sys.path], bir modül arandığında taranacak klasörlerin adlarını içeren bir dizidir. Bu diziye, 4. satırda tanımlanan proje kökü eklenir;
  • [Python Path] dizisini değişiklikten önce (satır 8) ve sonra (satır 12) görüntülenir;
    1. satır: f2 işlevini içeren [fonctions_module_01] modülünü içe aktarıyoruz;

PyCharm'te çalıştırıldığında aşağıdaki sonuçlar elde edilir:


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_08.py
Python path avant=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions\\shared', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages']
Python path après=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions\\shared', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions/shared']
310

Process finished with exit code 0
    1. satır: [shared] dosyasının [Python Path] içinde iki kez yer aldığı görülmektedir. Bu durum önlenebilir, ancak burada bir sorun teşkil etmemektedir;
    1. satır: f2 işlevi başarıyla çalıştırılmıştır;

Şimdi bir terminalde [fonc-08] dosyasını çalıştıralım:


(venv) C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\fonctions>python fonc_08.py
Python path avant=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages']
Python path après=['C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions', 'C:\\myprograms\\Python38\\python38.zip', 'C:\\myprograms\\Python38\\DLLs', 'C:\\myprograms\\Python38\\lib', 'C:\\myprograms\\Python38', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\venv\\lib\\site-packages', 'C:\\Data\\st-2020\\dev\\python\\cours-2020\\python3-flask-2020\\fonctions/shared']
310
    1. satır: Daha önce olduğu gibi, [shared] dosyası [Python Path] içinde yok;
    1. satır: şimdi içinde yer alıyor;
    1. satır: f2 işlevi bulundu;

6.9. [fonc_09] komut dosyası: parametre türlerinin tanımlanması

[fonc_09] komut dosyası, bir fonksiyonun parametrelerinin ve sonucunun türlerinin tanımlanabileceğini gösterir. Ancak bu tanımlama yalnızca fonksiyonun dokümantasyonu için yararlıdır. Python yorumlayıcısı, fonksiyonun gerçek parametrelerinin beklenen türde olup olmadığını kontrol etmez. Ancak Pycharm, gerçek ve biçimsel parametreler arasındaki tür tutarsızlıklarını bildirir. Bu tek neden bile tür bildirimlerini vazgeçilmez kılar.

Komut dosyası şu şekildedir:


# parametre türleri belirtilen bir işlev
# Bu yalnızca belgeleme amaçlıdır, çünkü Python yorumlayıcısı bunu dikkate almaz


def show(param: int) -> int:
    print(f"param={param}, type(param)={type(param)}")
    return param + 1


# main -------------------------
print(show(4))
show("xyz")

Notlar:

    1. satır: [param] formal parametresinin [int] türünde olduğu ve fonksiyonun sonucunun da [int] türünde olduğu belirtilir;
    1. satır: [show] işlevinin gerçek parametresinin türü doğrudur;
    1. satır: [show] işlevinin etkin parametresinin türü doğru değil;

Sonuçlar

C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_09.py
param=4, type(param)=<class 'int'>
5
param=xyz, type(param)=<class 'str'>
Traceback (most recent call last):
  File "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_09.py", line 11, in <module>
    show("xyz")
  File "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_09.py", line 6, in show
    return param + 1
TypeError: can only concatenate str (not "int") to str

Process finished with exit code 1
  • satır 10: [param] parametresinin türü [str]'tir. Bu mesaj görüntülendiğinde, [show] işlevinin koduna zaten girilmiş durumdadır. Dolayısıyla Python yorumlayıcısı, [show] işlevinin fiili parametresinin [str] türünde olmasını kabul etmiştir;
  • kodun 7. satırı, sonuçların 4-10. satırlarında görülen istisnaya neden oluyor;

Bununla birlikte, PyCharm bir anormallik olduğunu gösteriyor:

Image

[1]'te, PyCharm hatalı çağrıyı vurgulamıştır.

6.10. [fonc_10] komut dosyası: adlandırılmış parametreler

Bir fonksiyona parametre aktarmak için, fonksiyonun biçimsel parametrelerinin adlarını kullanabiliriz. Bu durumda, biçimsel parametrelerin sırasına uymak zorunda değiliz:


# etkin parametreleri biçimsel adlarıyla belirtilebilir
def f(x, y):
    return x + y


# main
print(f(y=10, x=3))

Notlar

    1. satır: f işlevinin x ve y olmak üzere iki biçimsel parametresi vardır;
    1. satır: f işlevi çağrılırken, biçimsel parametrelerin adları kullanılabilir. Bu uygulama en az iki durumda yararlı olabilir:
    2. fonksiyonun çok sayıda parametresi varsa ve bunların çoğunun varsayılan değeri varsa. Çağırma sırasında, yukarıdaki teknik, varsayılan değerini kullanmak istemediğimiz parametreleri başlangıçlandırmamızı sağlar;
    3. formel parametrelerin anlamlı isimleri varsa, fonksiyon çağrısında isimlendirilmiş parametrelerin kullanılması kodun okunabilirliğini artırır;

Sonuçlar

1
2
3
4
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_10.py
13

Process finished with exit code 0

6.11. [fonc_11] betiği: özyinelemeli işlev

[fonc_11] betiği, özyinelemeli (kendini çağıran) bir fonksiyon örneğidir:


# özyinelemeli işlev
def fact(i: int) -> int:
    # faktöriyel(1) değeri 1'dir
    # bir özyinelemeli fonksiyon bir noktada sona ermelidir
    if i == 1:
        return 1
    else:
        # faktöriyel(i)=i*faktöriyel(i-1)
        return i * fact(i - 1)


# ---------- main
print(f"fact(8)={fact(8)}")

Açıklamalar

  • 1-9. satırlar: faktöriyel fonksiyonu;
    1. satır: [factorielle] işlevi kendini çağırır;
  • 5-6. satırlar: özyinelemeli bir fonksiyon, bir koşul gerçekleştiğinde her zaman durmalıdır; aksi takdirde sonsuz özyineleme oluşur;

Sonuçlar

1
2
3
4
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_11.py
fact(8)=40320

Process finished with exit code 0

6.12. [fonc_12] betiği: özyinelemeli fonksiyon

[fonc_12] fonksiyonu, özyinelemenin işleyişi hakkında daha fazla ayrıntı verir:


# özyinelemeli fonksiyon
# j parametresinin davranışı


def fact(i: int, j: int) -> int:
    # rekürsif fonksiyonun sonlandırılması
    if i == 1:
        print(f"j={j}")
        return 1
    else:
        # j ile işlem yapılıyor
        j += 1
        print(f"avant fact j={j}")
        # rekürsiflik
        f = fact(i - 1, j)
        print(f"après fact j={j}")
        # sonuç
        return i * f


# ---------- main
print(f"fact(8)={fact(8, 0)}")

Yorumlar

    1. satır: Hala faktöriyel fonksiyonuyla ilgileniyoruz. Buna [j] parametresi eklenir;
    1. satır: j değişkeni her faktöriyel hesaplamasında düzenli olarak artırılır. Değişkenin özyineleme öncesindeki (12. satır) ve özyineleme sonrasındaki (16. satır) değerleri gösterilir (15. satır);

Sonuçlar

C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/fonctions/fonc_12.py
avant fact j=1
avant fact j=2
avant fact j=3
avant fact j=4
avant fact j=5
avant fact j=6
avant fact j=7
j=7
après fact j=7
après fact j=6
après fact j=5
après fact j=4
après fact j=3
après fact j=2
après fact j=1
fact(8)=40320

Process finished with exit code 0
  • satır 2-8: [j] değerinin, özyineleme durma koşuluna ulaşana kadar özyineleme devam ettiği sürece arttığı görülür. Bu andan itibaren, [fact] işlevine yapılan çağrıların dönüşü, çağrıların tersi yönde gerçekleşir;
  • satır 10-16: Bu çıktılar, faktöriyel çağrısının ardışık dönüşlerini yansıtmaktadır. [j] değişkeni, başlangıç değeri olan 1’e ulaşana kadar değerlerini geri kazanır;