Verilerin depolanması, okunması veya iletilmesi ile ilgileniyorsak Python işimizi oldukça kolaylaştırır. Bu amaçla Python, yalnızca dosyayı açmak, okumak/yazmak ve kapatmak için komutlar sağlayarak süreci basitleştirir. Böylece, çoğu programlama dilinin aksine, dosya girdisi ve çıktısı oluşturmak için karmaşık okuma ve yazma nesneleri oluşturmanız gerekmez. Bu konu, Python’un işletim sistemindeki dosyalarla nasıl etkileşebileceğini açıklamaktadır.
- file_object = open(filename [, access_mode][, buffering])
Bir dosyanın tüm içeriğini okuma/alma
Dosya i/o için tercih edilen yöntem with
anahtar sözcüğünü kullanmaktır. Böylece okuma veya yazma tamamlandığında dosya tanıtıcısının kapatılmasını sağlanır. Bu yüzden aşağıdaki örneklerde with kullanımı göreceksiniz.
with open('myfile.txt') as in_file:
content = in_file.read()
print(content)
ya da dosyayı kapatma işlemini manuel olarak gerçekleştirmek için with seçeneğinden vazgeçebilir ve close’u kendiniz çağırabilirsiniz:
in_file = open('myfile.txt', 'r')
content = in_file.read()
print(content)
in_file.close()
Bir with deyimi kullanmadan, beklenmedik bir istisna ortaya çıkması durumunda dosyayı yanlışlıkla açık tutabileceğinizi unutmayın:
in_file = open('myfile.txt', 'r')
raise Exception("oops")
in_file.close() # Bu asla çağrılmayacak
with ile birden fazla dosya açabileceğinizi unutmayın.
Bir dosyayı satır satır okuma
Dosyayı tamamen değil de satır satır okumak istediğimizde ise aşağıdakini yapabiliriz.
with open('myfile.txt', 'r') as fp:
for line in fp:
print(line)
Diğer yandan, readline()
metodunu kullanmak satır satır yineleme üzerinde daha ayrıntılı kontrol sağlar. Aşağıdaki örnek yukarıdakine eşdeğerdir:
with open('myfile.txt', 'r') as fp:
while True:
cur_line = fp.readline()
# Sonuç boş bir dizeyse
if cur_line == '':
# Dosyanın sonuna ulaştık
break
print(cur_line)
for döngüsü yineleyicisini ve readline() işlevini birlikte kullanmak kötü bir uygulama olarak kabul edilir.
Daha yaygın olarak, readlines() yöntemi dosyanın satırlarının yinelenebilir bir koleksiyonunu saklamak için kullanılır:
with open("myfile.txt", "r") as fp:
lines = fp.readlines()
for i in range(len(lines)):
print("Satır " + str(i) + ": " + line)
Bu, aşağıdakileri yazdıracaktır:
Satır 0: hello Satır 1: world
Bir dosyaya yazma
with open('myfile.txt', 'w') as f:
f.write("Satır 1")
f.write("Satır 2")
f.write("Satır 3")
f.write("Satır 4")
myfile.txt dosyasını açarsanız, içeriğinin şu şekilde olduğunu göreceksiniz:
Satır 1 Satır 2 Satır 3 Satır 4
Python satır sonlarını otomatik olarak eklemez, bunu manuel olarak yapmanız gerekir:
with open('myfile.txt', 'w') as f:
f.write("Satır 1\n")
f.write("Satır 2\n")
f.write("Satır 3\n")
f.write("Satır 4\n")
Satır 1 Satır 2 Satır 3 Satır 4
Metin kipinde (varsayılan) açılan dosyaları yazarken satır sonlandırıcı olarak os.linesep kullanmayın; bunun yerine \n kullanın.
Bir kodlama belirtmek istiyorsanız, open işlevine kodlama parametresini eklemeniz yeterlidir:
with open('my_file.txt', 'w', encoding='utf-8') as f: f.write('utf-8 text')
Bir dosyaya yazmak için print deyimini kullanmak da mümkündür. Bu işlemin kullanımı Python 2 ve Python 3’te farklıdır, ancak konsept aynıdır, ekrana gidecek çıktıyı alabilir ve bunun yerine bir dosyaya gönderebilirsiniz.
with open('fred.txt', 'w') as outfile:
s = "Henüz Ölmedim!"
print(s) # stdout'a yazar
print(s, dosya = outfile) # outfile'a yazar
#Not: dosya parametresini belirtmek VE ekrana yazmak mümkündür
#dosyanın doğrudan ya da bir değişken aracılığıyla None değeriyle sonlandığından emin olarak
myfile = None
print(s, file = myfile) # stdout'a yazar
print(s, file = None) # stdout'a yazar
Python 2’de şöyle bir şey yapardınız
outfile = open('fred.txt', 'w')
s = "Henüz Ölmedim!"
print s # stdout'a yazar
print >> outfile, s # outfile'a yazar
Yazma işlevinin aksine, yazdırma işlevi satır sonlarını otomatik olarak ekler.
Dosya modları
Bir dosyayı açabileceğiniz, mod parametresiyle belirtilen farklı modlar vardır. Bunlara bakalım:
- ‘r’ – okuma modu. Varsayılan değer. Dosyayı değiştirmenize değil, yalnızca okumanıza izin verir. Bu modu kullanırken dosya mevcut olmalıdır.
- ‘w’ – yazma modu. Dosya mevcut değilse yeni bir dosya oluşturur, aksi takdirde dosyayı siler ve üzerine yazmanıza izin verir.
- ‘a’ – ekleme modu. Dosyanın sonuna veri yazacaktır. Dosyayı silmez ve bu mod için dosya mevcut olmalıdır.
- ‘rb’ – ikili okuma modu. Bu, okumanın ikili modda zorlanması dışında r’ye benzer. Bu aynı zamanda varsayılan bir seçimdir.
- ‘r+’ – okuma modu ve aynı zamanda yazma modu. Bu, r ve w kullanmak zorunda kalmadan aynı anda dosyaları okumanızı ve yazmanızı sağlar.
- ‘rb+’ – ikili modda okuma ve yazma modu. Verilerin ikili olması dışında r+ ile aynıdır
- ‘wb’ – ikili olarak yazma modu. Verinin ikili olması dışında w ile aynıdır.
- ‘w+’ – yazma ve okuma modu. r+ ile tamamen aynıdır ancak dosya mevcut değilse yeni bir dosya oluşturulur. Aksi takdirde, dosyanın üzerine yazılır.
- ‘wb+’ – ikili modda yazma ve okuma modu. w+ ile aynıdır ancak veriler ikilidir.
- ‘ab’ – ikili modda ekleme. Verilerin ikili olması dışında a’ya benzer.
- ‘a+’ – ekleme ve okuma modu. Dosya mevcut değilse yeni bir dosya oluşturacağı için w+ ile benzerdir. Aksi takdirde, dosya işaretçisi varsa dosyanın sonuna gider.
- ‘ab+’ – ikili olarak ekleme ve okuma modu. Verilerin ikili olması dışında a+ ile aynıdır.
with open(filename, 'r') as f:
f.read()
with open(filename, 'w') as f:
f.write(filedata)
with open(filename, 'a') as f:
f.write('\n' + newdata)
Ne | r | r+ | w | w+ | a | a+ |
---|---|---|---|---|---|---|
Okuma | ✔ | ✔ | ✘ | ✔ | ✘ | ✔ |
Yazma | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ |
Dosya oluşturma | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ |
Dosya silme | ✘ | ✘ | ✔ | ✔ | ✘ | ✘ |
Başlangıç pozisyonu | b | b | b | b | b | b |
Python 3, özel oluşturma için yeni bir mod ekledi, böylece yanlışlıkla mevcut dosyayı kesmeyecek veya üzerine yazmayacaksınız.
- ‘x’ – özel oluşturma için açılır, dosya zaten mevcutsa FileExistsError yükseltir
- ‘xb’ – ikili olarak özel oluşturma yazma modu için açık. Verinin ikili olması dışında x ile aynıdır.
- ‘x+’ – okuma ve yazma modu. Dosya mevcut değilse yeni bir dosya oluşturacağı için w+ ile benzerdir. Aksi takdirde, FileExistsError’ı yükseltir.
- ‘xb+’ – yazma ve okuma modu. x+ ile tamamen aynıdır ancak veriler ikilidir
Ne | x | x+ | ||||
---|---|---|---|---|---|---|
Okuma | ✘ | ✔ | ✘ | ✔ | ✘ | ✔ |
Yazma | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Dosya oluşturma | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
Dosya silme | ✘ | ✘ | ✔ | ✔ | ✘ | ✘ |
Başlangıç pozisyonu | b | b | b | b | b | b |
Dosya açma kodunuzu daha pythonic bir şekilde yazmanıza izin verin:
try:
with open("fname", "r") as fout:
# Açık dosyanızla çalışın
except FileExistsError:
# Hata işlemleriniz buraya gider
Python 2’de şöyle bir şey yapardınız
import os.path
if os.path.isfile(fname):
with open("fname", "w") as fout:
# Açık dosyanızla çalışın
else:
# Hata işlemleriniz buraya gider
Platformlar Arası Kodlama: encoding
Python’un yerleşik open() işlevi kodunuzun platformlar arası çalıştırılmasını kolaylaştırır. Bu amaçla her zaman encoding değişkenini tanımlamak en iyi yöntem olacaktır. Bunun nedeni, bir sistemin varsayılan kodlamasının platformdan platforma farklılık göstermesidir.
Linux sistemleri varsayılan olarak utf-8 kullanırken, bu durum MAC ve Windows için geçerli değildir.
Bir sistemin varsayılan kodlamasını kontrol etmek için herhangi bir python yorumlayıcısından şunu deneyebiliriz:
import sys sys.getdefaultencoding()
Bu nedenle, çalıştığınız dizelerin düşündüğünüz gibi kodlandığından emin olmak ve platformlar arası uyumluluğu sağlamak için her zaman kodlamayı belirtmek akıllıca olacaktır.
with open('somefile.txt', 'r', encoding='UTF-8') as f:
for line in f:
print(line)
Dosyaları özyinelemeli olarak taramak
Alt dizinler de dahil olmak üzere tüm dosyaları taramak için os.walk kullanın:
import os
for root, folders, files in os.walk(root_dir):
for filename in files:
print root, filename
root_dir, geçerli dizinden başlamak için “.” olabilir veya başka bir yol da olabilir.
Dosya hakkında da bilgi almak isterseniz, os.scandir gibi daha verimli bir yöntem kullanabilirsiniz:
for entry in os.scandir(path):
if not entry.name.startswith('.') and entry.is_file():
print(entry.name)
Bir dosyanın veya yolun var olup olmadığını kontrol edin
EAFP kodlama stilini kullanın ve açmaya çalışın.
import errno
try:
with open(path) as f:
# Dosya var
except IOError as e:
# ENOENT (Böyle bir dosya veya dizin yok) değilse istisnayı yükseltin
if e.errno != errno.ENOENT:
raise
# Böyle bir dosya veya dizin yok
Bu aynı zamanda, kontrol ile dosyanın kullanıldığı zaman arasında başka bir işlemin dosyayı silmesi durumunda yarış koşullarını da önleyecektir. Bu yarış koşulu aşağıdaki durumlarda meydana gelebilir:
- Os modülünü kullanma:
import os os.path.isfile('/path/to/some/file.txt')
- pathlib’i kullanma:
import pathlib path = pathlib.Path('/path/to/some/file.txt') if path.is_file(): ...
Belirli bir yolun var olup olmadığını kontrol etmek için yukarıdaki EAFP prosedürünü izleyebilir veya yolu açıkça kontrol edebilirsiniz:
import os path = "/home/myFiles/directory1" if os.path.exists(path): ## Bir şeyler yap
mmap Kullanarak Rastgele Dosya Erişimi
mmap modülünü kullanmak, kullanıcının dosyayı belleğe eşleyerek bir dosyadaki konumlara rastgele erişmesini sağlar. Bu, normal dosya işlemlerini kullanmaya bir alternatiftir.
import mmap
with open('filename.ext', 'r') as fd:
# 0: tüm dosyayı eşle
mm = mmap.mmap(fd.fileno(), 0)
# 5'ten 10'a kadar olan indislerdeki karakterleri yazdır
mm[5:10] yazdır
# mm'nin geçerli konumundan başlayan satırı yazdır
print mm.readline()
# 5. dizine bir karakter yaz
mm[5] = 'a'
# mm'nin konumunu dosyanın başına döndür
mm.seek(0)
# mmap nesnesini kapatın
mm.close()
Bir dosyanın içeriğini farklı bir dosyaya kopyalama
with open(input_file, 'r') as in_file, open(output_file, 'w') as out_file:
for line in in_file:
out_file.write(line)
Aynı işlevi shutil modülü ile de gerçekleştirebilirdik. O zaman shutil modülünü aşağıdaki gibi çağırırdık.
import shutil shutil.copyfile(src, dst)
Bu konuda ayrıntı için shutil kullanarak dosya kopyalama yazısına bakabilirsiniz. shutil modülünü aynı zamanda dosya taşıma için de kullanabilirsiniz.
Dizin içindeki tüm dosyaları kopyalama
import shutil
source='//192.168.1.2/Daily Reports'
destination='D:\\Reports\\Today'
shutil.copytree(source, destination)
Hedef dizin halihazırda mevcut olmamalıdır.
Belirli bir satır aralığı için dosya okuma
Diyelim ki bir dosyanın yalnızca belirli satırları arasında yineleme yapmak istiyorsunuz
Bunun için itertools’u kullanabilirsiniz
import itertools
with open('myfile.txt', 'r') as f:
for line in itertools.islice(f, 12, 30):
# burada bir şey yap
Bu, python’da indeksleme 0’dan başladığı için 13’ten 20’ye kadar olan satırları okuyacaktır. Yani 1 numaralı satır 0 olarak indekslenir
Burada next() anahtar sözcüğünü kullanarak bazı ekstra satırları da okuyabilirsiniz.
Ve dosya nesnesini bir yinelenebilir olarak kullanırken, lütfen readline() deyimini kullanmayın, çünkü bir dosyayı dolaşmanın iki tekniği birbirine karıştırılmamalıdır
Bir dosyadaki metni değiştirme
import fileinput
replacements = {'Search1': 'Replace1',
'Search2': 'Replace2'}
for line in fileinput.input('filename.txt', inplace=True):
for search_for in replacements:
replace_with = replacements[search_for]
line = line.replace(search_for, replace_with)
print(line, end='')
Bir dosyanın boş olup olmadığını kontrol etme
import os os.stat(path_to_file).st_size == 0
veya:
import os os.path.getsize(path_to_file) > 0
Ancak, dosya mevcut değilse her ikisi de bir istisna atacaktır. Böyle bir hatayı yakalamak zorunda kalmamak için şunu yapın:
import os def is_empty_file(fpath): return os.path.isfile(fpath) and os.path.getsize(fpath) > 0
bir bool değeri döndürecektir.