7. Giriş ve Çıkış
- 7.1. Daha Güzel Çıkış Biçemi
- 7.2. Dosya Okuma ve Yazma
-
- 7.2.1. Dosya Nesnelerinin Yöntemleri
- 7.2.2.
pickle
Modülü
Bir yazılımın çıktısını sunmanın birkaç yolu vardır; veri yazdırılabilir ya da gelecekte kullanılabilecek şekilde bir dosyaya kaydedilebilir. Bu bölümde giriş ve çıkış ile ilgili olanakların bazılarına değineceğiz.
7.1. Daha Güzel Çıkış Biçemi
Buraya kadar değerleri yazdırmanın iki yolunu gördük: deyim ifadeleri ve
print deyimi. Üçüncü bir yol da dosya nesnelerinin write()
yöntemidir. Standart çıktıya sys.stdout
şeklinde atıfta
bulunulabilir.
Çoğu zaman boşluklar ile birbirinden ayrılmış değerlerden daha iyi
biçimlendirilimiş bir çıktıya ihtiyaç duyulur. Çıktınızı biçimlendirmenin
iki yolu var. İlki bütün dizge işlemlerini dilimleme ve birleştirme ile
yapıp istediğiniz herhangi bir biçimi elde etmek.
string
standart modülü dizgelerin istenen sütun
genişliğine kadar boşluklar ile doldurulmasını sağlayan, daha sonra
değineceğimiz, bazı faydalı işlevlere sahiptir. İkinci yol ise sol
bağımsız değişkeni bir dizge olan %
işlecini
kullanmaktır. %
işleci sol bağımsız değişkeni sağdaki
bağımsız değişkenine uygulanacak sprintf()
tarzı biçim dizgesi olarak yorumlar ve biçimleme işleminden sonra bir
dizge geri döndürür.
Sayısal değerleri dizgeye çevirmek için ise değer
repr()
veya str()
işlevine
geçirilebilir ya da ters tırnak işareti (``
)
içine alınabilir (repr()
ile aynı etkiye sahiptir).
str()
işlevi değerlerin insan tarafından okunabilir
gösterimini geri döndürürken, repr()
işlevi yorumlayıcı
tarafından okunabilir gösterimini geri döndürür (veya uygun sözdizim yok
ise SyntaxError
istisnası oluşturur). İnsan için anlam
ifade edecek bir gösterimi bulunmayan nesneler için
str()
işlevi repr()
ile aynı değeri
döndürür. Rakamlar, listeler ve sözlükler gibi yapılar ile daha pek çok
değer için her iki işlev de aynı sonucu verir. Dizgeler ve gerçel sayılar
ise iki farklı gösterime sahiptir.
İşte birkaç örnek:
>>>
s = 'Hello, world.'>>>
str(s) 'Hello, world.'>>>
`s` "'Hello, world.'">>>
str(0.1) '0.1'>>>
`0.1` '0.10000000000000001'>>>
x = 10 * 3.25>>>
y = 200 * 200>>>
s = 'The value of x is ' + `x` + ', and y is ' + `y` + '...'>>>
print s The value of x is 32.5, and y is 40000...>>>
# Ters tırnaklar sayılar dışındaki tipler ile de çalışır:...
p = [x, y]>>>
ps = repr(p)>>>
ps '[32.5, 40000]'>>>
# Karakter dizisinde ise tırnaklar ve ters bölü işareti eklenir:...
hello = 'hello, world\n'>>>
hellos = `hello`>>>
print hellos 'hello, world\n'>>>
# Ters tırnakların bağımsız değişkeni bir demet de olabilir:...
`x, y, ('spam', 'eggs')` "(32.5, 40000, ('spam', 'eggs'))"
Sayıların kare ve küplerinden oluşan bir tablo yazdırmanın iki yolu vardır:
>>>
import string>>>
for x in range(1, 11):...
print string.rjust(`x`, 2), string.rjust(`x*x`, 3),...
# Üst satırın sonundaki virgüle dikkat edin....
print string.rjust(`x*x*x`, 4)...
1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000>>>
for x in range(1,11):...
print '%2d %3d %4d' % (x, x*x, x*x*x)...
1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 6 36 216 7 49 343 8 64 512 9 81 729 10 100 1000
Sütunların arasındaki bir karakterlik boşluk print
tarafından eklenir; bağımsız değişkenlerin arasına daima bir boşluk
karakteri eklenir.
Bu örnek dizgelerin başını boşluklar ile doldurup bunları sağ tarafa
dayayan string.rjust()
işlevini kullanmaktadır.
Buna benzer string.ljust()
ve
string.center()
işlevleri de vardır. Bunlar bir şey
yazdırmaz; sadece yeni bir dizge geri döndürür. Verilen
dizge uzun ise kırpılmaz ve aynen geri döndürülür; bu
sütunlarınızın bozulmasına sebep olmasına rağmen hatalı bir değer
göstermekten iyidir. Büyük bir değeri kırpmayı gerçekten istiyorsanız
dilimleme ile bunu yapabilirsiniz
(string.ljust(x, n)[0:n]
gibi).
string.zfill()
işlevi ise rakamlar içeren dizgelerin
başını sıfırlar ile doldurur. Bu işlev artı ve eksi işaretlerini de
dikkate alır:
>>>
import string>>>
string.zfill('12', 5) '00012'>>>
string.zfill('-3.14', 7) '-003.14'>>>
string.zfill('3.14159265359', 5) '3.14159265359'
%
işleçi şu şekilde kullanılır:
>>>
import math>>>
print 'PI sayısının yaklaşık değeri: %5.3f' % math.pi PI sayısının yaklaşık değeri: 3.142
Dizgenin içinde birden fazla biçem varsa sağ terim olarak bir demet kullanmak gerekir:
>>>
table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}>>>
for name, phone in table.items():...
print '%-10s ==> %10d' % (name, phone)...
Jack ==> 4098 Dcab ==> 7678 Sjoerd ==> 4127
Çoğu biçim aynı C dilindeki gibi çalışır ve doğru veri türünün
geçirilmesi gerekir; bu yapılamaz ise bir istisna oluşur.
%s
biçiminin kullanımı daha rahattır; verilen
bağımsız değişken dizge değilse yerleşik işlev str()
ile
dizgeye dönüştürülür. Genişlik ya da hassasiyeti belirtmek için
*
ile bir tamsayı bağımsız değişken kullanılabilir. C dilindeki
%n
ve %p
biçimler ise
desteklenmemektedir.
Eğer bölmek istemediğiniz gerçekten uzun bir biçim dizgeniz varsa
biçimlendirmek istediğiniz bağımsız değişkenlere konumu yerine ismiyle atıfta
bulunabilmeniz güzel olur. Bu aşağıda gösterildiği gibi
%(isim)biçim
şeklinde yapılabilir:
>>>
table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}>>>
print 'Jack: %(Jack)d; Sjoerd: %(Sjoerd)d; Dcab: %(Dcab)d' % table Jack: 4098; Sjoerd: 4127; Dcab: 8637678
Bu özellik bütün yerel değişkenlerin bulunduğu bir sözlük geri döndüren
yerleşik işlev vars()
ile beraber kullanıldığında
faydalı olur.
7.2. Dosya Okuma ve Yazma
open()
işlevi bir dosya nesnesi geri döndürür ve
genellikle iki bağımsız değişken ile kullanılır: open(dosya_adı, kip)
>>>
f=open('/tmp/workfile', 'w')>>>
print f <open file '/tmp/workfile', mode 'w' at 80a0960>
İlk bağımsız değişken dosya adını içeren bir dizgedir. İkincisi ise
dosyanın nasıl kullanılacağını belirten karakterlerden oluşur. Erişim kipi
dosyadan sadece okuma yapılacak ise 'r'
, sadece yazma
için 'w'
(aynı isimli bir dosya zaten var ise üzerine
yazılır) ve dosyanın sonuna eklemeler yapmak için 'a'
olur. 'r+'
kipi dosyayı hem okuma hem de yazma yapmak
için açar. kip
bağımsız değişkeni seçimliktir; kullanılamaması halinde 'r'
olduğu varsayılır.
Windows ve Macintosh üzerinde kipe eklenen 'b'
harfi
dosyayı ikilik kipte açar; yani 'rb'
,
'wb'
ve 'r+b'
gibi kipler de vardır.
Windows metin ve ikilik dosyaları arasında ayrım yapmaktadır; metin
dosyalarında okuma veya yazma işlemlerinde satır sonu karakterleri
otomatik olarak biraz değişir. Bu görünmez değişiklik ASCII metin
dosyaları için iyidir; anacak JPEG resimler veya .EXE dosyalar gibi iklik
verileri bozar.
7.2.1. Dosya Nesnelerinin Yöntemleri
Bundan sonraki örneklerde f
adlı bir dosya nesnesinin
önceden oluşturulmuş olduğunu varsayacağız.
Dosyanın içeriğini okumak için belirli miktarda veriyi okuyup bunu
dizge olarak geri döndüren f.read(boy)
yöntemi
kullanılabilir. boy
okunacak bayt sayısını
belirleyen seçimlik bir bağımsız değişkendir; kullanılmaması halinde dosyanın
tamamı okunur. Dosyanın sonuna gelindiğinde f.read()
boş bir dizge ("") geri döndürür.
>>>
f.read() 'Dosyanın tamamı bu satırdan oluşuyor.\n'>>>
f.read() ''
f.readline()
dosyadan tek bir satır okur. Satırın
sonundaki satırsonu karakteri (\n
) korunur; ancak
dosya bir satırsonu karakteri ile bitmiyor ise son satırda bu karakter
silinir. Bu özellik geri döndürülen değerin birden fazla anlama gelmesini
engeller; f.readline()
boş bir dizge geri
döndürdüğünde dosyanın sonuna ulaşılırken boş bir satır tek bir
'\n'
karakteri ile ifade edilir.
>>>
f.readline() 'Bu dosyanın ilk satırı.\n'>>>
f.readline() 'Dosyanın ikinci satırı\n'>>>
f.readline() ''
f.readlines()
dosya içindeki bütün satırların
bulunduğu bir liste geri döndürür. Seçimlik bağımsız değişken
boy_ipucu
kullanılması durumunda ise dosyadan
boy_ipucu
kadar ve bundan bir satır tamamlamaya
yetecek kadar fazla bayt okunur ve bunlar yine satırlar listesi
şeklinde geri döndürülür.
>>>
f.readlines()
['Bu dosyanın ilk satırı.\n', 'Dosyanın ikinci satırı\n']
f.write(dizge)
yöntemi dizge
içeriğini dosyaya yazar ve None
geri döndürür.
>>>
f.write('Bu bir deneme satırıdır.\n')
f.tell()
dosya nesnesinin dosya içindeki konumunu
belirten bir tamsayı geri döndürür (dosyanın başından bayt cinsinden
ölçülür). f.seek(uzaklık, nereden)
ile de dosyanın
içinde istenen konuma gidilebilir. Konum, uzaklık
ile başvuru noktası nereden
değerlerinin toplanması
ile bulunur. nereden
0 olursa dosyanın başını,
1 o andaki konumu, 2 ise dosyanın sonunu belirtir. nereden
kullanılmaz ise 0 olduğu varsayılır ve başvuru noktası olarak dosyanın
başı alınır.
>>>
f=open('/tmp/workfile', 'r+')>>>
f.write('0123456789abcdef')>>>
f.seek(5) # Dosyadaki 5'inci bayta git>>>
f.read(1) '5'>>>
f.seek(-3, 2) # Sondan 3'üncü bayta git>>>
f.read(1) 'd'
Dosya ile işiniz bittiğinde f.close()
yöntemini
çağırarak dosyayı kapatabilir ve dosyanın işgal ettiği sistem
kaynaklarını serbest bırakabilirsiziz. f.close()
çağrıldıktan sonra dosya üzerinde başka işlem yapmaya devam etmek
mümkün değildir:
>>>
f.close()>>>
f.read() Traceback (most recent call last): File "<stdin>", line 1, in ? ValueError: I/O operation on closed file
Dosya nesnelerinin isatty()
ve
truncate()
gibi pek sık kullanılmayan başka
yöntemleri de vardır.
7.2.2. pickle
Modülü
Dizgeler kolayca dosyalara yazılıp dosyalardan okunabilir. Sayılar
biraz zahmetlidir; çünkü read()
yöntemi sadece
dizgeleri geri döndürür ve bunların '123' gibi bir değeri alıp sayısal
değeri 123'ü geri döndüren string.atoi()
işlevinden
geçirilmeleri gerekir. Listeler, sözlükler ve sınıf örnekleri gibi daha
karmaşık veri türlerini dosyalara kaydetmek isterseniz işler oldukça
zorlaşır.
Yazılımcıları karmaşık veri türlerini saklamak için kodlamak ve hata
ayıklamak ile uğraştırmak yerine Python bu iş için pickle
adlı standart modülü sağlar. Bu hayret verici modül neredeyse herhangi
bir Python nesnesini (bazı Python kodu biçimlerini bile!) dizge ile ifade
edilebilecek hale getirebilir ve bu halinden geri alabilir. Bu dönüşüm ve
geri kazanım işlemleri arasında nesne bir dosyaya kaydedilebilir ya da ağ
bağlantısı ile uzaktaki başka bir makineye gönderilebilir.
x
gibi bir nesneniz ve yazma işlemi için açılmış
f
gibi bir dosya nesneniz varsa bu nesneyi dosyaya
aktarmanız için tek satırlık kod yeterli olur:
pickle.dump(x, f)
Nesneyi geri almak için ise f
okumak için açılmış
bir dosya nesnesi olsun:
x = pickle.load(f)
Birden fazla nesnenin dönüştürülmesi gerekiyor ya da dönüştürülmüş
olan nesnelerin dosyaya yazılması istenmiyor ise pickle
farklı şekilde kullanılır. Bunları pickle
modülünün
belgelerinden öğrenmek mümkündür.
pickle
modülü saklanabilen ve başka yazılımlar
tarafından ya da aynı yazılımın farklı çalışma zamanlarında
kullanılabilecek Python nesneleri yapmanın standart yoludur.
pickle
modülü çok yaygın kullanıldığından Python
genişletme modülleri yazan çoğu yazılımcı matrisler gibi yeni veri
türlerinin doğru olarak dönüştürülebilir ve geri alınabilir olmasına
özen gösterir.