30 Temmuz 2013 Salı

sys Modülü

sys modülü Python sistemine ilişkin fonksiyonlar ve nitelikler barındırır. Yani bu modül sayesinde kullandığımız Python sürümünü yönetebiliriz.
Modüller konusunu incelerken Python da bulunan modüllerin aslında birer Python programı olduğunu söylemiştik. Yani os modülü aslında os.py adında bir programdır. Ama bunların bazı istisnaları vardır. sys modülü de bunlardan biridir.sys modülü Python programlama dili ile değilde C programlama dili ile yazılmıştır.
Diğer her şeyde olduğu gibi sys modülünün içeriğini öğrenmek için dir() fonksiyonunu kullanabiliriz.
import sys
print dir(sys)
['__displayhook__', '__doc__', '__excepthook__', '__name__', '__package__', '__stderr__', '__stdin__', 
'__stdout__', '_clear_type_cache', '_current_frames', '_getframe', '_mercurial', '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', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding',
'getdlopenflags', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof',
'gettrace', 'hexversion', 'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 
'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'py3kwarning', 'pydebug', 'setcheckinterval', 
'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 
'version', 'version_info', 'warnoptions']
Gördüğünüz gibi sys modülü içerisinde bir hayli fonksiyon ve nitelik barındırıyor. Biz bunlardan bazılarını inceleyeceğiz.
argv Niteliği
Python programını komut satırında çalıştırırken gönderdiğimiz argümanlar argv Niteliği'ne eleman olarak gönderilirler. Şimdi argv.py adında bir program oluşturun ve içerisine şu kodları yazın.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
print sys.argv[1]
Şimdi bu programı komut satırında şu şekilde çalıştırın.
python argv.py test
test
Gördüğünüz gibi ekrana test ifadesini yazdı. İşte argv niteliği komut satırında çalışırken yanında ek olarak argüman almamızı sağlar. Birden fazla argüman da gönderebiliriz.
import sys
print sys.argv[2]
Şimdi ikinci bir argüman gönderelim.
python argv.py test deneme
deneme
argv niteliğini tam anlayabilmek için programımızı şu hale getirelim.
import sys

print sys.argv
Aynı şekilde komut satırında çalışalım ve aldığımız çıktıya bir bakalım.
python argv.py test deneme
['argv.py', 'test', 'deneme']
Gördüğünüz gibi çıktı olarak bir liste elde ettik. Bu listedeki ilk elemanın programımızın adı olduğunu fark etmişsinizdir. Listeler üzerinde yaptığımız tüm işlemleri bu liste üzerinde de yapabiliriz. Şimdi bir tane ac.py adında bir dosya oluşturun ve içerisine şu kodları yazın.
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import os

def ac():
    if os.name == "nt":
        os.startfile(sys.argv[1]) #Eğer işletim sistemi windows ise
    elif os.name == "posix":
        os.system("xdg-open %s" %sys.argv[1]) #Eğer işletim sistemi Lünux ise

if(len(sys.argv)>2)
    print "Birden fazla dosyayı açmaya çalıştınız."
else:
    ac()

Gördüğünüz gibi kullanıcıdan programı komut satırında çalıştırırken, açmak istediği dosyanın adını da argüman olarak istiyoruz. Girdiği programı os modülünde işlediğimiz nitelikler ile işletim sistemine göre açıyoruz. Burada gönderilen argümanları sayarken 2 sayısını kullandığımıza dikkat edin. Hatırlarsanız argv niteliğinin tuttuğu listenin ilk elemanı programın kendi adıydı. Bu yüzden bu listenin eleman sayısı zaten en az birdir.
exit() Fonksiyonu
exit() Fonksiyonu programın sonlanmasını sağlar.
import sys

isim = raw_input("Öğrenim:").lower()
if isim == "üniversite":
    print "Hoşgeldiniz."
else:
    print "Bu program size uygun değil,sonlandırılıyor."
    sys.exit()

