Python Tiplerine Giriş¶
🌐 Translation by AI and humans
This translation was made by AI guided by humans. 🤝
It could have mistakes of misunderstanding the original meaning, or looking unnatural, etc. 🤖
You can improve this translation by helping us guide the AI LLM better.
Python, isteğe bağlı "type hints" (diğer adıyla "type annotations") desteğine sahiptir.
Bu "type hints" veya annotations, bir değişkenin type'ını bildirmeye yarayan özel bir sözdizimidir.
Değişkenleriniz için type bildirerek, editörler ve araçlar size daha iyi destek sağlayabilir.
Bu, Python type hints hakkında sadece hızlı bir eğitim / bilgi tazeleme dokümanıdır. FastAPI ile kullanmak için gereken minimum bilgiyi kapsar... ki aslında bu çok azdır.
FastAPI tamamen bu type hints üzerine kuruludur; bunlar ona birçok avantaj ve fayda sağlar.
Ancak hiç FastAPI kullanmasanız bile, bunlar hakkında biraz öğrenmeniz size fayda sağlayacaktır.
Not
Eğer bir Python uzmanıysanız ve type hints hakkında her şeyi zaten biliyorsanız, sonraki bölüme geçin.
Motivasyon¶
Basit bir örnekle başlayalım:
def get_full_name(first_name, last_name):
full_name = first_name.title() + " " + last_name.title()
return full_name
print(get_full_name("john", "doe"))
Bu programı çalıştırınca şu çıktıyı alırsınız:
John Doe
Fonksiyon şunları yapar:
first_namevelast_namedeğerlerini alır.title()ile her birinin ilk harfini büyük harfe çevirir.- Ortada bir boşluk olacak şekilde Concatenates eder.
def get_full_name(first_name, last_name):
full_name = first_name.title() + " " + last_name.title()
return full_name
print(get_full_name("john", "doe"))
Düzenleyelim¶
Bu çok basit bir program.
Ama şimdi bunu sıfırdan yazdığınızı hayal edin.
Bir noktada fonksiyon tanımını yazmaya başlamış olacaktınız, parametreler hazır...
Ama sonra "ilk harfi büyük harfe çeviren method"u çağırmanız gerekiyor.
upper mıydı? uppercase miydi? first_uppercase? capitalize?
Sonra eski programcı dostuyla denersiniz: editör autocomplete.
Fonksiyonun ilk parametresi olan first_name'i yazarsınız, sonra bir nokta (.) ve ardından autocomplete'i tetiklemek için Ctrl+Space'e basarsınız.
Ama ne yazık ki, işe yarar bir şey göremezsiniz:

Tipleri ekleyelim¶
Önceki sürümden tek bir satırı değiştirelim.
Fonksiyonun parametreleri olan şu parçayı:
first_name, last_name
şuna çevireceğiz:
first_name: str, last_name: str
Bu kadar.
Bunlar "type hints":
def get_full_name(first_name: str, last_name: str):
full_name = first_name.title() + " " + last_name.title()
return full_name
print(get_full_name("john", "doe"))
Bu, aşağıdaki gibi default değerler bildirmekle aynı şey değildir:
first_name="john", last_name="doe"
Bu farklı bir şey.
Eşittir (=) değil, iki nokta (:) kullanıyoruz.
Ve type hints eklemek, normalde onlarsız ne oluyorsa onu değiştirmez.
Ama şimdi, type hints ile o fonksiyonu oluşturmanın ortasında olduğunuzu tekrar hayal edin.
Aynı noktada, Ctrl+Space ile autocomplete'i tetiklemeye çalışırsınız ve şunu görürsünüz:

Bununla birlikte, seçenekleri görerek kaydırabilirsiniz; ta ki "tanıdık gelen" seçeneği bulana kadar:

Daha fazla motivasyon¶
Şu fonksiyona bakın, zaten type hints içeriyor:
def get_name_with_age(name: str, age: int):
name_with_age = name + " is this old: " + age
return name_with_age
Editör değişkenlerin tiplerini bildiği için, sadece completion değil, aynı zamanda hata kontrolleri de alırsınız:

