3.3. Python'da Modüller

Kayıt Tarihi:

Özet:

Önceki derslerde kendi fonksiyonlarınızı nasıl tanımlayabileceğinizi öğrendiniz, bu derste de fonksiyonlarınızdan modül oluşturmayı öğreneceksiniz. Böylece fonksiyonlarınıza başka programlar içinden de ulaşabilirsiniz.

Anahtar Kelimeler: __main__ · __name__ · dir · import · modül

Bazen bir programımızda tanımladığımız bir fonksiyonu başka bir programda tekrar kullanmak isteyebiliriz. Bunun en basit yolu fonksiyonun kodlarını kopyalayıp yeni programımıza yapıştırmak gibi gelebilir size ama bu kötü bir fikirdir. Bu fonksiyonu bir çok programda kullandığınızı varsayın, daha sonra bu fonksiyonu geliştirmek ya da fonksiyonun bir hatasını gidermek istediğimiz zaman her yerde fonksiyonun kodlarını değiştirmeniz gerekir. Programcılığın en temel kurallarından birine göre bir kodun elimizde tek bir versiyonu bulunmalıdır. Bunun için kullanacağımız fonksiyonları adına modül denilen dosyalarda saklayıp daha sonra ihtiyaç duyduğumuz programlar içinde bu fonksiyonu import etmeliyiz. Örneğin math modülü içindeki factorial() fonksiyonuna ne zaman ihtiyaç duysak from math import factorial biçiminde erişebiliriz.

Kullanıcı Tanımlı Modüller

Pythonda modül oluşturmak oldukça kolaydır, fonksiyonları modul.py gibi .py uzantılı bir dosyaya kaydederiz ve o dosya artık bir modüldür. Bundan sonra o dosyadaki fonksiyonlara istediğimiz zaman from modul import fonksiyon şeklinde erişebiliriz. Dikkat etmemiz gereken tek bir şey var aslında, kaydettiğimiz modül dosyasyı çalıştığımız programla aynı klasörde olmalıdır.

Örnek olarak Celsius, Kelvin ve Fahrenheit sıcaklık birimleri arasında dönüşüm yapan altı adet C2F, F2C, C2K, K2C, F2K ve K2F fonksiyonlarını tanımlayalım. Bu dönüşüm formülleri aşağıdaki kodlarda verildiği gibidir.


def C2F(C):
    return (9.0/5)*C + 32

def F2C(F):
    return (5.0/9)*(F - 32)

def K2C(K):
    return K - 273

def C2K(C):
    return C + 273

def F2K(F):
    return (5.0/9)*(F - 32) + 273

def K2F(K):
    return (9.0/5)*(K - 273) + 32

Bu kodları donusum1.py olarak kaydederek bir modul oluşturalım. Daha sonra bir interaktif Python oturumunda buradaki fonksiyonlara erişim sağlayalım. Eğer modülden bir veya bir kaç fonksiyona erişmek istiyorsak bunu aşağıdaki gibi yaparız.


Terminal > python
Python 2.7.13 (default, Apr  4 2017, 08:46:44)
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.42.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
>>> from donusum1 import C2F, F2K
>>> C2F(35)
95.0
>>> F2K(10)
260.77777777777777

Bir program içinde kullanılabilir olan fonksiyon ve değişkenlerin listesini dir() komutu ile görebiliriz. Modül içindeki tim fonksiyonları programımıza alıp bunu deneyelim.


>>> from donusum1 import *
>>> dir()
['C2F', 'C2K', 'F2C', 'F2K', 'K2C', 'K2F', '__builtins__', '__doc__',
'__name__', '__package__']

Dikkat edilirse tanımladığımız altı fonksiyon dışında bizim oluştumadığımız değişkenler de var programımızda. Bunlar her programda standart olan değişkenlerdir, karşılaştıkça bunları açıklayacağız.

Ana Program Olarak Modüller

Modül içerisinde tanımladığımız fonksiyonları sadece başka programlarda kullanmak yerine, doğrudan bu dosyayı da bir program olarak kullanmak isteyebiliriz. Aşağıdaki örneği dikkatlice inceleyip çalışma mantığını anlayın.


