bc1428
Ekim 14, 2022, 8:07ös
1
import math
import time
def calculate_time(func):
def inner(*args, **kwargs):
start = time.time()
time.sleep(1)
func(*args, **kwargs)
finish = time.time()
print("Fonksiyon", func.__name__, str(finish - start), "saniye sürdü.")
return inner
@calculate_time
def usalma(a, b):
print(math.pow(a,b))
@calculate_time
def faktoriyel(num):
print(math.factorial(num))
usalma(4, 9)
faktoriyel(7)
Burada @calculate_timein açılımı nedir?
decorators’un kullanım amacını anladım gibi ama tam olarak nedir?
burada calculate_time decorator’ı kullanılan methodun bitiş zamanını hesaplıyor
calculate_time methodu tanımlanıyor, altına inner methodu tanımlanıyor inner methodda başlangıç zamanı start değişkenine atanıyor, 1 saniye bekliyor, fonksiyonu çağırıyor (usalma, faktoriyel methodlarında kullanılmış ama başka herhangi bir methodda da kullanılabilir), daha sonra bitiş zamanını printliyor.
bc1428
Ekim 16, 2022, 3:46ös
4
import math
import time
def calculate_time(func):
def inner(*args, **kwargs):
start = time.time()
time.sleep(1)
finish = time.time()
print("Fonksiyon", func, str(finish - start), "saniye sürdü.")
return inner()
def usalma(a, b):
print(math.pow(a,b))
return usalma.__name__
def faktoriyel(num):
print(math.factorial(num))
return faktoriyel.__name__
deneme = calculate_time(faktoriyel(3))
usalma_deneme = calculate_time(usalma(5, 2))
usalma
deneme
Yukanıda attığım kodun alternatifi bu mudur? Yoksa daha mantıklı bir yolu var mı?
aib
Ekim 16, 2022, 8:58ös
5
Su sekilde calismali:
usalma_decorated = calculate_time(usalma)
faktoriyel_decorated = calculate_time(faktoriyel)
bc1428:
return inner()
Bu yanlis, inner’i cagirmayip dondurmemiz lazim. inner’in func’u cagirmasi lazim; ilk ornek dogruydu.
bc1428
Ekim 21, 2022, 6:32ös
6
def stopwatch(function, request = None):
def inner(request):
print(15, request)
start = datetime.now()
stop = datetime.now()
timedown = (stop - start)
if request == 0:
return start
elif request == 1:
return stop
else:
return timedown.microseconds
return inner
def text():
print("BC1428")
i = stopwatch(text)
print(i)
Hocam öyle yapınca da inner’e girmiyor.
bc1428
Ekim 21, 2022, 6:47ös
7
def stopwatch(function, request):
def inner():
start = datetime.now()
stop = datetime.now()
timedown = (stop - start)
if request == 0:
return start
elif request == 1:
return stop
elif request == 100:
return [start, stop, timedown.microseconds]
else:
return timedown.microseconds
return inner
def text():
print("BC1428")
used = stopwatch(text, 100)
print(used())
Sanırım oldu, bunda bir eksiklik, yanlışlık var mı hocam?
aib
Ekim 22, 2022, 8:45öö
8
i’yi cagirmiyorsun.
Bu cok karisik:
function kullanilmiyor?
request parametresi niye stopwatch’a ait?
start ile stop ayni deger?
En yukaridaki (sorudaki) en dogrusu hala.
bc1428
Ekim 22, 2022, 9:04öö
9
Hocam bu daha doğru oldu sanırım
def stopwatch(function):
def inner(request=None):
start = datetime.now()
function()
stop = datetime.now()
timedown = (stop - start)
if request == 0:
return start
elif request == 1:
return stop
elif request == 100:
return [start, stop, timedown.seconds]
else:
return timedown.microseconds
return inner
def text():
return print("BC1428")
k = stopwatch(text)
print(k(100))
Tamamı burada hocam
aib
Ekim 22, 2022, 10:34öö
11
Aa bi dakka.
request function’a gidecek zannediyordum. stopwatch'tan alinacak bilginin karakteristigi, degil mi?
O zaman stopwatch'ta olmasi dogruydu, kafam karismis, benim hatam.
aib
Ekim 22, 2022, 10:43öö
12
inner'in butun olayi function'i taklit etmek cunku. Dekoratoru ozel bir fonksiyon icin yaziyor ve yazma amacimiz bu fonksiyonun parametreleriyle oynamak degilse, inner hemen her zaman (*args, **kwargs) olacak ve function'i her zaman (*args, **kwargs) ile cagiracak. (Butun argumanlari alip oldugu gibi function'a paslamak icin. Hata varsa da function versin…)
Hatta inner'in function'i daha iyi taklit edebilmesi icin bir fonksiyon var: inner yerine (functools.wraps(function))(inner) dondurunce help(k) filan yazildiginda inner yerine function'in dokumentasyonu cikiyor, dekorator tamamen transparan oluyor.
(wraps aslinda dekorator ama konu recurse etmesin diye boyle yazdim)
bc1428
Ekim 22, 2022, 5:01ös
13
aib:
request function’a gidecek zannediyordum. stopwatch’tan alinacak bilginin karakteristigi, degil mi?
O zaman stopwatch’ta olmasi dogruydu, kafam karismis, benim hatam.
Yani hocam attığım örneklerin ilki ve sonuncusu doğrudur. Diğerlerinde de request uygundur ama yapı olarak functionu çağırmadığım için yanlıştır. Doğru mu anladım
aib
Ekim 22, 2022, 7:03ös
14
Su soru cevaplanmamis ama cevabinin “evet” oldugunu varsayarsak, sondan ikincinin function’i cagirani.
import functools
import datetime
def stopwatch(function, request):
@functools.wraps(function)
def inner(*args, **kwargs):
start = datetime.datetime.now()
function(*args, **kwargs)
stop = datetime.datetime.now()
timedown = (stop - start)
if request == 0:
return start
elif request == 1:
return stop
elif request == 100:
return [start, stop, timedown.microseconds]
else:
return timedown.microseconds
return inner
def text():
print("BC1428")
used = stopwatch(text, 100)
help(used)
print(used())
veya
import functools
import datetime
def stopwatch(request):
def outer(function):
@functools.wraps(function)
def inner(*args, **kwargs):
start = datetime.datetime.now()
function(*args, **kwargs)
stop = datetime.datetime.now()
timedown = (stop - start)
if request == 0:
return start
elif request == 1:
return stop
elif request == 100:
return [start, stop, timedown.microseconds]
else:
return timedown.microseconds
return inner
return outer
@stopwatch(100)
def text():
print("BC1428")
help(text)
print(text())