print "Program sonlanırsa bu yaazıyı kullanıcı göremez."
Öğrenim:ilköğretim
Bu program size uygun değil,sonlandırılıyor.
Gördüğünüz gibi eğer kullanıcı üniversite öğrenimi görmüyorsa program sonlanır. exit() fonksiyonunun yaptığı ekstra bir işlem yoktur.
getdefaultencoding() Fonksiyonu
Python 2.x programları yazarken bildiğiniz gibi her programımızın başına şu kodu yazıyoruz.
# -*- coding: utf-8 -*-
Bu kodu yazmadan şu şekilde bir program yazmaya çalışalım.
print "Bu yazı Türkçe karakterler bulundurmaktadır."
SyntaxError: Non-ASCII character '\xc4' in file /home/mazlumagar/workspace/Python/sys/getdefaultencoding.py on line 3, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details
Gördüğünüz gibi Python, ASCII karakterlerinden farklı karakterler kullanıldığı için, bu karakterleri tanımadı ve hata döndürdü. Şimdi getdefaultencoding() fonksiyonunun ne işe yaradığına bakalım.
import sys
print sys.getdefaulteimncoding()
ascii
Gördüğünüz gibi getdefaultencoding() Python'daki ön tanımlı kodlama biçimini gösteriyor. Python 2.x sürümlerinde ön tanımlı kodlama biçimi ascii olduğu için Türkçe karakter problemi yaşıyoruz. Bu problemin üstesinden gelebilmek için de yukarıda gösterdiğimiz kod parçasını programımıza ekleyerek, kodlama biçimini UTF-8 çeviriyoruz.
Aynı programı Python 3.x sürümünde çalıştıralım.
utf-8
Gördüğünüz gibi Python 3.x sürümünde ön tanımlı kodlama biçimi olarak UTF-8 geliyor. Bu yüzden Python 2.x'de yaşadığımız Türkçe karakter problemini 3.x sürümlerinde yaşamıyoruz.
path Niteliği
Python bir modolü içe aktarırken Python bu modülü path Niteliği'nin gösterdiği dizinler içerisinde arar.
import sys
for i in sys.path:
    print i
/home/mazlumagar/workspace/Python/sys
/home/mazlumagar/workspace/Python
/usr/lib/python2.7
/usr/lib/python2.7/plat-linux2
/usr/lib/python2.7/lib-tk
/usr/lib/python2.7/lib-old
/usr/lib/python2.7/lib-dynload
/usr/local/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages
/usr/lib/python2.7/dist-packages/PIL
/usr/lib/python2.7/dist-packages/gst-0.10
/usr/lib/python2.7/dist-packages/gtk-2.0
/usr/lib/python2.7/dist-packages/ubuntu-sso-client
/usr/lib/pymodules/python2.7
Gördüğünüz gibi Python'ın modülleri nerede aradığını listelemiş olduk. path Niteliği geriye bir liste döndürür. Listeler üzerinde yaptığımız ekleme,çıkarma gibi işlemleri bu liste üzerinde de yapabiliriz.
sys.path.append('/dizin/altdizin')
Python artık içe modül aktarırken bizim eklediğimiz dizin içerisine de bakacaktır. Bilmeliyiz ki program sonlandıktan sonra liste eski haline geri döner. Eklediğimiz dizinler sadece çalıştığımız program için geçerlidir.
Python bir modülü ararken bulma işlemini gerçekleştirdikten sonra arama işlemini sonlandırır. Yani bir modül iki dizinde birden varsa listenin ilk sırasında bulunan dizindeki modül içe aktarılacaktır.
platform Niteliği
Daha önce os Modülünü işlerken, kullanılan işletim sistemini tespit edebilmek için name niteliğini kullanabildiğimizi söylemiştik. sys Modülünün platform niteliği de aynı işlemi yapmaktadır.
import sys
print sys.platform
Linux 2
Linux üzerinde çalıştırdığımız için çıktı bu şekilde olacaktır.
İşletim Sistemi Çıktı
Linux Linux2
Windows win32
Mac OS darwin
sys modülünün platform niteliği bize kullandığımız işletim sisteminin kaç bit olduğu hakkında bilgi vermez. Windows'ta çıktının win32 olduğu sizi yanıltmasın. 64 bit Windows'ta da aynı çıktıyı verecektir. Eğer kullanılan işletim sisteminin kaç bit olduğunu öğrenmek istersek platform modülünden faydalanabiliriz.
import platform
print platform.architecture()
('32bit', 'ELF')
Gördüğünüz gibi 32 bit Linux işletim sisteminde çalıştığımız için bu şekilde çıktı aldık. Çıktının sözlük olduğuna dikkat edin. Sözlükler üzerinde yaptığımız işlemleri çıktı üzerinde yapabiliriz.
İşletim Sistemi Çıktı
32 bit Linux ('32bit', 'ELF')
64 bit Linux ('64bit', 'ELF')
32 bit Windows ('32bit', 'WindowsPE')
64 bit Windows ('64bit', 'WindowsPE')
stdout Niteliği
Bugüne kadar ekrana yazdırma işlemi yaparken print deyiminden faydalandık. Python, print deyimi ile yazdırdıktan sonra otomatik olarak yeni satıra geçer.
i=1
while i<10:
    print i
    i=i+1