def C2F(C):
    return (9.0/5)*C + 32

def F2C(F):
    return (5.0/9)*(F - 32)

def K2C(K):
    return K - 273

def C2K(C):
    return C + 273

def F2K(F):
    return (5.0/9)*(F - 32) + 273

def K2F(K):
    return (9.0/5)*(K - 273) + 32

import sys
bilgi = "Kullanim ornek: python %s C 21 F" % sys.argv[0]

if len(sys.argv) == 1:
    print bilgi
elif len(sys.argv) == 4:
    s = "%s2%s(%s)" % (sys.argv[1], sys.argv[3], sys.argv[2])
    exec("y = %s" % s)
    print "%s%s=%g%s" % (sys.argv[2], sys.argv[1], y, sys.argv[3])
else:
    print "Hatali giris.."

Bu programın çıktısı aşağıdaki gibi olacaktır.


Terminal > python donusum2.py
Kullanim ornek: python donusum2.py C 21 F

Terminal >  python donusum2.py C 21 F
21C=69.8F

Bu dosyayı bir program olarak çalıştırınca bir sıkıntı yok ama bunu başka program içinde import edersek dikkat etmemiz gereken bir husus var. Bir modülü programımıza bütünüyle import ettiğimizde modül dosyası baştan sona kadar çalıştırılır. Ama biz sadece modülün içinde tanımlanan fonksiyonlar gerekli, onun dışındaki kodları (ekrana yazdırma yapan veya hesaplama yapan) çalıştırmak istemeyiz.


>>> import donusum2
Kullanim ornek: python  C 21 F
>>> 
>>> dir(donusum2)
['C2F', 'C2K', 'F2C', 'F2K', 'K2C', 'K2F', '__builtins__', '__doc__',
'__file__', '__name__', '__package__', 'bilgi', 'sys']

Gördüğünüz gibi modülü import eder etmez ana fonksiyon gibi çalışıp ekrana bazı çıktılar gösterdi. Ayrıca bilgi ve sys gibi programımıza import etmek istemediğimiz fazladan değişkenler geldi. Bunların yerine sadece fonksiyon tanımlarının programımıza aktarılmasını, diğer kalan kodların ihmal edilmesini sağlayabiliriz. Bunun için modülümüzde fonksiyon tanımları dışında kalan, sadece ana program olarak çalışınca kullanılacak olan kısmı test bloğu denilen bir blok içinde yazarız. Bu blok içindeki kodlar sadece dosya ana program olarak çalıştırıldığında dikkate alınır. Test bloğunu oluşturmak için programda standart olarak tanımlı olan __name__ değişkenini kullanırız. Dosya ana program olarak çalıştırılırsa bu değişkenin değeri __main__'dir. Dolayısıyla fonksiyon tanımı dışındaki kodları __name__=="__main__" koşulu altında verebiliriz.


def C2F(C):
    return (9.0/5)*C + 32

def F2C(F):
    return (5.0/9)*(F - 32)

def K2C(K):
    return K - 273

def C2K(C):
    return C + 273

def F2K(F):
    return (5.0/9)*(F - 32) + 273

def K2F(K):
    return (9.0/5)*(K - 273) + 32

if __name__ == "__main__":
    import sys
    bilgi = "Kullanim ornek: python %s C 21 F" % sys.argv[0]
    if len(sys.argv) == 1:
        print bilgi
    elif len(sys.argv) == 4:
        s = "%s2%s(%s)" % (sys.argv[1], sys.argv[3], sys.argv[2])
        exec("y = %s" % s)
        print "%s%s=%g%s" % (sys.argv[2], sys.argv[1], y, sys.argv[3])
    else:
        print "Hatali giris.."

Bu modülü kullanırsak aşağıdaki gibi bir sonuç alırız. Fark edeceğiniz gibi fonksiyon tanımları dışında hiç bir şeyi programımıza almamış oluyoruz.


>>> import donusum3
>>> dir(donusum3)
['C2F', 'C2K', 'F2C', 'F2K', 'K2C', 'K2F', '__builtins__', '__doc__',
'__file__', '__name__', '__package__']