Unix dünyasında Python zaten var... ya da var gibi görünür
Windows dersinde Python'ın sıfırdan kurulduğunu gördün. macOS ve Linux'ta durum farklıdır: işletim sistemi kendi işleri için bir Python'a sahiptir ya da ona benzeyen bir yer tutucu koyar. Bu ders, sistemin Python'ına dokunmadan kendi Python'ını nasıl kuracağını, birden çok sürümü nasıl yöneteceğini ve Linux'ta bir gün mutlaka göreceğin externally-managed-environment hatasını anlatır. Kurulumun kısa hâlini Kurulum ve araçlar dersinde, sanal ortamın (virtual environment) ayrıntısını Sanal ortam ve paket yönetimi dersinde bulursun; burada işletim sistemine özgü kısımlara odaklanıyoruz.
Altın kural: sistem Python'ı işletim sistemine aittir. Ubuntu'nun paket yöneticisi, ağ araçları ve masaüstü bileşenleri /usr/bin/python3'e güvenir. Oraya sudo pip install ile paket eklemek ya da /usr/bin/python3 bağlantısını başka sürüme çevirmek sistemi bozabilir. Senin projelerin her zaman ya ayrı bir kurulumda ya da bir sanal ortamda yaşar.
macOS
Sistem python3 ve Xcode Command Line Tools
Yeni bir Mac'te Terminal'e python3 yazınca çoğu zaman bir pencere açılır: "python3 komutu geliştirici araçlarını gerektiriyor". /usr/bin/python3 aslında bir yer tutucudur; gerçek Python, Apple'ın Xcode Command Line Tools (CLT) paketiyle gelir ve genellikle eski bir sürümdür. CLT yine de gereklidir: derleyici, git ve Homebrew bunlara ihtiyaç duyar.
xcode-select --install # Command Line Tools'u kurar xcode-select -p # kurulu mu? /Library/Developer/CommandLineTools python3 --version # sistem python3 (eski olabilir) which -a python3 # PATH'te bulunan tüm python3'ler, sırayla
macOS 12.3'ten beri python (sürümsüz) komutu yoktur; yalnız python3 vardır. Bir eğitimde python yazıyorsa sen python3 yaz. Sanal ortam etkinken ise python komutu da çalışır, çünkü venv kendi bin/python bağlantısını getirir.
Homebrew ile kurulum
Homebrew, macOS'un fiilî paket yöneticisidir. brew.sh'deki tek satırlık betikle kurulur. Kurulum sonunda ekrana yazılan "Next steps" komutlarını mutlaka çalıştır; yoksa brew: command not found alırsın.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile eval "$(/opt/homebrew/bin/brew shellenv)" brew install python@3.12 python3.12 --version python3.12 -m venv .venv && source .venv/bin/activate
Apple Silicon (M serisi) Mac'lerde Homebrew /opt/homebrew'a, Intel Mac'lerde /usr/local'a kurulur. brew install python@3.12 sana python3.12 komutunu verir; sürümsüz python3 ise Homebrew'un o anki varsayılan Python'ını gösterebilir. Projelerde sürümlü komutu kullanmak sürprizleri önler. Homebrew'un Python'ı da "dışarıdan yönetilen" olarak işaretlidir; global pip install yerine venv kullanman beklenir.
import posixpath
def homebrew_onegi(makine):
return "/opt/homebrew" if makine == "arm64" else "/usr/local"
for makine in ["arm64", "x86_64"]:
onek = homebrew_onegi(makine)
print(f"{makine:7} -> {posixpath.join(onek, 'bin', 'python3.12')}")
Gerçek bilgisayarda platform.machine() bu değeri verir. python.org'un macOS yükleyicisini tercih edersen, kurulumdan sonra /Applications/Python 3.12/ klasöründeki Install Certificates.command dosyasına çift tıkla; yoksa ilk pip install denemende SSL sertifika hatası alabilirsin.
pyenv: sürüm yönetimi
Bir projen 3.11, diğeri 3.12 istiyorsa pyenv her sürümü kaynak koddan derleyip kullanıcı klasörüne kurar ve klasöre göre otomatik geçiş yapar. Bunu PATH'in başına koyduğu shim adlı küçük betiklerle yapar: python yazınca önce shim çalışır, hangi sürümün istendiğine bakar ve onu başlatır.
brew install pyenv # Linux'ta: curl https://pyenv.run | bash echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc echo 'eval "$(pyenv init - zsh)"' >> ~/.zshrc exec "$SHELL" # kabuğu yeniden başlat pyenv install 3.12.4 pyenv global 3.12.4 # varsayılan sürüm (~/.pyenv/version) cd anadolu-rapor && pyenv local 3.11.9 # bu klasöre özel (.python-version dosyası) pyenv versions
pyenv sürümü şu sırayla seçer: PYENV_VERSION ortam değişkeni → bulunduğun klasörde (ya da üst klasörlerde) .python-version dosyası → ~/.pyenv/version (global) → sistem Python'ı. Bu sıra bir "ilk dolu olan kazanır" zinciridir:
def pyenv_secimi(ortam_degiskeni, yerel_dosya, global_dosya):
adaylar = [
("PYENV_VERSION", ortam_degiskeni),
(".python-version", yerel_dosya),
("global", global_dosya),
]
for kaynak, deger in adaylar:
if deger and deger.strip():
return deger.strip(), kaynak
return "system", "sistem"
print(pyenv_secimi(None, "3.11.9\n", "3.12.4"))
print(pyenv_secimi("3.13.0", "3.11.9", "3.12.4"))
print(pyenv_secimi("", None, None))
Linux
Ubuntu / Debian
Ubuntu'da python3 hemen her zaman kuruludur (Ubuntu 24.04'te 3.12). Ama sanal ortam ve pip modülleri ayrı paketlerdir; bu yüzden ilk iş:
sudo apt update sudo apt install python3 python3-venv python3-pip python3 --version python3 -m venv .venv source .venv/bin/activate python -m pip install -r requirements.txt
python3-venv kurulu değilse python3 -m venv "ensurepip is not available" hatası verir. python komutunu istersen sudo apt install python-is-python3 paketi bir bağlantı ekler.
Fedora / RHEL
sudo dnf install python3 python3-pip # venv modülü python3 ile gelir python3 -m venv .venv && source .venv/bin/activate
externally-managed-environment (PEP 668)
Ubuntu 23.04, Debian 12 ve sonrasında (ayrıca Arch ve Homebrew'da) sistem Python'ına pip install yapınca şu hatayı görürsün:
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to install.
Bu bir hata değil, bir korumadır. PEP 668 ile dağıtımlar, Python'ın standart kütüphane klasörüne EXTERNALLY-MANAGED adında bir işaret dosyası koyar; pip bu dosyayı görünce global kurulumu reddeder. Böylece pip ile apt aynı dosyaların üzerine yazıp birbirini bozmaz. Doğru çözümler:
| İhtiyacın | Çözüm | Komut |
|---|---|---|
| Bir proje için kütüphane | Sanal ortam | python3 -m venv .venv; source .venv/bin/activate; pip install pandas |
| Her yerden çalışan bir komut satırı aracı (ruff, black, httpie) | pipx: her aracı kendi gizli venv'ine kurar | sudo apt install pipx; pipx ensurepath; pipx install ruff |
| Dağıtımın paketlediği bir kütüphane | apt | sudo apt install python3-requests |
| "Ne olursa olsun kur" | --break-system-packages | Kullanma: adındaki uyarı gerçektir |
import sysconfig, pathlib, sys
stdlib = pathlib.Path(sysconfig.get_path("stdlib"))
isaret = stdlib / "EXTERNALLY-MANAGED"
print("Standart kütüphane:", stdlib)
print("PEP 668 işareti var mı:", isaret.exists())
print("Sanal ortam mı:", sys.prefix != sys.base_prefix)
if sys.prefix != sys.base_prefix:
print("venv içinde pip serbest; işaret dosyası venv'e uygulanmaz.")
deadsnakes PPA: Ubuntu'da daha yeni Python
Ubuntu LTS sürümleri Python'ı sabit tutar (22.04'te 3.10). Daha yenisi gerekiyorsa topluluğun deadsnakes deposu ek sürümleri yan yana kurar:
sudo add-apt-repository ppa:deadsnakes/ppa sudo apt update sudo apt install python3.13 python3.13-venv python3.13 -m venv .venv
python3'ü yeni sürüme çevirmek apt, ağ yöneticisi ve terminal gibi sistem araçlarını bozabilir. Yeni sürümü her zaman sürümlü adıyla (python3.13) ve bir venv içinde kullan.uv: tek araçla Python ve ortam
uv, Rust ile yazılmış, çok hızlı bir Python paket ve proje yöneticisidir. Python'ın kendisini de indirip kurabildiği için pyenv, venv, pip ve pipx'in işini tek araçta toplar ve üç işletim sisteminde aynı komutlarla çalışır.
curl -LsSf https://astral.sh/uv/install.sh | sh # macOS/Linux (ya da: brew install uv) uv python install 3.12 # Python 3.12'yi indir uv python list # bilinen/kurulu sürümler uv venv --python 3.12 # .venv oluştur source .venv/bin/activate uv pip install pandas # pip ile aynı arayüz, çok daha hızlı uv tool install ruff # pipx benzeri global araç uv run betik.py # ortamı hazırlayıp betiği çalıştır
Hangi yolu ne zaman seçmeli?
| Durum | Önerilen yol | Neden |
|---|---|---|
| Mac'te öğrenmeye başlıyorum | python.org yükleyicisi ya da Homebrew | Basit, belgelenmiş |
| Mac/Linux'ta birden çok sürümle çalışıyorum | uv ya da pyenv | Klasöre göre sürüm, sisteme dokunmaz |
| Ubuntu sunucuda üretim servisi | apt'nin python3'ü + venv | Güvenlik güncellemelerini dağıtım yapar |
| Ubuntu LTS'de daha yeni sürüm lazım | deadsnakes ya da uv | Sistem Python'ı yerinde kalır |
| ruff, black gibi araçları her yerde kullanmak | pipx ya da uv tool | Her araç izole, PEP 668 ile uyumlu |
| Ekip hızlı ve tekrarlanabilir kurulum istiyor | uv (+ uv.lock) | Tek komut, kilit dosyası |
| Uygulamayı konteynerde çalıştıracağım | Resmî python:3.12-slim imajı | Ortam imajla birlikte gelir |
Hangi python3 çalışıyor?
Unix'te PATH klasörleri iki nokta (:) ile ayrılır ve kabuk, Windows'taki gibi soldan sağa ilk eşleşmeyi çalıştırır. which -a python3 hepsini, type python3 çalışacak olanı gösterir. Kabuk bulduğu yolu önbelleğe (cache) alır; PATH'i değiştirdikten sonra garip davranış görürsen hash -r önbelleği temizler.
import posixpath
path_metni = "/home/ayse/.pyenv/shims:/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin"
diskte = {"/opt/homebrew/bin/python3", "/usr/bin/python3", "/home/ayse/.pyenv/shims/python3"}
eslesmeler = [posixpath.join(k, "python3") for k in path_metni.split(":")
if posixpath.join(k, "python3") in diskte]
print("which -a python3:")
for yol in eslesmeler:
print(" ", yol)
print("Çalışacak olan:", eslesmeler[0])
Belirti → neden → çözüm
| Belirti | Neden | Çözüm |
|---|---|---|
python: command not found | Sistemde yalnız python3 var | python3 yaz; Ubuntu'da python-is-python3; venv içinde python zaten var |
error: externally-managed-environment | PEP 668 koruması | venv; araçlar için pipx / uv tool |
ensurepip is not available | python3-venv paketi eksik | sudo apt install python3-venv (ya da python3.12-venv) |
No module named pip | pip paketi kurulmamış | sudo apt install python3-pip ya da venv içinde çalış |
xcrun: error: invalid active developer path | macOS güncellemesi sonrası CLT kayıp | xcode-select --install |
brew: command not found (kurulumdan hemen sonra) | "Next steps" adımı atlandı; /opt/homebrew/bin PATH'te yok | brew shellenv satırını ~/.zprofile'a ekle |
macOS'ta SSL: CERTIFICATE_VERIFY_FAILED | python.org kurulumunun sertifika adımı yapılmadı | Install Certificates.command çalıştır |
pyenv install sonrası No module named '_ssl' ya da '_sqlite3' | Derleme bağımlılıkları eksikti | libssl-dev, libsqlite3-dev, zlib1g-dev, libffi-dev vb. kur, sürümü yeniden derle |
pyenv local çalışmıyor, eski sürüm geliyor | Kabuk başlangıç dosyasına pyenv init eklenmemiş | ~/.zshrc/~/.bashrc satırlarını ekle, exec "$SHELL" |
Permission denied (pip install) | Sistem klasörüne yazmaya çalışıyorsun | sudo kullanma; venv içinde kur |
./betik.py: Permission denied | Dosya çalıştırılabilir değil | chmod +x betik.py ve ilk satıra #!/usr/bin/env python3 |
apt ile python3 ve python3-venv kurmuş, uygulamayı /opt/rota-rapor/.venv içine yerleştirmiş ve systemd servisinde ExecStart=/opt/rota-rapor/.venv/bin/python -m rota_rapor yazmış. Venv'in Python'ını tam yoluyla çağırmak, etkinleştirmeye (source) gerek bırakmaz ve "sunucuda hangi Python çalışıyor" sorusunu ortadan kaldırır. Geliştiriciler ise Mac'lerinde aynı sürümü uv python install 3.12 ile kuruyor.Shebang ve çalıştırılabilir betikler
Unix'te bir betiğin ilk satırı #! ile başlıyorsa (shebang), çekirdek o satırdaki programı yorumlayıcı olarak kullanır. #!/usr/bin/env python3, PATH'teki ilk python3'ü bulur; etkin venv'e ve pyenv'e uyum sağlar. #!/usr/bin/python3 ise hep sistem Python'ını çağırır. Venv içindeki bir betik için en sağlamı venv'in Python'ını tam yoluyla yazmaktır.
import shlex, posixpath
def yorumlayici(ilk_satir):
if not ilk_satir.startswith("#!"):
return None
parcalar = shlex.split(ilk_satir[2:])
if posixpath.basename(parcalar[0]) == "env":
return next(p for p in parcalar[1:] if not p.startswith("-"))
return parcalar[0]
for satir in ["#!/usr/bin/env python3", "#!/usr/bin/python3.12 -u", "#!/usr/bin/env -S python3 -X utf8", "print('merhaba')"]:
print(f"{satir!r:40} -> {yorumlayici(satir)}")
Kabuk başlangıç dosyaları
macOS varsayılan olarak zsh kullanır: oturum açılışında ~/.zprofile, her yeni terminalde ~/.zshrc okunur. Ubuntu bash kullanır: ~/.bashrc. PATH'e eklediğin satırı yanlış dosyaya yazarsan "bir terminalde çalışıyor, ötekinde çalışmıyor" durumu oluşur. Değişiklikten sonra source ~/.zshrc ya da yeni terminal.
pip3 mü, python3 -m pip mi?
pip3, PATH'te ilk bulunan pip'tir ve başka bir Python'a ait olabilir; Homebrew, pyenv ve sistem Python'ı bir arada olduğunda bu sık olur. python3.12 -m pip ise paketin hangi yorumlayıcıya gideceğini kesinleştirir. Venv etkinken pip güvenlidir çünkü venv'in bin klasörü PATH'in en başına eklenmiştir.