Artık bunu düzeltmeniz gerektiğini, age'i str(age) ile string'e çevirmeniz gerektiğini biliyorsunuz:
def get_name_with_age(name: str, age: int):
name_with_age = name + " is this old: " + str(age)
return name_with_age
Tipleri bildirmek¶
Type hints bildirmek için ana yeri az önce gördünüz: fonksiyon parametreleri.
Bu, FastAPI ile kullanırken de onları en çok kullanacağınız yerdir.
Basit tipler¶
Sadece str değil, tüm standart Python tiplerini bildirebilirsiniz.
Örneğin şunları kullanabilirsiniz:
intfloatboolbytes
def get_items(item_a: str, item_b: int, item_c: float, item_d: bool, item_e: bytes):
return item_a, item_b, item_c, item_d, item_e
Tip parametreleri ile Generic tipler¶
dict, list, set ve tuple gibi, başka değerler içerebilen bazı veri yapıları vardır. Ve iç değerlerin kendi tipi de olabilir.
İç tipleri olan bu tiplere "generic" tipler denir. Ve bunları, iç tipleriyle birlikte bildirmek mümkündür.
Bu tipleri ve iç tipleri bildirmek için standart Python modülü typing'i kullanabilirsiniz. Bu modül, özellikle bu type hints desteği için vardır.
Python'un daha yeni sürümleri¶
typing kullanan sözdizimi, Python 3.6'dan en yeni sürümlere kadar (Python 3.9, Python 3.10, vb. dahil) tüm sürümlerle uyumludur.
Python geliştikçe, daha yeni sürümler bu type annotations için daha iyi destekle gelir ve çoğu durumda type annotations bildirmek için typing modülünü import edip kullanmanız bile gerekmez.
Projeniz için daha yeni bir Python sürümü seçebiliyorsanız, bu ek sadelikten yararlanabilirsiniz.
Tüm dokümanlarda her Python sürümüyle uyumlu örnekler vardır (fark olduğunda).
Örneğin "Python 3.6+", Python 3.6 veya üstüyle (3.7, 3.8, 3.9, 3.10, vb. dahil) uyumludur. "Python 3.9+" ise Python 3.9 veya üstüyle (3.10 vb. dahil) uyumludur.
Eğer Python'un en güncel sürümlerini kullanabiliyorsanız, en güncel sürüme ait örnekleri kullanın; bunlar en iyi ve en basit sözdizimine sahip olur, örneğin "Python 3.10+".
List¶
Örneğin, str'lerden oluşan bir list olan bir değişken tanımlayalım.
Değişkeni, aynı iki nokta (:) sözdizimiyle bildirin.
Type olarak list yazın.
list, bazı iç tipleri barındıran bir tip olduğundan, bunları köşeli parantez içine yazarsınız:
def process_items(items: list[str]):
for item in items:
print(item)
Bilgi
Köşeli parantez içindeki bu iç tiplere "type parameters" denir.
Bu durumda str, list'e verilen type parameter'dır.
Bu şu demektir: "items değişkeni bir list ve bu listedeki her bir öğe str".
Bunu yaparak, editörünüz listeden öğeleri işlerken bile destek sağlayabilir:

