Python Notlarım

Cem Topkaya
10 min readMay 12, 2021

--

  • 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.

https://replit.com/@cemt/herseynesne#main.py

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)
HesapMakinesi sınıfından ürettiğimiz nesneyi serileştirdiğimiz dosyanın içeriği
# 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öner
  • os.path.join : Birden fazla dizin dosya bilgisini birleştirip yolu döner
  • os.listdir : Dizin içindeki dosya ve dizinlerin listesini ([…]) döner
  • os.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 HesapMakinesi
class 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

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 = 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 = 29
print("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)

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

Varsayılan günlük seviyesi deiştirmedikçe WARNING olarak kalacaktır
Eğer günlüğü bir dosyaya yazdırmak istersek
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)

https://www.w3schools.com/python/ref_string_format.asp

--

--

Cem Topkaya
Cem Topkaya

Written by Cem Topkaya

Evlat, kardeş, ağabey, eş, baba, müzik sever, öğrenmek ister, paylaşmaya can atar, iyi biri olmaya çalışır, hakkı geçenlerden helallik ister vs.

No responses yet