Python'da `io` Modülü
Bu makale Python'daki io modülünü açıklar.
Python'daki io modülünü pratik örneklerle açıklayacağız.
YouTube Video
Python'da io Modülü
Girdi/çıktı işlemleri; dosyalar, ağlar ve standart I/O gibi her türlü veri işleminin temelini oluşturur. Python'un io modülü; bu girdi/çıktı işlemlerini birleştiren bir dizi soyut sınıf sağlar. Bu modülü anlamanın temel kavramı "akış (stream)" fikridir.
Akış (stream) nedir?
Bir akış, verileri ardışık ve sürekli olarak okuma ve yazma için soyut bir akıştır.
Dosya içeriğini bayt bayt okurken veya ağ üzerinden veri gönderip alırken, tüm bunlar veri akışı olarak ele alınabilir.
Bu mekanizmayı soyutlayarak, dosyalar, bellek ve ağlar gibi farklı I/O kaynakları okuma ve yazma gibi ortak işlemlerle yönetilebilir.
Python'un io modülü, akışlar için birleştirilmiş bir arayüz sağlayarak hem metin hem de ikili verinin verimli bir şekilde işlenmesini mümkün kılar.
io Modülünün Temel Yapısı
io modülü, akışların doğasına göre üç katmanlı bir hiyerarşiye sahiptir.
-
Ham Katman (
RawIOBase)RawIOBase, işletim sistemi dosya tanımlayıcıları ve aygıtlar gibi en düşük seviye bayt I/O'sunu yönetir. -
Bellekli Katman (
BufferedIOBase)BufferedIOBase, I/O verimliliğini artırmak için bir önbellek (buffer) sağlar.BufferedReaderveBufferedWritertipik örneklerdir. -
Metin Katmanı (
TextIOBase)TextIOBase, bayt dizilerini metinlere (string) dönüştürür ve karakter kodlamasını yönetir. Genellikle, bir dosyaopen()fonksiyonu ile açılırken bu katmandanTextIOWrapperkullanılır.
Bu yapı sayesinde, io modülü metin ve ikili I/O işlemlerini net bir şekilde ayırırken esnek kombinasyonlara da imkan tanır.
io Modülünün Temel Yapısı
En alttaki katmanda RawIOBase OS dosya tanımlayıcılarını işler, BufferedIOBase ise üzerine bir önbellek ekler ve en üstteki TextIOBase metin dönüşümlerini yönetir.
1import io
2
3# Check the core base classes hierarchy
4print(io.IOBase.__subclasses__())- Bu kod,
IOBase'den türeyen soyut sınıf grubunu kontrol etmek içindir.TextIOBase,BufferedIOBaseveRawIOBase'yi görerek hiyerarşik yapıyı doğrulayabilirsiniz.
io.IOBase: Hepsinin Temel Sınıfı
IOBase, tüm I/O nesneleri için soyut temel sınıftır ve close(), flush() ve seekable() gibi ortak yöntemleri tanımlar. Genellikle doğrudan kullanılmaz, genellikle türetilmiş sınıflar üzerinden erişilir.
1import io
2
3f = io.StringIO("data")
4print(f.seekable()) # True
5print(f.readable()) # True
6print(f.writable()) # True
7f.close()- Bu örnek,
IOBase'in ortak yöntemlerinin üst sınıflarda da kullanılabileceğini gösterir.seekable()vereadable(), bir akışın özelliklerini kontrol etmek için kullanışlıdır.
io.RawIOBase: En Düşük Seviye Katman
RawIOBase, işletim sistemi dosya tanımlayıcısına en yakın katmandır ve önbellekleme yapmaz. Tipik bir uygulama, bayt bazında okuma ve yazma yapan FileIO'dur.
1import io, os
2
3# Create a low-level FileIO object (no buffering)
4fd = os.open('raw_demo.bin', os.O_RDWR | os.O_CREAT)
5raw = io.FileIO(fd, mode='w+')
6raw.write(b'abc123')
7raw.seek(0)
8print(raw.read(6)) # b'abc123'
9raw.close()FileIO,RawIOBase'in somut bir implementasyonudur; tüm okuma ve yazmalarbytesolarak yapılır. Daha üsttekiBufferedIOBasekatmanı ile birleştirildiğinde verimlilik artırılabilir.
io.BufferedIOBase: Orta Katman (Önbellekli)
BufferedIOBase, önbellekleme yapan ve disk erişimini daha verimli hale getiren bir ara katmandır. Başlıca uygulamalar BufferedReader, BufferedWriter, BufferedRandom ve BufferedRWPair'dır.
1import io
2
3# Create a buffered binary stream on top of a BytesIO (simulate file)
4base = io.BytesIO()
5buffered = io.BufferedWriter(base)
6buffered.write(b'Python IO buffering')
7buffered.flush()
8base.seek(0)
9print(base.read()) # b'Python IO buffering'- Bu örnekte,
BufferedWriterile yazılan veriler geçici olarak bellek tamponunda saklanır veflush()çağrıldığında alt katmana aktarılır.
BufferedReader Örneği
BufferedReader, peek() ve read() ile verimli okumayı destekleyen, yalnızca okunabilir bir tamponlu akıştır.
1import io
2
3stream = io.BytesIO(b"1234567890")
4reader = io.BufferedReader(stream)
5print(reader.peek(5)) # b'12345' (non-destructive)
6print(reader.read(4)) # b'1234'
7print(reader.read(3)) # b'567'peek(), veriye yalnızca "bakış" atar ve göstericiyi (pointer) hareket ettirmez.read()ile birleştirerek, tamponlamayı esnek olarak kontrol edebilirsiniz.
io.TextIOBase: Yalnızca Metin Katmanı
TextIOBase, dizeleri işlemek için kullanılan ve dahili olarak kod çözme ve kodlama işlemlerini gerçekleştiren bir soyutlama katmanıdır. Tipik bir uygulama sınıfı TextIOWrapper'dır.
1import io
2
3# Wrap a binary stream to handle text encoding
4binary = io.BytesIO()
5text_stream = io.TextIOWrapper(binary, encoding='utf-8')
6text_stream.write("\u3053\u3093\u306B\u3061\u306F")
7text_stream.flush()
8
9# Reset stream position
10binary.seek(0)
11
12# Read bytes once
13data = binary.read()
14
15# Show both raw bytes and decoded text
16print("Raw bytes:", data)
17print("Decoded text:", data.decode('utf-8'))- Bu örnekte,
TextIOWrappermetni UTF-8'e dönüştürerek alttaki ikili akışa yazar.
TextIOWrapper ile Okuma Örneği
Okuma sırasında kod çözme otomatik olarak yapılır.
1import io
2
3binary_data = io.BytesIO("Python I/O".encode('utf-8'))
4text_reader = io.TextIOWrapper(binary_data, encoding='utf-8')
5print(text_reader.read()) # 'Python I/O'TextIOWrapper, metin I/O için temel sınıftır ve neredeyse tüm üst seviye dosya işlemlerinin temelini oluşturur.
io.StringIO: Bellek İçi Metin Akışı
StringIO, bellekteki metinleri sanki bir dosyaymış gibi işlemenizi sağlayan bir sınıftır. I/O testi ve geçici veri üretimi için kullanışlıdır.
1import io
2
3text_buf = io.StringIO()
4text_buf.write("In-memory text stream")
5text_buf.seek(0)
6print(text_buf.read()) # 'In-memory text stream'StringIO, diski kullanmadan dosya benzeri işlemlere imkan tanır ve birim testlerinde yaygın olarak kullanılır.
io.BytesIO: Bellek İçi İkili Akış
BytesIO, bayt dizilerini (bytes) işleyen bir bellek içi dosya sınıfıdır. Dosya kullanmak istemediğiniz ikili veri işleme veya veri sıkıştırma gibi durumlarda yararlıdır.
1import io
2
3buf = io.BytesIO()
4buf.write(b'\x01\x02\x03')
5buf.seek(0)
6print(list(buf.read())) # [1, 2, 3]BytesIO,BufferedIOBaseile aynı arayüze sahiptir ve birçok dosya API'sinin yerine kullanılabilir.
Özel Akışlar (Özgün Sınıflar Oluşturma)
io içindeki sınıflar genişletilebilirdir ve kendi akış sınıflarınızı oluşturmanıza olanak tanır. Aşağıda, yazım sırasında tüm metni büyük harfe çeviren bir TextIOBase alt sınıfı örneği verilmiştir.
1import io
2
3class UpperTextIO(io.TextIOBase):
4 def __init__(self):
5 self.buffer = ""
6 def write(self, s):
7 self.buffer += s.upper()
8 return len(s)
9
10u = UpperTextIO()
11u.write("hello io")
12print(u.buffer) # "HELLO IO"TextIOBasesözleşmesine uyduğunuz sürece, bu gibi özel davranışlar tanımlayabilirsiniz. Ayrıca dosyalar ve ağlar gibi özel durumlar için akışları genişletmek de kolaydır.
Özet
io modülü, girdi/çıktı işlemlerini soyut ve somut sınıfların bir hiyerarşisi şeklinde organize eder.
RawIOBase, işletim sistemi seviyesinde bayt I/O için bir sınıftır.BufferedIOBase, verimli bir önbellek katmanı sağlayan bir sınıftır.TextIOBase, metinlerin okuma ve yazmasını yöneten bir sınıftır.StringIOveBytesIO, bellek içi akışlar sağlayan sınıflardır.
Bu sınıfları anlamak, Python'un I/O sisteminin nasıl çalıştığını doğru şekilde kavramanızı ve bunları dosya işlemlerine, ağ iletişimine ve test akışlarının tasarımına uygulamanızı sağlar.
Yukarıdaki makaleyi, YouTube kanalımızda Visual Studio Code'u kullanarak takip edebilirsiniz. Lütfen YouTube kanalını da kontrol edin.