Skip to content

Commit 7567589

Browse files
authored
MetaProgramming Fundemantals and Examples
1 parent c13608c commit 7567589

File tree

1 file changed

+129
-0
lines changed

1 file changed

+129
-0
lines changed

Metaprogramming.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
"""
2+
Bu kodlar meta programlama egzersizi için yazılmıştır.
3+
Metaprogramlama basitçe programları programlamak demektir.
4+
Yani bir programı programlamak istediğimizde veya
5+
yazdığımız programın kendisini programlamak istediğimizde
6+
metaprogramlama denilen kavramdan faydalanırız.
7+
8+
Bu programı çalıştırmak için bulunduğunuz dizinde deneme.py ve bos_dosya.py isimli
9+
iki adet python dosyası oluşturun. Daha sonra bu python programlarını bu dosya üzerinden programlayalım.
10+
"""
11+
12+
with open("bos_dosya.py","a") as f:
13+
f.close()
14+
15+
#oluşturduğumuz dosyaların import edilmesi
16+
import deneme
17+
import bos_dosya
18+
import Metaprogramming # programın kendisini import etmesi
19+
20+
21+
22+
if __name__ == '__main__':
23+
#Yayıncı isminde bir değişkenim var. En altta nasıl olduğunu görebilirsin.
24+
print("Yayıncı:", Metaprogramming.Yayinci)
25+
#print(deneme.__dict__) # deneme dosyası içindeki tüm özellikler ve değişkenler
26+
27+
# metaclass aracılığıyla oluşturacağımız insan sınıfı için yapıcı metod
28+
def insan_init(self, boy, kilo, isim):
29+
self.kilo = kilo
30+
self.boy = boy
31+
self.isim = isim
32+
33+
# type fonksiyonuyla insan sınıfı oluşturma
34+
insan = type(
35+
"insan", #sınıfın adı
36+
(), #base class tanımlama (biz kullanmayacağız)
37+
# sınıf metodlarımızı tanımlama
38+
{"__init__": insan_init,
39+
"get_name": lambda self: print(self.isim),
40+
"VKI": lambda self: print(self.isim + " kişisinin Vücut/Kitle İndeksi: " + "{:.2f}".format(self.kilo/((self.boy/100)**2)))
41+
}
42+
)
43+
44+
#deneme dosyasının gömülü metodlarına bakalım
45+
print(dir(deneme)) #henüz biz hiç bi şey tanımlamadık
46+
47+
# deneme dosyasında yeni_nesne adında bir insan sınıfı oluşturalım
48+
deneme.__dict__["yeni_nesne"] = insan(175, 85, "Değişik insan")
49+
deneme.yeni_nesne.get_name() # isim alma
50+
deneme.yeni_nesne.VKI() # vücut kitle indeksi alma
51+
print("Orjinal değer: ", deneme.a) #deneme dosyası içinde tanımlanmış a değişkeninin değerini aldık
52+
deneme.a = "Atatürk"
53+
print("Değiştirdiğimiz değer: ", deneme.a)
54+
print(dir(deneme)) # deneme dosyasının gömülü metodlarında artık bizim oluşturduğumuz nesne görünecek.
55+
# print(deneme.__dict__["__file__"].split("\\")[-1])
56+
# print(deneme.__dict__["__cached__"])
57+
58+
# bos_dosya.py isimli programda yeni listeler tanımlayalım
59+
60+
# liste+number olacak şekilde 100 tane liste tanımlayalım ve
61+
# içine o listenin sonundaki numaraya kadar olan sayıları ekleyelim
62+
# for i in range(100):
63+
# bos_dosya.__dict__["liste" + str(i)] = [j for j in range(i)]
64+
65+
# #bos_dosya.py içinde 20 ye kadar olan listelere bakalım
66+
# for i in range(20):
67+
# print(bos_dosya.__dict__["liste"+str(i)])
68+
69+
70+
71+
72+
# METAPROGRAMMING YÖNTEMLERİYLE HİÇBİR İZNİMİZ OLMAYAN BİR PYTHON DOSYASINA DA ERİŞİP
73+
# İÇİNDEKİLERİ OKUYABİLİR VEYA ÇALIŞTIRABİLİRİZ. BUNUN İÇİN __pycache__ dosyasının oluşturulmuş olması gerekir.
74+
#deneme.py dosyasının izinlerini değiştirip deneyebilirsiniz!
75+
# __pycache__ içideki dosyayı okuma izniniz olmalıdır!
76+
import deneme #okuyamasak bile bu python dosyasını cache üzerinden import edebilecektir. Çünkü cache okunabilir durumda!
77+
78+
def hello():
79+
print("HACKED!")
80+
81+
deneme.__dict__["hello"] = hello
82+
deneme.hello()
83+
# DOSYA İÇİNDEN SELAMLA VE W İSİMLİ FONKSİYONLARI ÇALIŞTIRALIM
84+
# deneme.selamla(isim="Regaip", soyad="Kurt")
85+
# deneme.w()
86+
87+
# #DOSYANIN İÇİNDEKİLERİ CACHE'I OKUDUĞUMUZ İÇİN GÖREBİLDİK AMA AÇMAYA ÇALIŞTIĞIMIZDA HATA VERECEKTİR.
88+
# with open("deneme.py", "r") as f:
89+
# print(f.readlines())
90+
91+
92+
# METAPROGRAMLAMANIN KULLANIMI
93+
# Metaprogramlamada metaclasslar kullanılır ve bir metaclass type dan kalıtım alır.
94+
# metaclass alan bir sınıfın özellikleri metaclass tarafından düzenlenebilir. Örnek verelim:
95+
class StringMeta(type):
96+
# bureda eğer bu metaclass ile oluşturulan sınıfın adı y ile başlıyorsa
97+
# o sınıfa sınıfın adını yazdıran bir yaz fonksiyonu eklensin
98+
def __new__(cls, what, bases=None, dict=None):
99+
print(dict) # dict sınıfın özelliklerini barındırır.
100+
new_dict = {}
101+
if dict["__qualname__"].startswith("y"):
102+
print("Sınıf adı y ile başlıyor, yaz fonksiyonu ayarlanacak!")
103+
def yaz(self):
104+
print(dict["__qualname__"])
105+
#Soru: Bu ne işe yarar? Diyebiiliriz.
106+
#Cevap: Örneğin IDE'ler bizim yazdığımız kodu metaprogramlama ile tıpkı böyle denetler.
107+
# Böylece hatalı yerleri gösterirler mesela.
108+
new_dict["yaz"] = yaz
109+
return type.__new__(cls, what, bases, new_dict)
110+
class yreg(metaclass=StringMeta):
111+
pass
112+
class reg(metaclass=StringMeta):
113+
pass
114+
#yreg sınıfının adı y ile başladığı için yaz metodu olacak içinde.
115+
y = yreg()
116+
y.yaz()
117+
118+
r = reg()
119+
# r.yaz çalışmaz çünkü r nesnesinin oluşturulduğu sınıfın adı y ile başlamıyor, yaz metodu tanımlanmadı!
120+
# dolayısıyla yaz fonksiyonuna sahip değil!
121+
#r.yaz()
122+
123+
124+
#Program çalışma zamanı içinde kendini de değiştirebilir!
125+
Metaprogramming.__dict__["Yayinci"] = "Regaip KURT"
126+
127+
#program import edildiğinde Kemal değeri yazılırken en sonda Atatürk değeri yazacak.
128+
eval("deneme.w()")
129+
exec("deneme.w()")

0 commit comments

Comments
 (0)