Tipler olmadan, bunu başarmak neredeyse imkansızdır.
item değişkeninin, items listesindeki elemanlardan biri olduğuna dikkat edin.
Ve yine de editör bunun bir str olduğunu bilir ve buna göre destek sağlar.
Tuple ve Set¶
tuple'ları ve set'leri bildirmek için de aynısını yaparsınız:
def process_items(items_t: tuple[int, int, str], items_s: set[bytes]):
return items_t, items_s
Bu şu anlama gelir:
items_tdeğişkeni 3 öğeli birtuple'dır: birint, bir başkaintve birstr.items_sdeğişkeni birset'tir ve her bir öğesibytestipindedir.
Dict¶
Bir dict tanımlamak için, virgülle ayrılmış 2 type parameter verirsiniz.
İlk type parameter, dict'in key'leri içindir.
İkinci type parameter, dict'in value'ları içindir:
def process_items(prices: dict[str, float]):
for item_name, item_price in prices.items():
print(item_name)
print(item_price)
Bu şu anlama gelir:
pricesdeğişkeni birdict'tir:- Bu
dict'in key'leristrtipindedir (örneğin her bir öğenin adı). - Bu
dict'in value'larıfloattipindedir (örneğin her bir öğenin fiyatı).
- Bu
Union¶
Bir değişkenin birkaç tipten herhangi biri olabileceğini bildirebilirsiniz; örneğin bir int veya bir str.
Python 3.6 ve üzeri sürümlerde (Python 3.10 dahil), typing içinden Union tipini kullanabilir ve köşeli parantez içine kabul edilecek olası tipleri yazabilirsiniz.
Python 3.10'da ayrıca, olası tipleri vertical bar (|) ile ayırabildiğiniz yeni bir sözdizimi de vardır.
def process_item(item: int | str):
print(item)
from typing import Union
def process_item(item: Union[int, str]):
print(item)
Her iki durumda da bu, item'ın int veya str olabileceği anlamına gelir.
Muhtemelen None¶
Bir değerin str gibi bir tipi olabileceğini ama aynı zamanda None da olabileceğini bildirebilirsiniz.
Python 3.6 ve üzeri sürümlerde (Python 3.10 dahil), typing modülünden Optional import edip kullanarak bunu bildirebilirsiniz.
from typing import Optional
def say_hi(name: Optional[str] = None):
if name is not None:
print(f"Hey {name}!")
else:
print("Hello World")
Sadece str yerine Optional[str] kullanmak, aslında değer None olabilecekken her zaman str olduğunu varsaydığınız hataları editörün yakalamanıza yardımcı olmasını sağlar.
Optional[Something], aslında Union[Something, None] için bir kısayoldur; eşdeğerdirler.
Bu aynı zamanda Python 3.10'da Something | None kullanabileceğiniz anlamına gelir:
def say_hi(name: str | None = None):
if name is not None:
print(f"Hey {name}!")
else:
print("Hello World")
from typing import Optional
def say_hi(name: Optional[str] = None):
if name is not None:
print(f"Hey {name}!")
else:
print("Hello World")
from typing import Union
def say_hi(name: Union[str, None] = None):
if name is not None:
print(f"Hey {name}!")
else:
print("Hello World")
Union veya Optional kullanmak¶
Python sürümünüz 3.10'un altındaysa, benim oldukça öznel bakış açıma göre küçük bir ipucu:
- 🚨
Optional[SomeType]kullanmaktan kaçının - Bunun yerine ✨
Union[SomeType, None]kullanın ✨.
İkisi eşdeğerdir ve altta aynı şeydir; ama ben Optional yerine Union önermeyi tercih ederim. Çünkü "optional" kelimesi değerin optional olduğunu ima ediyor gibi durur; ama gerçekte anlamı "değer None olabilir"dir. Değer optional olmasa ve hâlâ required olsa bile.
Bence Union[SomeType, None] ne anlama geldiğini daha açık şekilde ifade ediyor.
Bu, tamamen kelimeler ve isimlendirmelerle ilgili. Ancak bu kelimeler, sizin ve ekip arkadaşlarınızın kod hakkında nasıl düşündüğünü etkileyebilir.
Örnek olarak şu fonksiyonu ele alalım:
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
🤓 Other versions and variants
def say_hi(name: str | None):
print(f"Hey {name}!")
name parametresi Optional[str] olarak tanımlanmış, ama optional değil; parametre olmadan fonksiyonu çağıramazsınız:
say_hi() # Oh, no, this throws an error! 😱
name parametresi hâlâ required'dır (optional değildir) çünkü bir default değeri yoktur. Yine de name, değer olarak None kabul eder:
say_hi(name=None) # This works, None is valid 🎉
İyi haber şu ki, Python 3.10'a geçtiğinizde bununla uğraşmanız gerekmeyecek; çünkü tiplerin union'larını tanımlamak için doğrudan | kullanabileceksiniz:
def say_hi(name: str | None):
print(f"Hey {name}!")
🤓 Other versions and variants
from typing import Optional
def say_hi(name: Optional[str]):
print(f"Hey {name}!")
Ve böylece Optional ve Union gibi isimlerle de uğraşmanız gerekmeyecek. 😎
Generic tipler¶
Köşeli parantez içinde type parameter alan bu tiplere Generic types veya Generics denir, örneğin:
Aynı builtin tipleri generics olarak kullanabilirsiniz (köşeli parantez ve içindeki tiplerle):
listtuplesetdict
Ve önceki Python sürümlerinde olduğu gibi typing modülünden:
UnionOptional- ...and others.
Python 3.10'da, Union ve Optional generics'lerini kullanmaya alternatif olarak, tip union'larını bildirmek için vertical bar (|) kullanabilirsiniz; bu çok daha iyi ve daha basittir.
Aynı builtin tipleri generics olarak kullanabilirsiniz (köşeli parantez ve içindeki tiplerle):
listtuplesetdict
Ve typing modülünden gelen generics:
UnionOptional- ...and others.
Tip olarak sınıflar¶
Bir sınıfı da bir değişkenin tipi olarak bildirebilirsiniz.
Örneğin, adı olan bir Person sınıfınız olsun:
class Person:
def __init__(self, name: str):
self.name = name
def get_person_name(one_person: Person):
return one_person.name
Sonra bir değişkeni Person tipinde olacak şekilde bildirebilirsiniz:
class Person:
def __init__(self, name: str):
self.name = name
def get_person_name(one_person: Person):
return one_person.name
Ve sonra, yine tüm editör desteğini alırsınız:

Bunun "one_person, Person sınıfının bir instance'ıdır" anlamına geldiğine dikkat edin.
"one_person, Person adlı class'tır" anlamına gelmez.
Pydantic modelleri¶
Pydantic, data validation yapmak için bir Python kütüphanesidir.
Verinin "shape"'ini attribute'lara sahip sınıflar olarak tanımlarsınız.
Ve her attribute'un bir tipi vardır.
Ardından o sınıfın bir instance'ını bazı değerlerle oluşturursunuz; bu değerleri doğrular, uygun tipe dönüştürür (gerekliyse) ve size tüm veriyi içeren bir nesne verir.
Ve bu ortaya çıkan nesne ile tüm editör desteğini alırsınız.
Resmî Pydantic dokümanlarından bir örnek:
from datetime import datetime
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str = "John Doe"
signup_ts: datetime | None = None
friends: list[int] = []
external_data = {
"id": "123",
"signup_ts": "2017-06-01 12:22",
"friends": [1, "2", b"3"],
}
user = User(**external_data)
print(user)
# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
print(user.id)
# > 123
🤓 Other versions and variants
from datetime import datetime
from typing import Union
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str = "John Doe"
signup_ts: Union[datetime, None] = None
friends: list[int] = []
external_data = {
"id": "123",
"signup_ts": "2017-06-01 12:22",
"friends": [1, "2", b"3"],
}
user = User(**external_data)
print(user)
# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
print(user.id)
# > 123
Bilgi
Daha fazlasını öğrenmek için Pydantic'in dokümanlarına bakın.
FastAPI tamamen Pydantic üzerine kuruludur.
Bunların pratikte nasıl çalıştığını Tutorial - User Guide içinde çok daha fazla göreceksiniz.
İpucu
Pydantic, default value olmadan Optional veya Union[Something, None] kullandığınızda özel bir davranışa sahiptir; bununla ilgili daha fazla bilgiyi Pydantic dokümanlarında Required Optional fields bölümünde okuyabilirsiniz.
Metadata Annotations ile Type Hints¶
Python'da ayrıca, Annotated kullanarak bu type hints içine ek metadata koymayı sağlayan bir özellik de vardır.
Python 3.9'dan itibaren Annotated, standart kütüphanenin bir parçasıdır; bu yüzden typing içinden import edebilirsiniz.
from typing import Annotated
def say_hello(name: Annotated[str, "this is just metadata"]) -> str:
return f"Hello {name}"
Python'un kendisi bu Annotated ile bir şey yapmaz. Editörler ve diğer araçlar için tip hâlâ str'dir.
Ama FastAPI'ye uygulamanızın nasıl davranmasını istediğinize dair ek metadata sağlamak için Annotated içindeki bu alanı kullanabilirsiniz.
Hatırlanması gereken önemli nokta: Annotated'a verdiğiniz ilk type parameter, gerçek tiptir. Geri kalanı ise diğer araçlar için metadatadır.
Şimdilik, sadece Annotated'ın var olduğunu ve bunun standart Python olduğunu bilmeniz yeterli. 😎
İleride bunun ne kadar güçlü olabildiğini göreceksiniz.
İpucu
Bunun standart Python olması, editörünüzde mümkün olan en iyi developer experience'ı almaya devam edeceğiniz anlamına gelir; kodu analiz etmek ve refactor etmek için kullandığınız araçlarla da, vb. ✨
Ayrıca kodunuzun pek çok başka Python aracı ve kütüphanesiyle çok uyumlu olacağı anlamına gelir. 🚀
FastAPI'de type hints¶
FastAPI, birkaç şey yapmak için bu type hints'ten faydalanır.
FastAPI ile type hints kullanarak parametreleri bildirirsiniz ve şunları elde edersiniz:
- Editör desteği.
- Tip kontrolleri.
...ve FastAPI aynı bildirimleri şunlar için de kullanır:
- Gereksinimleri tanımlamak: request path parameters, query parameters, headers, bodies, dependencies, vb.
- Veriyi dönüştürmek: request'ten gerekli tipe.
- Veriyi doğrulamak: her request'ten gelen veriyi:
- Veri geçersiz olduğunda client'a dönen otomatik hatalar üretmek.
- OpenAPI kullanarak API'yi dokümante etmek:
- bu, daha sonra otomatik etkileşimli dokümantasyon kullanıcı arayüzleri tarafından kullanılır.
Bunların hepsi kulağa soyut gelebilir. Merak etmeyin. Tüm bunları Tutorial - User Guide içinde çalışırken göreceksiniz.
Önemli olan, standart Python tiplerini tek bir yerde kullanarak (daha fazla sınıf, decorator vb. eklemek yerine), FastAPI'nin sizin için işin büyük kısmını yapmasıdır.
Bilgi
Tüm tutorial'ı zaten bitirdiyseniz ve tipler hakkında daha fazlasını görmek için geri döndüyseniz, iyi bir kaynak: mypy'nin "cheat sheet"i.