1
2
3
4
5
6
7
8
9
Aynı işlemi for döngüsü ile de yapabiliriz. Burada bir alt satıra geçmesini istemezsek print deyiminden sonra virgül kullanabiliriz.
i=1
while i<10:
    print i,
    i=i+1
1 2 3 4 5 6 7 8 9
Gördüğünüz gibi bu sefer sayılar yan yana yazıldı. Ama bu sefer de aralarında birer boşluk bırakıldı. Eğer print deyiminden sonra virgül kullanılırsa ifadeler arasında birer boşluk bırakılır. İstediğimiz şey bu olmayabilir. Biz sadece ifadelerin yan yana yazılmasını istiyor olabiliriz. Eğer böyle bir şey istersek sys modülünün stdout niteliğinin write() fonksiyonunu kullanabiliriz.
import sys
i=1
while i<10:
    sys.stdout.write(str(i))
    i=i+1
123456789
İfadeler yan yana ve istediğimiz şekilde yazıldı. write() fonksiyonuna verdiğimiz argüman karakter dizisi olmak zorundadır.
sys.stdout.write(2)
Traceback (most recent call last):
    sys.stdout.write(2)
TypeError: expected a character buffer object
Sayı yazdırmaya çalışınca program hata verdi. Bu hatayı almamak için önceki örnekte ifadeleri karakter dizisine dönüştüren str() fonksiyonunu kullandık.
Biz şimdiye kadar print deyimi ile çıktıları ekrana verdik. Ama istersek bunu değiştirebiliriz. stdout niteliğini kullanarak print deyiminin nereye çıktı vereceğini belirtebiliriz.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys

ac = open("stdout.txt","w")

sys.stdout = ac
print "print deyimi ile txt dosyasına yazıyoruz."
ac.close()
Burada kullandığımız sys.stdout=ac ifadesi ile print deyiminin çıktıları açtığımız dosyaya vereceğini söylüyoruz. Buradan anlıyoruz ki print deyimi varsayılan olarak çıktıları ekrana veriyor. Biz burada bunu değiştirdik. Eğer dosyayı kapattıktan sonra print ile yazmak istersek hata alırız.
print "deneme"
Traceback (most recent call last):
    print "deneme"
ValueError: I/O operation on closed file
Çünkü print deyimi burada açtığımız dosyayı arıyor. Biz dosyayı kapattığımız için hata ile karşılaşıyoruz. Peki print deyiminin tekrardan ekrana yazmasını nasıl sağlayacağız? Bunun için şu komutu kullanmamız yeterli.
sys.stdout = sys.__stdout__
print "deneme"
deneme
Artık sıkıntı olmadan ekrana çıktı verebildik. sys.__stdout__ ifadesi Python'ın öntanımlı standart çıktı komutunu tutar. Yani aslında programın kendi içinde sys.stdout ifadesi sys.__stdout__ değerine eşittir.
Geliştiricilerin tavsiye etiği yol ise şu şekildedir.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys

varsayilan = sys.stdout
ac = open("stdout.txt","w")

sys.stdout = ac
print "print deyimi ile txt dosyasına yazıyoruz."
ac.close()

sys.stdout = varsayilan
print "deneme"
deneme
Bu yöntem ile herhangi bir sıkıntı olmadan ilk önce açtığımız dosyaya sonrada ekrana yazı yazdırdık.
version_info Niteliği
version_info niteliği kullanılan Python sürümü hakkında bilgi verir.
import sys
print sys.version_info
sys.version_info(major=2, minor=7, micro=3, releaselevel='final', serial=0)

0 yorum :

Yorum Gönder