sys Modülü¶
Python’daki en önemli modüllerden biri os ise, öbürü de sys adlı modüldür. Bu modüller o kadar önemlidir ki, Python’daki hiç bir modülü bilmeseniz de bu iki modülü bilmeniz gerekir. os modülünü, “Modüller” konusunu işlerken anlatmıştık. Şimdi de sys modülünü inceleyeceğiz.
sys modülü, Python sistemine ilişkin fonksiyonlar ve nitelikler barındırır. Bu modülü kullanarak, elinizdeki Python sürümünü yönetebilirsiniz. Bunun tam olarak ne demek olduğunu biraz sonra gayet net bir şekilde anlayacaksınız.
“Modüller” konusunu anlatırken, modüllerin aslında .py uzantılı birer Python programı olduğunu söylemiştik. Mesela daha önce incelediğimiz os modülü, bilgisayarımızda bulunan os.py adlı bir dosyaydı. Python’daki hemen hemen bütün modüller böyledir. Yani hemen hemen bütün Python modülleri birer .py dosyası olarak sistemimizde bulunur. Ancak bu durumun bazı istisnaları da vardır. Örneğin sys modülü bu istisnalardan biridir. Bu modül, öteki pek çok modülün aksine Python programlama dili ile değil C programlama dili ile yazılmıştır. Dolayısıyla bu modülün Python kodları yoktur. Bu modülün C kodlarını görmek için http://svn.python.org/projects/python/branches/release26-maint/Python/sysmodule.c adresini ziyaret edebilirsiniz.
sys Modülünün İçeriği¶
Her zaman olduğu gibi, sys modülünün içinde ne olduğunu görmek için dir() fonksiyonundan yararlanabilirsiniz:
>>> dir(sys)
['__displayhook__', '__doc__', '__egginsert', '__excepthook__',
'__name__', '__package__', '__plen', '__stderr__', '__stdin__',
'__stdout__', '_clear_type_cache', '_current_frames', '_getframe',
'api_version', 'argv', 'builtin_module_names', 'byteorder',
'call_tracing', 'callstats', 'copyright', 'displayhook',
'dont_write_bytecode', 'exc_clear', 'exc_info', 'exc_type',
'excepthook', 'exec_prefix', 'executable', 'exit', 'flags',
'float_info', 'getcheckinterval', 'getdefaultencoding',
'getdlopenflags', 'getfilesystemencoding', 'getprofile',
'getrecursionlimit', 'getrefcount', 'getsizeof', 'gettrace',
'hexversion', 'maxint', 'maxsize', 'maxunicode', 'meta_path',
'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform',
'prefix', 'ps1', 'ps2', 'py3kwarning', 'pydebug', 'setcheckinterval',
'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace',
'stderr', 'stdin', 'stdout', 'subversion', 'version',
'version_info', 'warnoptions']
Gördüğünüz gibi sys modülü içinde epey fonksiyon ve nitelik var. Biz bu fonksiyon ve nitelikler arasından en önemlilerini incelemeye çalışacağız. Bu bölümde şu fonksiyon ve nitelikleri inceleyeceğiz:
- argv
- exit
- getdefaultencoding
- path
- platform
- stdout
- version_info
O halde ilk niteliğimizle başlayalım...
argv Niteliği¶
Bu nitelik sys modülünün en bilinen ve en sık kullanılan niteliğidir. Dolayısıyla bu niteliği öğrenirken bu niteliğe özel önem ve ilgi göstermenizi öneririm.
Etrafta şöyle programları sıkça görmüş olmalısınız: Komut satırında programın adı ile birlikte birtakım seçenekler de belirtirsiniz ve ilgili program o belirttiğiniz seçeneklere göre programı işletir. Mesela elimizde “muzikcalar” adlı bir program olduğunu varsayalım. Amacı müzik çalmak olan program mesela şöyle kullanılıyor olabilir:
muzikcalar sarki_adi.mp3
Bu komutla “sarki_adi.mp3” adlı şarkıyı çalabiliriz... Böyle bir programı Python’da yazmak için argv niteliğinden yararlanabiliriz. Şimdi şu kodlara bakın:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
def sarkiyi_cal():
if os.name == "nt":
os.startfile(sys.argv[1])
elif os.name == "posix":
os.system("xdg-open %s" %sys.argv[1])
if len(sys.argv) < 2:
print "Çalınacak şarkı adını belirtmediniz!"
elif len(sys.argv) > 2:
print "Birden fazla dosya adı belirttiniz!"
else:
sarkiyi_cal()
Gelin isterseniz bu kodları açıklamaya başlamadan önce, argv niteliğinin tam olarak nasıl bir işe yaradığını anlamak için şöyle bir şey yazalım:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
print sys.argv
Şimdi bu programı argv_testi.py adıyla kaydedin ve programı python argv_testi.py komutuyla çalıştırın. Bu programı çalıştırdığınızda şöyle bir çıktı alacaksınız:
istihza@istihza:~/Desktop$ python argv_testi.py
['argv_testi.py']
Gördüğünüz gibi sys modülünün argv niteliği aslında basit bir listeden ibarettir. Bu listenin ilk öğesi de yazdığımız programın adıdır (argv_testi.py). argv niteliği bir liste olduğu için listelerle yapabildiğiniz her şeyi bu nitelikle de yapabilirsiniz.
Şimdi aynı programı şu şekilde çalıştırın:
istihza@istihza:~/Desktop$ python argv_testi.py falanca filanca
Bu defa şöyle bir çıktı alacağız:
['argv_testi.py', 'falanca', 'filanca']
Gördüğünüz gibi, yazdığınız programa eklediğiniz her seçenek argv listesine sırayla ekleniyor.
argv listesinin ilk öğesi her zaman programınızın adıdır. Dolayısıyla eğer argv listesinin uzunluğu 2’den azsa, programınız herhangi bir seçenek belirtilmeden, sadece ismi belirtilerek çalıştırılmış demektir. Bu bilgiyi kullanarak şöyle bir program yazabilirsiniz:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
if len(sys.argv) < 2:
print "Herhangi bir seçenek belirtmediniz!"
elif len(sys.argv) >= 2:
print "Programı şu seçeneklerle birlikte çalıştırdınız: "
for i in sys.argv[1:]:
print i
Dediğimiz gibi, eğer argv niteliğinin gösterdiği listenin uzunluğu 2’den azsa kullanıcı hiç bir seçenek belirtmemiş demektir (if len(sys.argv) < 2:).
Ama eğer argv niteliğin gösterdiği listenin uzunluğu 2 veya daha fazla ise kullanıcımız programı çalıştırırken bazı seçenekler belirtmiş demektir (elif len(sys.argv) >= 2:). Bu seçenekleri argv listesinin ilk öğesi dışındaki bütün öğelerini ekrana yazdırarak görebilirsiniz:
for i in sys.argv[1:]:
print i
İlk öğeyi ekrana yazdırmaya gerek yok. Çünkü bildiğiniz gibi, ilk öğe her zaman programımızın adını gösteriyor...
Bütün bu açıklamalardan sonra, ilk başta yazdığımız programı anlamak çok daha kolay bir hal almış olmalı. Programımızı tekrar görelim:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
def sarkiyi_cal():
if os.name == "nt":
os.startfile(sys.argv[1])
elif os.name == "posix":
os.system("xdg-open %s" %sys.argv[1])
if len(sys.argv) < 2:
print "Çalınacak şarkı adını belirtmediniz!"
elif len(sys.argv) > 2:
print "Birden fazla dosya adı belirttiniz!"
else:
sarkiyi_cal()
Burada öncelikle sys ve os modüllerini içe aktarıyoruz. Çünkü programımız içinde bu iki modüle ait nitelik ve fonksiyonlardan yararlanacağız.
Ardından sarkiyi_cal() adlı bir fonksiyon yazdık. Eğer kullanılan işletim sistemi Windows ise argv listesinin birinci öğesini, yani kullanıcının program adından sonra yazdığı ilk seçeneği, os modülünün startfile() fonksiyonunu kullanarak çalıştırıyoruz. Eğer kullanılan işletim sistemi GNU/Linux ise, os modülünün system() fonksiyonunu kullanarak yine argv listesinin ilk öğesini çalıştırıyoruz.
Elbette kullanıcının program adından sonra hiç bir seçenek belirtmeme veya 2’den fazla seçenek belirtme ihtimali de var. İşte bu ihtimallere karşı şu kodları yazıyoruz:
if len(sys.argv) < 2:
print "Çalınacak şarkı adını belirtmediniz!"
elif len(sys.argv) > 2:
print "Birden fazla dosya adı belirttiniz!"
Eğer kullanıcımız program adının yanına sadece 1 adet seçenek eklerse, o zaman sarkiyi_cal() adlı fonksiyonu devreye sokuyoruz. Peki size bir soru: Bu haliyle programımız müzik dosyası veya başka bir tür dosya diye bir ayrımda bulunmaksızın bütün dosyaları, sistemde o türdeki dosyayı açan öntanımlı uygulamayla çalıştıracaktır. Acaba biz bu programda kullanıcının girdiği dosya adlarının müzik dosyası olup olmadığını nasıl denetler ve programımızı sadece müzik dosyalarını çalıştıracak hale getirebiliriz?
argv niteliği başka pek çok faydalı iş için kullanılabilecek harika bir araçtır. Mesela şu programa bir bakın:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
surum = "0.2"
yardim = """
"FALANCA programının %s sürümünü kullanıyorsunuz.
Bu programı kullanabilmek için sisteminizde Python
dışında filanca adlı modülün de kurulu olması gerekiyor.
Programı komut satırından python falanca.py komutuyla
çalıştırabilirsiniz. İyi eğlenceler!""" % surum
if len(sys.argv) < 2:
print "..."
elif sys.argv[1] == "-v":
print surum
elif sys.argv[1] == "-h":
print yardim
else:
print "Böyle bir seçenek yok!"
Gördüğünüz gibi bu programda kullanıcılarımıza programın sürümünü ve yardım dosyasını görüntüleme imkanı veriyoruz. Eğer kullanıcımız şu komutu verirse kullandığı programın sürümünü öğrenebilir:
python falanca.py -v
Ya da eğer şu komutu verirse programın yardım dosyasına ulaşabilir:
python falanca.py -h
Eğer kullanıcı “-v” ve “-h” dışında başka bir şey yazarsa programımız kendisini böyle bir seçenek olmadığı konusunda uyaracaktır.
exit() Fonksiyonu¶
sys modülünün içindeki fonksiyonlardan biri de exit() fonksiyonudur. Aslında siz bu fonksiyonu daha önce de görmüştünüz. Hatırlarsanız ilk derslerimizin birinde bu fonksiyonun Python’un etkileşimli kabuğundan çıkmak için kullanıldığını söylemiştik. Mesela yukarıda yazdığımız programda bu fonksiyonu kullanmak istersek şöyle bir şey yazabiliriz:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
surum = "0.2"
yardim = """
"FALANCA programının %s sürümünü kullanıyorsunuz.
Bu programı kullanabilmek için sisteminizde Python
dışında filanca adlı modülün de kurulu olması gerekiyor.
Programı komut satırından python falanca.py komutuyla
çalıştırabilirsiniz. İyi eğlenceler!""" % surum
if len(sys.argv) < 2:
sys.exit()
elif sys.argv[1] == "-v":
print surum
elif sys.argv[1] == "-h":
print yardim
else:
print "Böyle bir seçenek yok!"
Böylece eğer argv listesinin uzunluğu 2’den azsa programımız kapanacaktır.
Bu fonksiyonun çok fazla bir özelliği yoktur. Gördüğünüz gibi exit() fonksiyonunu programdan çıkmak için kullanıyoruz.
getdefaultencoding() Fonksiyonu¶
Bildiğiniz gibi, yazdığımız bir programda Türkçe karakterler kullanabilmemiz için programımızın en başına şuna benzer bir satır eklememiz gerekiyor:
# -*- coding: utf-8 -*-
Böylece Python’a, program içinde kullanacağımız kodlama biçiminin “utf-8” olacağını bildirmiş oluyoruz. Eğer bu satırı yazmazsak Python otomatik olarak “ascii” adlı bir kodlama biçimini kullanacaktır.
Not
“utf-8”, “ascii” ve unicode konularında ayrıntılı bilgi edinmek için “ascii, unicode ve Python” başlıklı konuyu inceleyebilirsiniz.
Python’un öntanımlı kodlama biçiminin ne olduğunu öğrenmek için getdefaultencoding() adlı fonksiyondan yararlanabilirsiniz:
>>> sys.getdefaultencoding()
'ascii'
Gördüğünüz gibi Python öntanımlı olarak ‘ascii’ adlı kodlama biçimini kullanıyor. Python’da yaşadığımız pek çok Türkçe karakter probleminin nedeni budur.
Not
Python’un 3.x sürümlerinde öntanımlı kodlama biçimi “utf-8” olarak değiştirildi. Bu yüzden Python’un 3.x sürümlerinde Türkçe karakter problemleri çok daha az olacaktır.
path Niteliği¶
Modüller konusu içinde os modülünü anlatırken sys modülünün path adlı niteliğinden söz etmiştik. Orada da söylediğimiz gibi, Python içe aktarmaya çalıştığımız bir modülü ararken path niteliğinin gösterdiği dizinlerin içine bakar.
Bu niteliği şöyle kullanıyoruz:
>>> import sys
>>> sys.path
Bu komutun çıktısının, komutu verdiğiniz işletim sistemine göre farklılık göstereceğini biliyorsunuz.
Tıpkı argv niteliği gibi, path niteliği de bir listedir. Dolayısıyla listeler üzerinde yaptığınız her şeyi path niteliği üzerinde de yapabilirsiniz. Mesela listelerin insert() veya append() metotlarını kullanarak path listesine yeni öğeler ekleyebilirsiniz:
>>> sys.path.append("/herhangi/bir/dizin")
Bu komut, eklediğiniz dizini listenin en sonuna iliştirecektir. Eğer dizininizi listenin en başına eklemek isterseniz şu komutu kullanabilirsiniz:
>>> sys.path.insert(0, "/herhangi/bir/dizin")
Python içe aktaracağınız bir modülü path listesinde ararken listenin başından sonuna doğru ilerler ve modülü bulduğu anda arama işlemini durdurur. Dolayısıyla, mesela bir modül iki farklı dizin içinde yer alıyorsa, Python listede soldan sağa doğru bulduğu ilk modülü dikkate alacaktır. O yüzden yazdığınız programlarda bazen bir dizini bu listenin en başına eklemeniz gerekebilir.
platform Niteliği¶
Hatırlarsanız kullanılan işletim sistemini tespit etmek için os modülünün name adlı niteliğini kullanıyorduk. Aynen buna benzer bir şekilde, kullanılan işletim sistemini tespit etmek için sys modülünün platform adlı niteliğinden de yararlanabiliriz:
>>> sys.platform
'linux2'
Ben bu komutu GNU/Linux üzerinde verdiğim için aldığım çıktı linux2 oldu. Eğer aynı komutu Windows üzerinde verirseniz şöyle bir çıktı alırsınız:
>>> sys.platform
'win32'
Bu komut Mac Os X’te ise şöyle bir çıktı verir:
>>> sys.platform
'darwin'
Bu nitelik ile ilgili şöyle bir uyarı yapalım: Windows mimariniz 32 bit de olsa 64 bit de olsa bu nitelik her zaman win32 çıktısı verecektir. Dolayısıyla bu niteliği kullanarak 32/64 bit ayrımı yapamazsınız. Kullanılan işletim sisteminin 32 bit mi yoksa 64 bit mi olduğunu tespit edebilmek için platform adlı başka bir modülden yararlanabilirsiniz:
>>> import platform
>>> platform.architecture()
('32bit', 'ELF')
Ben bu komutu 32 bitlik bir GNU/Linux işletim sisteminde verdiğim için çıktı yukarıdaki gibi oldu. Eğer sistemim 64 bit olsaydı şöyle bir çıktı alacaktım:
>>> platform.architecture()
('64bit', 'ELF')
Bu komut 32 bitlik Windows işletim sistemlerin şu çıktıyı verir:
>>> platform.architecture()
('32bit', 'WindowsPE')
64 bitlik Windows işletim sisteminde ise şu çıktıyı alacaksınız:
>>> platform.architecture()
('64bit', 'WindowsPE')
Gördüğünüz gibi bu çıktılar birer demettir. Dolayısıyla demetlere nasıl davranıyorsanız bu çıktılara da öyle davranabilirsiniz.
stdout Niteliği¶
Bildiğiniz gibi Python’da ekrana herhangi bir şey yazdırabilmek için print deyiminden yararlanıyoruz:
>>> print "merhaba!"
merhaba!
Python print deyimlerinden sonra otomatik olarak yeni satıra geçer. Yani:
>>> for i in range(10):
... print "%s. satır" %(int(i)+1)
...
1. satır
2. satır
3. satır
4. satır
5. satır
6. satır
7. satır
8. satır
9. satır
10. satır
Gördüğünüz gibi, her satırdan sonra bir alt satıra geçiliyor. print deyiminin bir sonraki satıra geçmesini engellemek için virgülden yararlanabiliriz:
>>> for i in range(10):
... print i,
...
0 1 2 3 4 5 6 7 8 9
Burada çıktıya dikkat edin. Sayılar alt alta değil, yan yana diziliyor. Bunu sağlayan şey print i satırından sonra getirdiğimiz bir adet virgül işaretidir... Ancak burada her sayının arasında birer adet de boşluk karakteri var. İstediğiniz şey bu olabilir. Ama olmaya da bilir... Eğer hem öğeleri yan yana dizmek hem de öğeler arasında boşluk bırakmamak istiyorsanız sys modülünün stdout niteliğini kullanabilirsiniz. Daha doğrusu bu iş için sys modülünün stdout niteliğinin write() adlı metodunu kullanacağız. Hemen bir örnek verelim:
>>> sys.stdout.write("Merhaba!")
Merhaba!>>>
Gördüğünüz gibi, sys.stdout.write() print niteliğiyle aynı işi görüyor. Tek farkları, print niteliğinin işini bitirdikten sonra yeni satıra geçerken sys.stdout.write() metodunun bunu yapmaması. Bu durumu daha net bir şekilde görebilmek için şöyle bir örnek verebiliriz:
>>> for i in range(10):
... sys.stdout.write(str(i))
...
0123456789>>>
Gördüğünüz gibi, sys.stdout.write() metodu bütün sayıları yan yana dizdi ve satır sonunda da yeni satıra geçmedi. Bu kodlarda dikkat etmemiz gereken bir başka şey de sys.stdout.write() metoduna verdiğimiz argümanın bir karakter dizisi olması zorunluluğudur. sys.stdout.write() metodu sayıları ekrana basamaz:
>>> for i in range(10):
... sys.stdout.write(i)
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: argument 1 must be string or
read-only character buffer, not int
Böyle bir hata almamak için, for döngüsü içinde “i” değişkenini str() fonksiyonunu kullanarak karakter dizisine dönüştürüyoruz.
sys.stdout.write() komutunu kullanabileceğiniz faydalı bir örnek şöyle olabilir:
>>> import sys, time
>>> for i in range(20):
... time.sleep(1)
... sys.stdout.write("%s\r" %i)
... sys.stdout.flush()
Bu kodları çalıştırdığınızda 0’dan 20’ye kadar olan sayılar birer saniye aralıklarla tek bir satıra yazdırılacaktır. Ayrıca bu sayılar yan yana değil, birbirlerinin yerine geçerek ekrana basılacaktır... Peki bu kodlar nasıl çalışıyor? Hemen açıklayalım:
1. İlk satırda sys ve time adlı iki modülü içe aktardık. Bunlardan sys modülünü biliyoruz. time modülünü ise henüz öğrenmedik. Ama bu modülü de zamanı geldiğinde inceleyeceğiz. Şimdilik biz bu time adlı modülün, Python’da tarih ve zamanla ilgili işlemler yapmamızı sağlayan bir modül olduğunu bilelim yeter.
2. Sonraki satırda bir for döngüsü kurduk. Bu döngüde 0’dan 20’ye kadar olan sayıları ekrana basacağız.
3. for döngüsünün ilk satırında time.sleep(1) gibi bir kod görüyoruz. Burada time modülünün sleep() adlı fonksiyonunu kullandık. Bu fonksiyon, yapılan işlemlere belli sürelerde zaman aralıkları koymamızı sağlar. Biz burada bu süre aralığını 1 saniye olarak belirledik. Bizim kodlarımızda 0’dan 20’ye kadar olan sayılar 1’er saniye aralıklarla ekrana basılacak.
4. Sonraki satırda sys.stdout.write("%s\r" %i) komutunu görüyoruz. Bu kod 0’dan 20’ye kadar olan sayıların alt alta değil, yan yana yazılmasını sağlıyor. Burada bir de “\r” ifadesini görüyoruz. Aslında bu bir kaçış dizisidir. Görevi ise bir karakter dizisinin 0. konumuna dönülmesini sağlamaktır. Bu kaçış dizisinin nasıl çalıştığını anlamak için şöyle bir örnek verebiliriz:
>>> print "merhaba\ristihza"
istihza
Burada olan şey şu: “merhaba” karakter dizisinin hemen ardından “\r” kaçış dizisinin etkisiyle 0. konuma, yani karakter dizisinin en başına dönülüyor ve “istihza” karakter dizisi “merhaba” karakter dizisinin üzerine yazılıyor. “istihza” karakter dizisi ile “merhaba” karakter dizisi aynı sayıda karakterden oluştuğu için “merhaba” karakter dizisi siliniyor, onun yerine sadece “istihza” karakter dizisi çıktıda görünüyor. Yukarıdaki sys.stdout.write("%s\r" %i) komutunda da “\r” kaçış dizisi sayılar ekrana döküldükçe en başa dönülmesini, böylece bir sonraki sayının bir önceki sayıyı silmesini sağlıyor.
5. Son satırdaki sys.stdout.flush() ise sayıların ekranda hemen görünebilmesini sağlıyor. Dilerseniz bu satırı kaldırıp programı öyle çalıştırmayı deneyerek bu satırın tam olarak ne işe yaradığını görebilirsiniz. (Bazı işletim sistemlerinde bu satır gereksizdir. Ancak yazdığınız programın birden fazla işletim sisteminde düzgün çalışmasını istiyorsanız bu satırı eklemeniz gerekir.)
Aslında yukarıda yazdığımız kodları şöyle de yazabilirdik:
>>> import sys, time
>>> for i in range(20):
... time.sleep(1)
... print "%s\r" %i,
... sys.stdout.flush()
Ancak sys.stdout niteliği size aynı işi daha doğal bir şekilde yapma imkanı verir. Ayrıca sys.stdout‘un başka meziyetleri de vardır.
Normal şartlar altında print deyimi yardımıyla yazdırdığımız şeyler doğrudan ekranda görünür. Yani:
>>> print "bir şey"
Bu komutu verdiğimizde bir şey çıktısı hemen ekranda görünecektir. Çünkü print komutu, çıktıları doğrudan ekrana verir. Ama eğer istersek biz print çıktılarını ekran dışında başka yerlere de yönlendirebiliriz. Mesela şu kodlara bir bakın:
>>> import sys
>>> f = open("log.txt", "w")
>>> sys.stdout = f
>>> print "Yeni bir mesajınız var!"
>>> f.close()
Burada şu işlemleri yaptık:
- Öncelikle sys modülünü içe aktardık. Bunu neden yaptığımızı artık adınız gibi biliyorsunuz...
- Daha sonra, mevcut çalışma dizini içinde log.txt adlı bir dosya oluşturduk ve bu dosyayı yazma kipinde (“w”) açtık.
- Sonraki satırda f adını verdiğimiz dosyamızı sys.stdout niteliğine atadık. “stdout” kelimesinin açılımı “standard output“tur. Bu ifade “standart çıktı konumu” anlamına gelir. Dolayısıyla sys.stdout niteliği Python’da print komutunun nereye çıktı vereceğini belirler. Normal şartlar altında, bildiğiniz gibi, print komutu doğrudan ekrana çıktı verir. Yani Python’un öntanımlı “standart çıktı konumu” bilgisayar ekranıdır. İşte biz bu sys.stdout niteliğinin gösterdiği değeri başka bir konuma atayarak standart çıktı konumunu değiştirebiliriz. Biz yukarıdaki örnekte standart çıktı konumu olarak f adını verdiğimiz dosyayı gösterdik.
- Gördüğünüz gibi, bir önceki adımda yaptığımız işlemlerden ötürü artık print komutu ekrana çıktı vermiyor. Bu komutla yazdırdığımız şeyler doğruca log.txt dosyasına yazdırılıyor.
- Son olarak, dosyada yaptığımız değişikliklerin etkili olabilmesi için dosyamızı kapatıyoruz.
Şimdi mevcut çalışma dizini altındaki log.txt adlı dosyayı açın ve içinde ne yazdığına bakın.
Dosyayı kapattıktan sonra artık print komutunu kullanamayız. Dosyayı kapattıktan sonra print komutunu kullanmaya çalışırsak Python bize şöyle bir hata mesajı verecektir:
>>> print "deneme"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file
Python’da kapattığınız bir dosya üzerinde yeni işlem yapamazsınız. Ya dosyayı yeniden açmanız, ya da gerekli bütün işlemleri dosyayı kapatmadan önce yapmanız gerekir...
Yalnız burada şöyle bir soru akla geliyor: Biz yukarıdaki komutlar yardımıyla standart çıktı konumunu değiştirdik. Dolayısıyla artık print komutu, çıktılarını ekrana değil dosyaya veriyor... Peki biz print komutunu eski haline nasıl döndüreceğiz? Bunun birkaç yolu vardır:
1. Etkileşimli kabuğu kapatıp yeniden açabilirsiniz. Etkileşimli kabuğu kapatıp yeniden açtığınızda her şey eski haline dönecektir.
2. Şu komutu kullanabilirsiniz:
>>> sys.stdout = sys.__stdout__
sys.__stdout__ ifadesi, Python’un öntanımlı standart çıktı konumunu tutar. Dolayısıyla sys.stdout niteliğinin değerini sys.__stdout__ yapacak olursanız print komutu eski haline dönecektir.
3. Python geliştiricilerinin, bu tür işlemler için tavsiye ettiği yol ise şudur:
>>> import sys
>>> orijinal_konum = sys.stdout
>>> f = open("log.txt", "w")
>>> sys.stdout = f
>>> print "deneme mesajı"
>>> f.close()
>>> sys.stdout = orijinal_konum
>>> print "deneme"
deneme
Burada sys.stdout‘un değerini değiştirmeden önce, özgün çıktı konumunu orijinal_konum adlı bir değişkende saklıyoruz. Daha sonra normal bir şekilde çıktı konumu yönlendirme işlemlerini gerçekleştiriyoruz. İşimiz bitip dosyayı kapattıktan sonra da sys.stdout değerini eski haline döndürebilmek için bu niteliğin değerini orijinal_konum olarak değiştiriyoruz. Böylece print komutu eski işlevine yeniden kavuşmuş oluyor.
version_info Niteliği¶
sys modülü konusunda inceleyeceğimiz son niteliğin adı version_info. Oldukça kolay bir niteliktir bu. Bu niteliğin görevi kullanılan Python sürümü hakkında bilgi vermektir. Bunu şöyle kullanıyoruz:
>>> sys.version_info
(2, 6, 5, 'final', 0)
Gördüğünüz gibi, version_info niteliği çıktı olarak bir demet veriyor. Bu niteliği kullanarak, yazdığınız programlarda sürüm kontrolü yapabilirsiniz. Mesela:
>>> if not sys.version_info[:2] == (2, 6):
... print ("Bu programı kullanabilmeniz için "
... "Python'un 2.6 sürümü kurulu olmalı!")
Böylelikle sys modülünü tamamlamış olduk. En başta da söylediğimiz gibi, bu modül Python’daki en önemli modüllerden biridir. Dolayısıyla bu konu içinde anlatılanları sık sık tekrar etmenizi öneririm.