7 - Python’ın İleri Seviye Özellikleri I – Dekoratörler ve Fonksiyonel Yaklaşımlar
2025
Bu hafta Python’ın güçlü özelliklerinden dekoratörler ve fonksiyonel yaklaşımlar konularını işleyeceğiz. Bu sunumda:
Dekoratörler @dekoratör_adı
ile fonksiyonun üstüne yazılır:
Çıktı:
Fonksiyon öncesi işlem.
Merhaba!
Fonksiyon sonrası işlem.
Açıklama:
my_decorator
, say_hello
fonksiyonunu sarmalar ve ek işlemler yapar.@my_decorator
, say_hello = my_decorator(say_hello)
anlamına gelir.Bir fonksiyonun çalışma süresini ölçen dekoratör:
import time
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} {end - start:.4f} saniye sürdü.")
return result
return wrapper
@timer
def slow_function():
time.sleep(2)
print("Fonksiyon çalıştı.")
slow_function()
Çıktı:
Fonksiyon çalıştı.
slow_function 2.0023 saniye sürdü.
Açıklama: *args
ve **kwargs
sayesinde dekoratör esnek hale gelir.
Fonksiyonun kaç kez çağrılabileceğini sınırlayalım:
Çıktı:
Merhaba!
Merhaba!
Merhaba!
say_hello maksimum çağrı sayısına ulaştı.
say_hello maksimum çağrı sayısına ulaştı.
Açıklama: nonlocal calls
ile içteki değişken kontrol edilir.
Yetkilendirme kontrolü yapan dekoratör (uzun kod, 2 slayta bölündü):
def require_role(required_role):
def decorator(func):
def wrapper(user, *args, **kwargs):
if user.role == required_role:
return func(user, *args, **kwargs)
else:
raise PermissionError(f"'{required_role}' yetkisi gereklidir!")
return wrapper
return decorator
class User:
def __init__(self, name, role):
self.name = name
self.role = role
Açıklama: Kullanıcı sınıfı ve dekoratör tanımı burada yapıldı.
@require_role("admin")
def access_secret_data(user):
return "Gizli Veri: XYZ123"
admin = User("Ali", "admin")
user = User("Ayşe", "user")
print(access_secret_data(admin)) # Çalışır: "Gizli Veri: XYZ123"
# print(access_secret_data(user)) # Hata: PermissionError
Açıklama: admin
yetkisi olan kullanıcı erişebilir, diğerleri hata alır.
Fibonacci hesaplarken önbellek kullanalım:
from time import sleep
def memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrapper
@memoize
def fibonacci(n):
if n <= 1:
return n
sleep(0.1) # Gecikleme simülasyonu için
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(30)) # İlk hesaplama
print(fibonacci(30)) # Önbellekten gelir
Açıklama: Tekrarlanan hesaplamalar önbellekten alınarak hızlanır.
Sınıfa yeni bir metod ekleyelim:
Çıktı:
Merhaba, dünya!
Açıklama: print_hello
metodu sınıfa dinamik olarak eklenir.
setattr
Fonksiyonusetattr(object, name, value)
object
: Özellik eklemek istediğiniz nesne.name
: Eklemek istediğiniz özelliğin adı (string).value
: Özelliğin değeri.class MyClass:
pass
obj = MyClass()
# Dinamik olarak yeni bir özellik ekleyelim
setattr(obj, 'new_attr', 42)
print(obj.new_attr) # 42
setattr
, obj
nesnesine new_attr
adında bir özellik ekler.Sınıfın metodlarını loglayalım:
def log_methods(cls):
for name, value in cls.__dict__.items():
if callable(value) and not name.startswith("__"):
setattr(cls, name, log_decorator(value))
return cls
def log_decorator(func):
def wrapper(*args, **kwargs):
print(f"{func.__name__} çağrıldı.")
return func(*args, **kwargs)
return wrapper
@log_methods
class MyClass:
def method1(self):
print("Method1 çalıştı.")
obj = MyClass()
obj.method1()
Çıktı:
method1 çağrıldı.
Method1 çalıştı.
lambda arguments: expression
Bir listenin elemanlarına fonksiyon uygulayalım:
numbers = [1, 2, 3, 4, 5]
squares = list(map(lambda x: x ** 2, numbers))
print(squares) # [1, 4, 9, 16, 25]
Açıklama: map
, her elemana lambda
fonksiyonunu uygular.
Listeden eleman filtreleyelim:
Açıklama: filter
, çift sayıları seçer.
Listeyi tek bir değere indirgeyelim:
from functools import reduce
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product) # 120
Açıklama: reduce
, elemanları çarpar.
Tuple listesini sıralayalım:
students = [("Ahmet", 85), ("Mehmet", 92), ("Ayşe", 78)]
sorted_students = sorted(students, key=lambda x: x[1], reverse=True)
print(sorted_students) # [('Mehmet', 92), ('Ahmet', 85), ('Ayşe', 78)]
Açıklama: Notlara göre sıralama yapılır.
E-ticaret ürün analizi (uzun kod, 2 slayta bölündü):
products = [
{"id": 1, "name": "Laptop", "price": 5000, "stock": 10, "category": "Elektronik"},
{"id": 2, "name": "Mouse", "price": 200, "stock": 50, "category": "Elektronik"},
{"id": 3, "name": "Kitap", "price": 50, "stock": 100, "category": "Kitap"}
]
Açıklama: Ürün listesi tanımlandı.
# Elektronik ürünlerin ortalama fiyatı
electronics = list(filter(lambda p: p["category"] == "Elektronik", products))
prices = list(map(lambda p: p["price"], electronics))
avg_price = sum(prices) / len(prices)
print(f"Elektronik ortalama fiyat: {avg_price}") # 2600.0
Açıklama: Fonksiyonel araçlarla veri işlenir.
lambda
, map
, filter
, reduce
ile kısa ve etkili kod.map
ile bir listedeki kelimelerin uzunluklarını hesaplayın.filter
ile 70 üzeri notları seçen bir fonksiyon yazın.