Python Notlarım
- Dizin/Dosya İşlemleri
- Birim Test (unittest)
- public/private
*args
İle Parametre Sayısını Esnek Hale**kw
İle Liste Halinde Parametre Geçirmek- Günlük Seviyesi
- Enum
- __str__ ve __repr__
@staticmethod ile @classmethod Karşılaştırması
__str__ ve __repr__ *
__dict__ İle Üyelerin çekilmesi
Python içinde herşeyin Object olduğunu bilerek başlayalım.
Serileştirme ve Seri Kaldırma (serialize/deserialize)
İkili Serleştirme (pickle)
https://replit.com/@cemt/pickleornek#main.py
Serileştirmek için dump
, seriyi kaldırmak için load
metotları kullanılır.
Bir dosyaya birden fazla nesneyi serileştirerek saklayabilirsiniz. Ancak dosyadan nesneleri çıkarmak için peş peşe load etmemiz gerekiyor!
# Serileştir
# Dosyayı ikili formatta yazmak için wb modunda açmalıyız
pickle.dump( HesapMakinesi(), open('dosya.bin', 'wb') )# Seriyi Kaldır
nesne = pickle.load(dosya)
print(nesne) #<hesapMakinesi.HesapMakinesi object at 0x7f691c3c46d0>
nesne.topla(1,2)
# Eğer utf8 ile okumak isteseydik hata alırdık:
# with open(serilesenDosyaYolu, 'r') as dosya:
#
# Traceback (most recent call last):
# File "main.py", line 19, in <module>
# print(dosya.read())
# File "/usr/lib/python3.8/codecs.py", line 322, in decode
# (result, consumed) = self._buffer_decode(data, self.errors, final)
# UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte# Bu yüzden ikili dosya biçiminde açmamız gerekiyor: 'rb'
with open(serilesenDosyaYolu, 'rb') as dosya:
print(dosya.read())
# b'\x80\x04\x95&\rhesapMakinesi\x94\rHesapMakinesi\x93)\x81\x94.'
Dizin/Dosya İşlemleri
os.path.dirname
: Tam dosya yolunu barındıran dizinin yolunu döneros.path.join
: Birden fazla dizin dosya bilgisini birleştirip yolu döneros.listdir
: Dizin içindeki dosya ve dizinlerin listesini ([…]
) döneros.makedirs
: Dizin yaratır
import osdir = os.path.dirname('c:\_Projects\python\log seviyesi\modul1.py')os.listdir(dir)
['.vscode', 'coverage', 'dosyayaGunluk.py', 'gunluk.py',...]os.path.join(dir, 'cem.js')
'c:\\_Projects\\python\\log seviyesi\\cem.js'
os.makedirs(dizinYolu, exist_ok=True)
Eğer python≥3.2
kullanıyorsanız exist_ok=True
ile eğer dizin mevcutsa üretilecek istisnayı yönetmiş oluyorsunuz. Dizin varsa bozmadan devam et!
>>> [file for file in os.listdir(dir)]
['.git', '3gpp', 'clients', 'coverage', 'debug.log', 'HealthCheck.yaml', 'Log.yaml', 'README.md', 'swagger-ui', 'yaml-gen', 'yaml.rar']
>>>
>>> [print(file) for file in os.listdir(dir)]
.git
3gpp
clients
coverage
debug.log
HealthCheck.yaml
Log.yaml
README.md
swagger-ui
yaml-gen
yaml.rar
[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]
>>>
os.walk
Python yöntemi walk (), ağacı yukarıdan aşağıya veya aşağıdan yukarıya doğru yürüterek bir dizin ağacındaki dosya adlarını oluşturur.
os.walk(top[, topdown=True[, onerror=None[, followlinks=False]]])
top — Dizin içindeki her bir dizin için 3-tuple verir, yani (dirpath
, dirnames
, filenames
)
topdown— [İsteğe bağlı] yukarıdan aşağıya bağımsız değişken True
ise veya belirtilmemişse, dizinler yukarıdan aşağıya taranır. Yukarıdan aşağıya False
olarak ayarlanmışsa, dizinler aşağıdan yukarıya doğru taranır.
onerror — Hata olduğunda devam edip etmeyeceğini belirler.
followlinks — Bu, True
olarak ayarlanmışsa, sembolik bağlantılarla gösterilen dizinleri ziyaret eder.
>>> dir = os.path.dirname('C:\\_Projects\\python\\dizin\\')
>>>
>>> for dir, sub, files in os.walk(dir):
... print(dir)
... print(sub)
... print(files)
...
C:\_Projects\python\dizin
['alt_dizin1']
['dizin_dosya1.txt', 'dizin_dosya2.txt']
C:\_Projects\python\dizin\alt_dizin1
['alt_dizin2']
['alt_dizin1_dosya1.txt', 'alt_dizin1_dosya2.txt']
C:\_Projects\python\dizin\alt_dizin1\alt_dizin2
[]
['alt_dizin2_dosya1.txt', 'alt_dizin2_dosya2.txt', 'alt_dizin2_dosya3.txt']
Dosya İşlemleri *
close() : Açık bir dosyayı kapatır. Dosya zaten kapatılmışsa hiçbir etkisi yoktur.detach() : Temeldeki ham akışı tampondan ayırmak ve geri döndürmek için kullanılır. Ham akış ayrıldıktan sonra, tampon kullanılamaz durumdadır.fileno() : Dosyanın tam sayısını (dosya tanımlayıcı) döndürür.flush() : Dosya akışının yazma arabelleğini temizler.isatty() : Dosya akışı etkileşimli ise True döndürür.read(n) : Dosyadan en fazla n karakter okur. Negatif veya None ise dosyanın sonuna kadar okur.write(s) : s dizesini dosyaya yazar ve yazılan karakter sayısını döndürür.readable() : Dosya akışı okunabiliyorsa True döndürür.
writeable(): Dosya akışı yazılabiliyorsa True döndürür.readline(n=-1) : Dosyadan bir satır okur ve döndürür. Belirtilirse en fazla n bayt olarak okur.writelines(lines) : Dosyaya bir satır listesi yazar.seek(offset,from=SEEK_SET) : (Başlangıç, geçerli, bitiş) ile ilgili olarak dosya konumunu ofset bayt olarak değiştirir.seekable() : Dosya akışı rastgele erişimi destekliyorsa True döndürür.tell() : Mevcut dosya konumunu döndürür.truncate(size=None) : Dosya akışını bayt boyutuna göre yeniden boyutlandırır. Boyut belirtilmezse, mevcut konuma yeniden boyutlandırılır.
file.open()
>>> f = open("alt_dosya1.txt") # bulunduğu dizindeki dosyayı açar
>>> f = open("C:/_Projects/python/dizin/dizin_dosya1.txt")
r
: Okumak için dosyayı 0
pozisyonunda açar (varsayılan).
r+
: OKUMAK ve YAZMAK için dosyayı 0
pozisyonunda açar
w
: Yazmak için dosyayı açar. Mevcut değilse yeni bir dosya oluşturur veya varsa dosyayı keser.
w+
: YAZMAK ve OKUMAK için dosyayı açar. Dosya oluşturulmazsa oluşturulur var, aksi takdirde truncate edilir (truncate
, 0
pozisyonundan itibaren üzerine yazmak demektir).
x
: Özel oluşturma için dosya açar. Dosya zaten varsa işlem başarısız olur.
a
: Dosyanın sonuna eklemek için açar. Dosya yoksa yeni dosya oluşturur.
a+
: OKUMAK ve YAZMAK için dosyayı dosyanın en sonunda açar. Dosya yoksa oluşturulur. Akışı en sona konumlar, dosyaya yazdıktan sonra konumu yine dosyanın en sonuna ayarlayacaktır.
t
: Metin modunda açar. (varsayılan)
b
: İkili modda açılır.
+
: Güncelleme için dosyayı açar (okuma ve yazma)
| r r+ w w+ a a+
------------------|--------------------------
read | + + + +
write | + + + + +
write after seek | + + +
create | + + + +
truncate | + +
position at start | + + + +
position at end | + +
open()
f = open("test.txt") # 'r' veya 'rt' ye denktir
f = open("test.txt",'w') # Metin modunda yazar
f = open("img.bmp",'r+b') # İkili modda okur ve yazar
Eğer metin dosyalarıyla çalışıyorsak unutmamalı windows cp1252 kodlamasıyla yazarken Linux utf8 kullanır ve metin dosyası açarken kodlamasını da vermek doğru olanıdır:
f = open("test.txt", mode='r', encoding='utf-8')
f.close()
Dosya ile işiniz bitti kapatın. Eğer dosyayı açarken veya sonraki işlemlerinizde istisna olduysa istisnayı yönetsenizde, yönetmesenizde dosyayı kapatın:
f = open("test.txt", mode='r', encoding='utf-8')
f.close()
Her halükarda dosyayı kapatmayı unutmayın!
try:
f = open("test.txt", encoding = 'utf-8')
.
..
finally:
f.close()
with
İle Otomatik Close
Eğer dosyayı with
ile açarsak, dosyanın kapanışını otomatik yapabiliriz:
with open("test.txt",'w',encoding = 'utf-8') as f:
f.write("satır ekle\n")
f.write("Bir satır daha ekle\n\n")
Yukarıdaki satırlarda, mevcut dizinde yoksa test.txt
adlı yeni bir dosya oluşturulur, varsa üzerine yazılır.
file.read()
Dosyayı baştan sona okur:
>>> f.read()
'Tüm dosya içeriğini okur ve döner.\n'
Dosyayı satır satır okur ve okuduğu satırı döner:
>>> f.readline()
'This is the first line of the file.\n'
Bir dosyadan satır okumak için, dosya nesnesi üzerinde döngü yapabilirsiniz. Bu, bellek açısından verimli, hızlıdır ve basit kod yazmanızı sağlar:
>>> for line in f:
... print(line, end='')
...
This is the first line of the file.
Second line of the file
Bir listedeki bir dosyanın tüm satırlarını okumak istiyorsanız, list(f)
veya f.readlines()
da kullanabilirsiniz.
Dosyayı yazma modunda açıp okumak istersek hata alırız:
>>> dosyaYolu = os.path.join(dir, ‘dizin_dosya1.txt’
>>> f = open(dosyaYolu, 'w')
>>> f.write('naber?')
6
>>> f.read()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
io.UnsupportedOperation: not readable# Yazma modunda açıp okuma yapmak istisna yaratır
>>> f.close
file.detach()
>>> f = open("C:\_Projects\python\dIzIn\dosya.txt", 'w+')
>>> f.write('cemo')
4
>>> f.detach()
<_io.BufferedRandom name='C:\\_Projects\\python\\dIzIn\\dosya.txt'>
>>>
>>> f.close()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: underlying buffer has been detached
sas
>>> f = open("test.txt",'r',encoding = 'utf-8')
>>> f.read(4) # read the first 4 data
'This'
>>> f.read(4) # read the next 4 data
' is '
>>> f.read() # read in the rest till end of file
'my first file\nThis file\ncontains three lines\n'
>>> f.read() # further reading returns empty sting
''
asd
Birim Test (unittest)*
unittest.main()
unittest Dahil ettiğimiz yerleşik (builtin) bir sınıf. unittest.main()
metodu ise modülün içinde unittest.TestCase
türünü miras almış sınıfları bulup, bu sınıflardan bir nesne yaratıp sırasıyla setup
, test_
ile başlayan metotları ve tearDown
metotlarını çalıştırıyor.
Ref: Pankaj,
hesapMakinesi.py
class HesapMakinesi(object):
sonuc = 0
def __init__(self):
print('Makine açıldı...')def topla(self, *args):
for val in args:
self.sonuc += val
return self.sonuc
main.py
import unittest
from hesapMakinesi import HesapMakinesiclass TestEden(unittest.TestCase):
def setUp(self):
self.facit = HesapMakinesi()def tearDown(self):
print('Test bitti!')def test_ikiden_fazla_sayiyi_toplar(self):
sonuc = self.facit.topla(3,5,9)
self.assertEqual(17, sonuc)
print('sonuç beklendiği gibi')def test_tek_sayiyi_toplanir_kendi_doner(self):
sonuc = self.facit.topla(3)
self.assertEqual(3, sonuc)
print('sonuç beklendiği gibi')@unittest.skip("Es geçilecek test")
def test_esGecilecek(self):
print('es geçilecek')def no_test_calismas(self):
print('Çalışmayan test')unittest.main()
@unittest.*
@unittest.skip("demonstrating skipping")
Enum*
C# Enum
enum Products { HardDrive = 0, PenDrive = 4, Keyboard = 8 };
Java Enum
enum Devices {
LAPTOP, MOBILE, TABLET, DESKTOP;
}
Python Enum
enum
Modülü yerleşik (builtin) olarak geliyor ve içerisinde Enum türünü barındırıyor.
Enum
Tanımı yine class
ile yapılmakta
from enum import Enumclass ResmiBayram(Enum):
...--- veya ----import enumclass ResmiBayram(enum.Enum):
UlusalEgemenlikVeCocuk = 23
EmekVeDayanisma = 1
AtatürkUAnmaVeGenclikSpor = 19
ZaferBayrami = 30
Cumhuriyet = 29
Enum vs IntEnum
import enumclass ResmiBayram(enum.Enum):
UlusalEgemenlikVeCocuk = 23
EmekVeDayanisma = 1
AtaturkUAnmaVeGenclikSpor = 19
ZaferBayrami = 30
Cumhuriyet = 29--- IntEnum dan türüyorsa int dönüşümü yapılabilir ---
class ResmiBayram(enum.IntEnum):
Cumhuriyet = 29
print(int(ResmiBayram.Cumhuriyet)) # 29 yazar--- Ama Enum türünü miras alıyorsa istisna fırlatır ---
class ResmiBayram(enum.Enum):
Cumhuriyet = 29
print(int(ResmiBayram.Cumhuriyet)) # TypeError: int() argument must be a string, a bytes-like object or a number, not 'ResmiBayram'
import enumclass ResmiBayram(enum.Enum):
UlusalEgemenlikVeCocuk = 23
EmekVeDayanisma = 1
AtaturkUAnmaVeGenclikSpor = 19
ZaferBayrami = 30
Cumhuriyet = 29print("ResmiBayram.Cumhuriyet.name :", ResmiBayram.Cumhuriyet.name)
print("ResmiBayram.Cumhuriyet.value :",ResmiBayram.Cumhuriyet.value)
print("ResmiBayram.Cumhuriyet :", ResmiBayram.Cumhuriyet)
print("ResmiBayram['Cumhuriyet'] :", ResmiBayram['Cumhuriyet'])
print("ResmiBayram(29) :", ResmiBayram(29))
print("ResmiBayram(29).name :", ResmiBayram(29).name)
print("repr(ResmiBayram(29)) :", repr(ResmiBayram(29)))
print("type(ResmiBayram.Cumhuriyet) :",type(ResmiBayram.Cumhuriyet))print('\nfor in ResmiBayram')
for adi in (ResmiBayram):
print('\t', adi)
public/private
publicPrivate.py
# __all__ ile `from sinif import *` ile erişilebilir hale getirilen
# tüm üyeleri tanımlayabiliriz.
# Eğer __all__ ile bilinçli belirtmezsek; _ ile başlayan üyeler erişime gizli
# _ ile başlamayan üyeler erişime açık olacaklar
__all__ = ['public_fonksiyon', '_private_fonksiyon', '_dogal_private']def public_fonksiyon():
print("public fonksiyon")
def _private_fonksiyon():
print("private fonksiyon")# __all__ ile tanımlandığı için aşağıdaki public değişkene dışarıdan erişilemez !
dogal_public = 21# __all__ bildirimi yapılmamış olsaydı private olarak işaretlenmişti !
# __all__ içinde tanımlı olduğu için dışarıdan erişilebilir.
# Bu yüzden __all__ için "Weak Private" denir
_dogal_private = 12
main.py
from publicPrivate import *public_fonksiyon()
_private_fonksiyon()
print("_dogal_private: ",_dogal_private)
print("_dogal_public: ",_dogal_public)
Çıktı:
public fonksiyon
private fonksiyon
_dogal_private: 12
Traceback (most recent call last):
File "main.py", line 6, in <module>
print("_dogal_public: ",_dogal_public)
NameError: name '_dogal_public' is not defined
*args İle Parametre Sayısını Esnek Hale
C# Nasıl başa çıkıyor?
C# dilinde params ile n uzunlukta dizi şeklinde parametre alınıyor.
using System;
using System.Linq;class MainClass {
public static void Main (string[] args) {
diziParams(new[]{1,3,5});
diziParams(7,9);
diziParams_2("cem", 11,"topkaya",15);
}public static void diziParams(params int[] args){
foreach(var a in args) {
Console.WriteLine(a);
}
Console.WriteLine("----------------");
}public static void diziParams_2(string isim, params object[] args){
Console.WriteLine("String parametre(İsim): "+isim);foreach(var a in args) {
Console.WriteLine(a);
}
Console.WriteLine("----------------");
}
}
Java Nasıl başa çıkıyor?
Java’da VarArgs diye isimlendiriliyor.
class Main{public static void main(String []args){
varArgs_1( 7, true, "cem", 8.9, 'a');
varArgs_2(new Integer(7), new Boolean(true), new String("cem"), new Double(8.9), new Character('a'));
} private static void varArgs_1(Object... dizi) {
for(Object eleman : dizi)
System.out.print(eleman + " ");
} private static void varArgs_2(int sayi, Object... dizi) {
System.out.println("\n----------------------------");
System.out.print(sayi + " ");
for(int i = 0; i < dizi.length; i++)
System.out.print(dizi[i] + " ");
}
}
Python Nasıl başa çıkıyor?
def diziArgs(isim, *args):
print("İsim: " + isim)
print('Args: ', args)
print('----------------')diziArgs("Cem")
diziArgs("Cem", 2021, 'Covid Günleri', 'neler neler...')
**kw İle Liste Halinde Parametre Geçirmek
keyword
olarak parametre geçiriyoruz.
Varsa *args parametresi daima **kw parametresinden önce gelmeli!!!
Args ve Keyword arasındaki farkı ikisini aynı anda çalıştırınca göreceğiz:
İsim: Cem
Args: ()
Keyword: {}
----------------
İsim: Cem
Args: (1, 2, 'topkaya')
Keyword: {'adi': 'Cem', 'soyadi': 'Topkaya'}
Günlük Seviyesi
import logginglogging.basicConfig(filename="uygulama_gunlugu.log", level=logging.DEBUG, format="%(asctime)s %(name)s %(levelname)s %(message)s")logging.debug('debug Seviyesi günlük kaydı')
logging.info('info Seviyesi günlük kaydı')
logging.warning('warning Seviyesi günlük kaydı')
logging.error('error Seviyesi günlük kaydı')
logging.critical('critical Seviyesi günlük kaydı')
logging.getLogger(“gunluk_adı”)
getLogger
ile bir günlük nesnesi yaratıyoruz. Bu nesne name
özelliğinde sabit bir isim veya __name__
parametresiyle çalıştığı modülün adını almasını sağlıyoruz. Eğer kodu gunluk.py
içinde çalıştırırsak __main__
olarak görüntülenirken gunluk.py
dosyasını içeren (import gunluk
) başka bir dosyadan çalıştırdığımızda “gunluk” modülünün adını göreceğiz.
Dosyaya ve Konsola Günlük Kaydını Yazdırmak
basicConfig Ayarlarını Parçalayarak Yazalım
gunlukcu = logging.getLogger()
gunlukcu.setLevel(logging.ERROR)bicim = logging.Formatter('%(levelname)s %(message)s')
dosyaIsleyici = logging.FileHandler('GunlukDosyasi.log')
dosyaIsleyici.setFormatter(bicim)gunlukcu.addHandler(dosyaIsleyici)