Python (7. Bölüm)
Pardus-Linux.org | Wiki sitesinden
Forum'da bu konunun tartışma adresi: http://forum.pardus-linux.org/viewtopic.php?t=10478&highlight=
Konu başlıkları |
Modüller
Giriş
Modül, kabaca, fonksiyonları ve sabitleri (constants) içeren, istendiğinde başka programların içine davet edilebilen, .py uzantılı bir dosyadır. Modüller, yazacağımız programlara işlevsellik katmamızı sağlar.
Bu bölümde en önemli Python modüllerinden os modülünü inceleyerek, Python'da modüllerin nasıl kullanıldığını anlamaya çalışacağız.
Modül Çekme (importing Modules)
Python'da programımız içinde kullanacağımız modülleri birkaç farklı yöntemle çekebiliriz. Hemen kısaca bu yöntemleri görelim:
import modül_adı
Bu yöntemle bir modülü, bütün içeriğiyle birlikte çekebiliriz. Veya başka bir deyişle bir modülün içinde ne var ne yoksa programımız içine davet edebiliriz... Kimileri buna "import" etmek de diyor...
from modül_adı import *
Bu yöntemle bir modül içinde adı "__" ile başlayanlar hariç bütün fonksiyonları programımız içine çekebiliriz. Yani bu yöntem de tıpkı yukarıda anlatılan yöntemde olduğu gibi, bütün fonksiyonları alacaktır... Yalnız "__" ile başlayan fonksiyonlar hariç...
from modül_adı import falanca, filanca
Bu yöntem ise bir modülden "falanca" ve "filanca" adlı fonksiyonları çağırmamızı sağlayacaktır. Yani bütün içeriği değil, bizim istediğimiz fonksiyonları çekmekle yetinecektir.
Peki bu yöntemlerden hangisini kullanmak daha iyidir. Eğer ne yaptığınızdan tam olarak emin değilseniz veya o modülle ilgili bir belgede farklı bir yöntem kullanmanız önerilmiyorsa, anlatılan birinci yöntemi kullanmak her zaman daha güvenlidir (import modül_adı). Çünkü öbür yöntemler modül içeriğinin tamamını çekmediği için programınızda işlev kaybı yaşayabilirsiniz... Ama tabii ki hangi içeriği çekmeniz gerektiğinden eminseniz o başka...
Modüller hakkında genel bir bilgi edindiğimize göre artık önemli modüllerden os modülünü incelemeye başlayabiliriz:
os Modülü
Bu modül bize, kullanılan işletim sistemiyle ilgili işlemler yapma olacağı sunuyor. Modülün kendi belgelerinde belirtildiğine göre, bu modülü kullanan programların farklı işletim sistemleri üzerinde çalışma şansı daha fazla...
Bu modülü, yukarıda anlattığımız şekilde çekeceğiz:
import os
Eğer bu şekilde modülü "import" etmezsek, bu modülle ilgili kodlarımızı çalıştırmak istediğimizde Python bize bir hata mesajı gösterecektir.
Bu modülü programımız içine nasıl davet edeceğimizi öğrendiğimize göre, os modülü içindeki fonksiyonlardan söz edebiliriz. Öncelikle, isterseniz bu modül içinde neler var neler yok şöyle bir listeleyelim:
Python komut satırında ">>>" işaretinden hemen sonra
import os
komutuyla os modülünü alıyoruz. Daha sonra şu komutu veriyoruz:
dir(os)
İsterseniz daha anlaşılır bir çıktı elde edebilmek için bu komutu şu şekilde de verebilirsiniz:
for icerik in dir(os): print icerik
Gördüğünüz gibi, bu modül içinde bir yığın fonksiyon var! Şimdi biz bu fonksiyonlardan önemli olanlarını incelemeye çalışalım...
name fonksiyonu
Basit bir örnekle başlayalım:
#!/usr/bin/env python
#-*- coding:latin-1 -*-
import os
if os.name == "posix":
a = raw_input("Linus Torvalds'a mesajınızı yazın:")
print "Selam Linux kullanıcısı!"
if os.name == "nt":
a = raw_input("Bill Gates'e mesajınızı yazın:")
print "Selam Windows Kullanıcısı!"
Bu basit örnekte öncelikle "os" adlı modülü bütün içeriğiyle birlikte programımıza davet ettik... Daha sonra bu modül içindeki "name" fonksiyonunu kullanarak, kullanılan işletim sistemini sorguladık. Buna göre bu program çalıştırıldığında, eğer kullanılan işletim sistemi Linux ise, kullanıcıdan "Linus Torvalds'a mesajını yazması" istenecektir. Eğer kullanılan işletim sistemi Windows ise, "Bill Gates'e mesaj yazılması istenecektir... Python'da işletim sistemi isimleri için tanımlı olarak şu ifadeler bulunur:
Linux için "posix",
Windows için "nt", "dos", "ce"
Macintosh için "mac"
OS/2 için "os2"
Aynı komutları şu şekilde de yazabiliriz:
#!/usr/bin/env python
#-*- coding:latin-1 -*-
from os import name
if name == "posix":
a = raw_input("Linus Torvalds'a mesajınızı yazın:")
print "Selam Linux kullanıcısı!"
if name == "nt":
a = raw_input("Bill Gates'e mesajınızı yazın:")
print "Selam Windows Kullanıcısı!"
Dikkat ederseniz burada "from os import name" komutuyla, os modülü içindeki name fonksiyonunu çektik yalnızca. Ayrıca program içinde kullandığımız "os.name" ifadesini de "name" şekline dönüştürdük... Çünkü "from os import name" komutuyla yalnızca "name" fonksiyonunu çektiğimiz, aslında os modülünü çekmediğimiz için, "os.name" yapısını kullanırsak Python bize "os" isminin tanımlanmadığını söyleyecektir.
listdir fonksiyonu
Os modülü içinde yer alan bu fonksiyon bize bir dizin içindeki dosyaları veya klasörleri listeleme imkanı veriyor. Bunu şöyle kullanıyoruz:
import os
a = os.listdir("/home/")
print a
Yukarıdaki örnekte her zamanki gibi, modülümüzü "import os" komutuyla programımızın içine çektik ilk önce. Ardından kullanım kolaylığı açısından "os.listdir" fonksiyonunu "a" adlı bir değişkene bağladık. Örnekte os.listdir fonksiyonunun nasıl kullanıldığını görüyorsunuz. Örneğimizde /home dizini altındaki dosya ve klasörleri listeliyoruz. Burada parantez içinde tırnak işaretlerini ve yatık çizgileri nasıl kullandığımıza dikkat edin. En son da "print a" komutuyla /home dizininin içeriğini liste olarak ekrana yazdırıyoruz.
Çıktının tipinden anladığımız gibi, elimizde olan şey, öğeleri yan yana dizilmiş bir "liste". Eğer biz dizin içeriğinin böyle yan yana değil de alt alta dizildiğinde daha yakışıklı görüneceğini düşünüyorsak, kodlarımızı şu biçime sokabiliriz:
import os
a = os.listdir("/home/")
for dosyalar in a:
print dosyalar
Hatta eğer dosyalarımıza numara vererek listelemek istersek şöyle de yapabiliriz:
import os
a = os.listdir("/home/")
c = 0
for dosyalar in a:
if c < len(a):
c = c+1
print c, dosyalar
getcwd fonksiyonu
Os modülü içinde yer alan bu fonksiyon bize o anda hangi dizin içinde bulunduğumuza dair bilgi verir. İsterseniz bu fonksiyonun tam olarak ne işe yaradığını bir örnek üzerinde görelim. Bunun için, kolaylık açısından, hemen Python komut satırını açalım ve ">>>" işaretinden hemen sonra şu komutu yazalım:
import os
Bu komutu yazıp enter'e bastıktan sonra da şu komutu verelim:
os.getcwd()
Gördüğünüz gibi bu komut bize o anda hangi dizin içinde bulunduğumuzu söylüyor. Bu arada İngilizce bilenler için söyleyelim, buradaki "cwd"nin açılımı "current working directory". Yani kabaca "mevcut çalışma dizini"... Daha açık ifade etmek gerekirse: "O anda içinde bulunduğumuz dizin".
Şöyle bir örnek vererek konuyu biraz açalım:
#!/usr/bin/env python
#-*- coding:latin-1 -*-
import os
mevcut_dizin = os.getcwd()
if mevcut_dizin == "/home/istihza/Desktop":
for i in os.listdir(mevcut_dizin):
print i
else:
print "Bu program yalnızca /home/istihza/Desktop dizininin içeriğini gösterebilir!"
Yukarıdaki örnekte öncelikle os modülünü programımıza çektik. Daha sonra mevcut_dizin adında bir değişken yaratıp "os.getcwd" fonksiyonunun kendisini bu değişkenin değeri olarak atadık. Ardından, "eğer mevcut_dizin /home/istihza/Desktop ise bu dizin içindeki dosyaları bize listele ve sonucu ekrana yazdır, yok eğer mevcut_dizin /home/istihza/Desktop değil ise, bu program yalnızca /home/istihza/Desktop dizininin içeriğini gösterebilir, cümlesini göster" dedik. Burada dikkat ederseniz "if" ifadesinden sonra "for" döngüsünü kullandık... Bu işlemi, ekran çıktısı daha yakışıklı olsun diye yaptık... Eğer böyle bir kaygımız olmasaydı,
if mevcut_dizin == "/home/istihza/Desktop":
satırının hemen altına
print mevcut_dizin
yazıp işi bitirirdik...
Biz burada getcwd fonksiyonu için basit örnekler verdik, ama eminim siz yaratıcılığınızla çok daha farklı ve kullanışlı kodlar yazabilirsiniz...
Şimdi de os modülü içindeki başka bir fonksiyona değinelim.
chdir() fonksiyonu
Bu fonksiyon yardımıyla içinde bulunduğumuz dizini değiştirebiliriz. Diyelim ki o anda /usr/share/apps dizini içindeyiz. Eğer bir üst dizine, yani /usr/share/ dizinine geçmek istiyorsak, şu komutu verebiliriz:
import os os.chdir(os.pardir) print os.getcwd()
Buradaki "pardir" sabiti, İngilizce "parent directory" (bir üst dizin) ifadesinin kısaltması oluyor.
"pardir" sabiti dışında, bir de "curdir" sabiti vardır. Bu sabiti kullanarak "mevcut dizin" üzerinde işlemler yapabiliriz:
import os os.listdir(os.curdir)
Gördüğünüz gibi bu "curdir" sabiti "getcwd()" fonksiyonuna benziyor.
Bunun dışında, istersek gitmek istediğimiz dizini kendimiz elle de belirtebiliriz:
import os
os.chdir("/var/tmp")
mkdir() ve makedirs() fonksiyonları
Bu iki fonksiyon yardımıyla dizin veya dizinler oluşturacağız. Mesela:
import os
os.mkdir("/test")
Bu kod "/" dizini altında "test" adlı boş bir klasör oluşturacaktır...
Eğer bu kodu şu şekilde yazarsak, "mevcut çalışma dizini" içinde yeni bir dizin oluşacaktır:
import os
os.mkdir("test")
Yani, mesela "mevcut çalışma dizini" masaüstü ise bu "test" adlı dizin masaüstünde oluşacaktır... İsterseniz bu kodları şu şekle getirerek yeni oluşturulan dizinin nerede olduğunu da görebilirsiniz:
import os
print os.getcwd()
os.mkdir("test")
Bundan başka, eğer isterseniz mevcut bir dizin yapısı içinde başka bir dizin de oluşturabilirsiniz. Yani mesela "/home/kullanıcı_adınız/" dizini içinde "deneme" adlı boş bir dizin oluşturabilirsiniz:
import os
os.mkdir("/home/istihza/deneme")
Peki diyelim ki iç içe birkaç tane yeni klasör oluşturmak istiyoruz. Yani mesela "/home/kullanıcı_adınız" dizini altında yeni bir "Programlar" dizini, onun altında da "Python" adlı yeni başka bir dizin daha oluşturmak istiyoruz. Hemen deneyelim:
import os
os.mkdir("/home/istihza/Programlar/Python")
Ne oldu? Şöyle bir hata çıktısı elde ettik:
Traceback (most recent call last):
File "deneme.py", line 2, in ?
os.mkdir("/home/istihza/Programlar/Python")
OSError: [Errno 2] No such file or directory: '/home/istihza/Programlar/Python'
Demek ki bu şekilde çoklu dizin oluşturamıyoruz. İşte bu amaç için elimizde makedirs() fonksiyonu var. Hemen deneyelim yine:
import os
os.makedirs("/home/istihza/Programlar/Python")
Gördüğünüz gibi, /home/kullanıcı_adımız/ dizini altında yeni bir "Programlar" dizini ve onun altında da yeni bir "Python" dizini oluştu.
Buradan çıkan sonuç, demek ki mkdir() fonksiyonu bize yalnızca bir adet dizin oluşturma izni veriyor.. Eğer biz birden fazla, yani çoklu yeni dizin oluşturmak istiyorsak makedirs() fonksiyonunu kullanmamız gerekiyor.
Küçük bir örnek daha verip bu bahsi kapatalım:
import os
print os.getcwd()
os.makedirs("test/test1/test2/test3")
Tahmin ettiğiniz gibi bu kod "mevcut çalışma dizini" altında iç içe "test", "test1", "test2" ve "test3" adlı dizinler oluşturdu... Eğer "test" ifadesinin soluna "/" işaretini eklerseniz, bu boş dizinler "root" altında oluşacaktır...
rmdir() ve removedirs() fonksiyonları
Bu fonksiyonlar bize mevcut dizinleri silme olanağı tanıyor.. Yalnız, burada hemen bir uyarı yapalım: Bu fonksiyonları çok dikkatli kullanmamız gerekiyor... Ne yaptığınızdan, neyi sildiğinizden emin değilseniz bu fonksiyonları kullanmayın! Çünkü Python bu komutu verdiğinizde tek bir soru bile sormadan çatır çatır silecektir belirttiğiniz dizini... Böyle bir durumda, bir çift yaşlı gözle ekrana bakakalmak istemezsiniz, değil mi? Gerçi, bu komutlar yalnızca içi boş dizinleri silecektir, ama yine de benden uyarması!
Hemen bir örnek verelim. Diyelim ki "mevcut çalışma dizinimiz" olan masaüstünde "TEST" adlı boş bir dizin var ve biz bu dizini silmek istiyoruz:
import os
os.rmdir("TEST")
Böylece "TEST" dizini uçtu gitti... Haydi selametle!
Bu işlemin ardından hâlâ kendinizdeyseniz bir de şu örneğe bakın:
import os
os.rmdir("/home/istihza/TEST")
Bu kod ise /home/kullanıcı_adı dizini altındaki boş "TEST" dizinini uçuracaktır...
Tıpkı mkdir() ve makedirs() fonksiyonlarında olduğu gibi, iç içe birden fazla boş dizini silmek istediğimizde ise removedirs() fonksiyonundan yararlanıyoruz:
import os
os.removedirs("test1/test2")
Yine hatırlatmakta fayda var: Neyi sildiğinize mutlaka dikkat edin...
Python'da dizinleri nasıl yöneteceğimizi, nasıl dizin oluşturup sileceğimizi basitçe gördük. Şimdi de bu "dizinleri yönetme" işini biraz irdeleyelim.
Şimdiye kadar hep bir dizin, onun altında başka bir dizin, onun altında da başka bir dizini nasıl oluşturacağımızı çalıştık... Peki aynı dizin altında birden fazla dizin oluşturmak istersek ne yapacağız?
Bu işlemi çok kolay bir şekilde şöyle yapabiliriz:
import os
os.makedirs("test1/test2")
os.makedirs("test1/test3")
Bu kodlar "mevcut çalışma dizini" altında "test1" adlı bir dizin ile bunun altında "test2" ve "test3" adlı başka iki adet dizin daha oluşturacaktır.
Peki bu "test1", "test2" ve "test3" ifadelerinin sabit değil de değişken olmasını istersek ne yapacağız. Şöyle bir şey deneyelim:
import os test1 = "Belgelerim" test2 = "Hesaplamalar" test3 = "Resimler" os.makedirs(test1/test2) os.makedirs(test1/test3)
Bu kodları çalıştırdığımızda Python bize şöyle bir şey söyler:
Traceback (most recent call last):
File "deneme.py", line 4, in ?
os.makedirs(test1/test2)
TypeError: unsupported operand type(s) for /: 'str' and 'str'
Peki neden böyle oldu ve bu hata ne anlama geliyor?
Kod yazarken bazı durumlarda "/" işareti programcıları sıkıntıya sokabilir. Çünkü bu işaret Python'da hem "bölme" işleci hem de "dizin ayracı" olarak kullanılıyor... Biraz önce yazdığımız kodda Python bu işareti "dizin ayracı" olarak değil "bölme işleci" olarak algıladı ve sanki "test1" ifadesini "test2" ifadesine bölmek istiyormuşuz gibi bir muamele yaptı bize... Ayrıca kullandığımız "os.makedirs" fonksiyonunu da gördüğü için ne yapmaya çalıştığımızı anlayamadı ve kafası karıştı... Yani, "Arkadaşım, bir yandan dizin oluşturmaya çalışıyorsun, bir yandan da bölme yapmaya çalışıyorsun... Karar ver!" dedi bize Python... Peki bu meseleyi nasıl halledeceğiz?
Bu meseleyi halletmek için kullanmamız gereken başka bir fonksiyon var Python'da...
os.sep fonksiyonu
Bu fonksiyon, işletim sistemlerinin "dizin ayraçları" hakkında bize bilgi veriyor... Eğer yazdığımız bir programın farklı işletim sistemleri üzerinde çalışmasını istiyorsak bu fonksiyon epey işimize yarayacaktır... Çünkü her işletim sisteminin dizin ayracı birbiriyle aynı değil. Bunu şu örnekle gösterebiliriz:
Hemen bir Python komut satırı açıp şu komutları verelim:
>>>import os >>>os.sep '/'
Bu komutu Linux'ta verdiğimiz için komutun çıktısı "/" şeklinde oldu. Eğer aynı komutu Windows'ta verirsek sonuç şöyle olacaktır:
>>>import os >>>os.sep '\\'
Peki bu os.sep fonksiyonu ne işe yarar? Yazdığımız kodlarda doğrudan "dizin ayracı" vermek yerine bu fonksiyonu kullanırsak, programımızı farklı işletim sistemlerinde çalıştırırken, sistemin kendine özgü "dizin ayracı"nın kullanılmasını sağlamış oluruz... Yani mesela:
import os
os.makedirs("test/test2")
komutu yerine;
import os
os.makedirs("test" + os.sep + "test2")
komutunu kullanırsak programımızı farklı işletim sistemlerinde çalıştırırken herhangi bir aksaklık olmasını önlemiş oluruz. Çünkü burada os.sep ifadesi, ilgili işletim sistemi hangisiyle ona ait olan dizin ayracının otomatik olarak yerleştirilmesini sağlayacaktır...
Bu os.sep fonksiyonu ayrıca dizin adlarını "değişken" yapmak istediğimizde de bize yardımcı olacaktır.. Hatırlarsanız yukarıda şöyle bir kod yazmıştık:
import os test1 = "Belgelerim" test2 = "Hesaplamalar" test3 = "Resimler" os.makedirs(test1/test2) os.makedirs(test1/test3)
Yine hatırlarsanız bu kodu çalıştırdığımızda Python hata vermişti. Çünkü Python burada "/" işaretini bölme işleci olarak algılamıştı. İşte bu hatayı almamak için os.sep fonksiyonundan faydalanabiliriz. Şöyle ki:
import os test1 = "Belgelerim" test2 = "Hesaplamalar" test3 = "Resimler" os.makedirs(test1) os.makedirs(os.sep.join([test1,test2])) os.makedirs(os.sep.join([test1,test3]))
Dikkat ederseniz, burada os.sep fonksiyonuna bir de "join" diye bir ifade ekledik. Bu ifade kendisinden sonra gelecek dizin adlarının "birleştirilmesi" emrini veriyor... Bu fonksiyon sayesinde "/" işaretine hiç bulaşmadan, başımızı derde sokmadan işimizi halledebiliyoruz. Ayrıca burada parantez ve köşeli parantezlerin nasıl kullanıldığına da dikkat etmemiz gerekiyor...
Yukarıda "test1", "test2" ve "test3" değişkenlerinin adlarını doğrudan kod içinde verdik... Tabii eğer istersek raw_input fonksiyonuyla dizin adlarını kullanıcıya seçtirebileceğimiz gibi, şöyle bir şey de yapabiliriz:
import os def dizinler(test1,test2,test3): os.makedirs(test1) os.makedirs(os.sep.join([test1,test2])) os.makedirs(os.sep.join([test1,test3]))
Dikkat ederseniz, burada öncelikle os modülünü çağırıyoruz. Daha sonra "dizinler" adlı bir fonksiyon oluşturup parametre olarak "test1", "test2" ve "test3" adlı değişkenler belirliyoruz. Ardından "os.makedirs(test1)" komutuyla "test1" adlı bir dizin oluşturuyoruz. Tabii bu "test1" bir değişken olduğu için adını daha sonradan biz belirleyeceğiz. Alttaki satırda ise os.makedirs ve os.sep.join fonksiyonları yardımıyla, bir önceki satırda oluşturduğumuz "test1" adlı dizinin içinde "test2" adlı bir dizin daha oluşturuyoruz. Burada os.sep.join fonksiyonu "/" işaretiyle uğraşmadan dizinleri birleştirme imkanı sağlıyor bize... Hemen alttaki satırda da benzer bir işlem yapıp kodlarımızı bitiriyoruz.
Böylece bir fonksiyon tanımlamış olduk. Şimdi bu dosyayı "deneme" adıyla masaüstüne kaydedelim.. Böylelikle kendimize bir modül yapmış olduk. Şimdi Python komut satırını açalım ve şu komutları verelim:
>>>import deneme
>>>deneme.dizinler("Belgelerim", "Videolar", "Resimler")
Burada öncelikle "import deneme" satırıyla "deneme" adlı modülümüzü çağırdık. Daha sonra "deneme.dizinler..." satırıyla bu modül içindeki "dizinler" adlı fonksiyonu çağırdık... Böylelikle masaüstünde "Belgelerim" adlı bir klasörün içinde "Videolar" ve "Resimler" adlı iki klasör oluşturmuş olduk...
Bu os.sep.join ifadesi ile ilgili son bir şey daha söyleyip bu konuya bir nokta koyalım.
Şimdi Python komut satırını açarak şu kodları yazalım:
>>>import os >>>os.sep.join(["Dizin1", "Dizin2"])
Enter'e bastığımızda, bu komutların çıktısı şöyle olur:
'Dizin1/Dizin2'
Aynı kodları Windows üzerinde verirsek de şu çıktıyı alırız:
'Dizin1\\Dizin2'
Gördüğünüz gibi farklı platformlar üzerinde, os.sep fonksiyonunun çıktısı birbirinden farklı oluyor. Bu örnek, os.sep fonksiyonunun, yazdığımız programların "taşınabilirliği" (portability), yani "farklı işletim sistemleri üzerinde çalışabilme kabiliyeti" açısından ne kadar önemli olabileceğini gösteriyor...
Diğer Python Modülleri
Diğer modüller ve açıklamaları için Burada Bulabilirsiniz
Önceki Bölüm: Fonksiyonlar
Sonraki Bölüm: Dosya İşlemleri
Bu yazı Programlama bölümünün bir parçasıdır.
