24 KiB
Virtual Environments
Python projeleriyle çalışırken, her proje için kurduğunuz package'leri birbirinden izole etmek adına büyük ihtimalle bir virtual environment (veya benzer bir mekanizma) kullanmalısınız.
/// info | Bilgi
Virtual environment'leri, nasıl oluşturulduklarını ve nasıl kullanıldıklarını zaten biliyorsanız bu bölümü atlamak isteyebilirsiniz. 🤓
///
/// tip | İpucu
Virtual environment, environment variable ile aynı şey değildir.
Environment variable, sistemde bulunan ve programların kullanabildiği bir değişkendir.
Virtual environment ise içinde bazı dosyalar bulunan bir klasördür.
///
/// info | Bilgi
Bu sayfada virtual environment'leri nasıl kullanacağınızı ve nasıl çalıştıklarını öğreneceksiniz.
Eğer Python'ı kurmak dahil her şeyi sizin yerinize yöneten bir tool kullanmaya hazırsanız, uv'yi deneyin.
///
Proje Oluşturun
Önce projeniz için bir klasör oluşturun.
Ben genelde home/user klasörümün içinde code adlı bir klasör oluştururum.
Sonra bunun içinde her proje için ayrı bir klasör oluştururum.
// Go to the home directory
$ cd
// Create a directory for all your code projects
$ mkdir code
// Enter into that code directory
$ cd code
// Create a directory for this project
$ mkdir awesome-project
// Enter into that project directory
$ cd awesome-project
Virtual Environment Oluşturun
Bir Python projesi üzerinde ilk kez çalışmaya başladığınızda, projenizin içinde virtual environment oluşturun.
/// tip | İpucu
Bunu her çalıştığınızda değil, proje başına sadece bir kez yapmanız yeterlidir.
///
//// tab | venv
Bir virtual environment oluşturmak için, Python ile birlikte gelen venv modülünü kullanabilirsiniz.
$ python -m venv .venv
/// details | Bu komut ne anlama geliyor
python:pythonadlı programı kullan-m: bir modülü script gibi çalıştır; bir sonraki kısımda hangi modül olduğunu söyleyeceğizvenv: normalde Python ile birlikte kurulu gelenvenvmodülünü kullan.venv: virtual environment'i yeni.venvklasörünün içine oluştur
///
////
//// tab | uv
Eğer uv kuruluysa, onunla da virtual environment oluşturabilirsiniz.
$ uv venv
/// tip | İpucu
Varsayılan olarak uv, .venv adlı bir klasörde virtual environment oluşturur.
Ancak ek bir argümanla klasör adını vererek bunu özelleştirebilirsiniz.
///
////
Bu komut .venv adlı bir klasörün içinde yeni bir virtual environment oluşturur.
/// details | .venv veya başka bir ad
Virtual environment'i başka bir klasörde de oluşturabilirsiniz; ancak buna .venv demek yaygın bir konvansiyondur.
///
Virtual Environment'i Aktif Edin
Oluşturduğunuz virtual environment'i aktif edin; böylece çalıştırdığınız her Python komutu veya kurduğunuz her package onu kullanır.
/// tip | İpucu
Projede çalışmak için yeni bir terminal oturumu başlattığınız her seferinde bunu yapın.
///
//// tab | Linux, macOS
$ source .venv/bin/activate
////
//// tab | Windows PowerShell
$ .venv\Scripts\Activate.ps1
////
//// tab | Windows Bash
Ya da Windows'ta Bash kullanıyorsanız (örn. Git Bash):
$ source .venv/Scripts/activate
////
/// tip | İpucu
Bu environment'e yeni bir package kurduğunuz her seferinde environment'i yeniden aktif edin.
Böylece, o package'in kurduğu bir terminal (CLI) programı kullanıyorsanız, global olarak kurulu (ve muhtemelen ihtiyacınız olandan farklı bir versiyona sahip) başka bir program yerine, virtual environment'inizdeki programı kullanmış olursunuz.
///
Virtual Environment'in Aktif Olduğunu Kontrol Edin
Virtual environment'in aktif olduğunu (bir önceki komutun çalıştığını) kontrol edin.
/// tip | İpucu
Bu opsiyoneldir; ancak her şeyin beklendiği gibi çalıştığını ve hedeflediğiniz virtual environment'i kullandığınızı kontrol etmek için iyi bir yöntemdir.
///
//// tab | Linux, macOS, Windows Bash
$ which python
/home/user/code/awesome-project/.venv/bin/python
Eğer python binary'sini projenizin içinde (bu örnekte awesome-project) .venv/bin/python yolunda gösteriyorsa, tamamdır. 🎉
////
//// tab | Windows PowerShell
$ Get-Command python
C:\Users\user\code\awesome-project\.venv\Scripts\python
Eğer python binary'sini projenizin içinde (bu örnekte awesome-project) .venv\Scripts\python yolunda gösteriyorsa, tamamdır. 🎉
////
pip'i Yükseltin
/// tip | İpucu
uv kullanıyorsanız, pip yerine onunla kurulum yaparsınız; dolayısıyla pip'i yükseltmeniz gerekmez. 😎
///
Package'leri kurmak için pip kullanıyorsanız (Python ile varsayılan olarak gelir), en güncel sürüme yükseltmeniz gerekir.
Bir package kurarken görülen birçok garip hata, önce pip'i yükseltince çözülür.
/// tip | İpucu
Bunu genelde virtual environment'i oluşturduktan hemen sonra bir kez yaparsınız.
///
Virtual environment'in aktif olduğundan emin olun (yukarıdaki komutla) ve sonra şunu çalıştırın:
$ python -m pip install --upgrade pip
---> 100%
/// tip | İpucu
Bazen pip'i yükseltmeye çalışırken No module named pip hatası alabilirsiniz.
Böyle olursa, aşağıdaki komutla pip'i kurup yükseltin:
$ python -m ensurepip --upgrade
---> 100%
Bu komut pip kurulu değilse kurar ve ayrıca kurulu pip sürümünün ensurepip içinde bulunan sürüm kadar güncel olmasını garanti eder.
///
.gitignore Ekleyin
Git kullanıyorsanız (kullanmalısınız), .venv içindeki her şeyi Git'ten hariç tutmak için bir .gitignore dosyası ekleyin.
/// tip | İpucu
Virtual environment'i uv ile oluşturduysanız, bunu zaten sizin için yaptı; bu adımı atlayabilirsiniz. 😎
///
/// tip | İpucu
Bunu virtual environment'i oluşturduktan hemen sonra bir kez yapın.
///
$ echo "*" > .venv/.gitignore
/// details | Bu komut ne anlama geliyor
echo "*": terminale*metnini "yazar" (sonraki kısım bunu biraz değiştiriyor)>:>işaretinin solundaki komutun terminale yazdıracağı çıktı, ekrana basılmak yerine sağ taraftaki dosyaya yazılsın.gitignore: metnin yazılacağı dosyanın adı
Git'te * "her şey" demektir. Yani .venv klasörü içindeki her şeyi ignore eder.
Bu komut, içeriği şu olan bir .gitignore dosyası oluşturur:
*
///
Package'leri Kurun
Environment'i aktif ettikten sonra, içine package kurabilirsiniz.
/// tip | İpucu
Projede ihtiyaç duyduğunuz package'leri ilk kez kurarken veya yükseltirken bunu bir kez yapın.
Bir sürümü yükseltmeniz veya yeni bir package eklemeniz gerekirse tekrar yaparsınız.
///
Package'leri Doğrudan Kurun
Acele ediyorsanız ve projenizin package gereksinimlerini bir dosyada belirtmek istemiyorsanız, doğrudan kurabilirsiniz.
/// tip | İpucu
Programınızın ihtiyaç duyduğu package'leri ve versiyonlarını bir dosyada tutmak (ör. requirements.txt veya pyproject.toml) (çok) iyi bir fikirdir.
///
//// tab | pip
$ pip install "fastapi[standard]"
---> 100%
////
//// tab | uv
Eğer uv varsa:
$ uv pip install "fastapi[standard]"
---> 100%
////
requirements.txt'ten Kurun
Bir requirements.txt dosyanız varsa, içindeki package'leri kurmak için artık onu kullanabilirsiniz.
//// tab | pip
$ pip install -r requirements.txt
---> 100%
////
//// tab | uv
Eğer uv varsa:
$ uv pip install -r requirements.txt
---> 100%
////
/// details | requirements.txt
Bazı package'ler içeren bir requirements.txt şöyle görünebilir:
fastapi[standard]==0.113.0
pydantic==2.8.0
///
Programınızı Çalıştırın
Virtual environment'i aktif ettikten sonra programınızı çalıştırabilirsiniz; program, virtual environment'in içindeki Python'ı ve oraya kurduğunuz package'leri kullanır.
$ python main.py
Hello World
Editörünüzü Yapılandırın
Muhtemelen bir editör kullanırsınız; otomatik tamamlamayı ve satır içi hataları alabilmek için, editörünüzü oluşturduğunuz aynı virtual environment'i kullanacak şekilde yapılandırdığınızdan emin olun (muhtemelen otomatik algılar).
Örneğin:
/// tip | İpucu
Bunu genelde yalnızca bir kez, virtual environment'i oluşturduğunuzda yapmanız gerekir.
///
Virtual Environment'i Devre Dışı Bırakın
Projeniz üzerinde işiniz bittiğinde virtual environment'i deactivate edebilirsiniz.
$ deactivate
Böylece python çalıştırdığınızda, o virtual environment içinden (ve oraya kurulu package'lerle) çalıştırmaya çalışmaz.
Çalışmaya Hazırsınız
Artık projeniz üzerinde çalışmaya başlayabilirsiniz.
/// tip | İpucu
Yukarıdaki her şeyin aslında ne olduğunu anlamak ister misiniz?
Okumaya devam edin. 👇🤓
///
Neden Virtual Environment
FastAPI ile çalışmak için Python kurmanız gerekir.
Sonrasında FastAPI'yi ve kullanmak istediğiniz diğer tüm package'leri kurmanız gerekir.
Package kurmak için genelde Python ile gelen pip komutunu (veya benzeri alternatifleri) kullanırsınız.
Ancak pip'i doğrudan kullanırsanız, package'ler global Python environment'ınıza (Python'ın global kurulumuna) yüklenir.
Problem
Peki package'leri global Python environment'a kurmanın sorunu ne?
Bir noktada, muhtemelen farklı package'lere bağımlı birçok farklı program yazacaksınız. Ayrıca üzerinde çalıştığınız bazı projeler, aynı package'in farklı versiyonlarına ihtiyaç duyacak. 😱
Örneğin philosophers-stone adında bir proje oluşturduğunuzu düşünün; bu program, harry adlı başka bir package'e 1 versiyonu ile bağlı. Yani harry'yi kurmanız gerekir.
flowchart LR
stone(philosophers-stone) -->|requires| harry-1[harry v1]
Sonra daha ileri bir zamanda prisoner-of-azkaban adlı başka bir proje oluşturuyorsunuz; bu proje de harry'ye bağlı, fakat bu proje harry versiyon 3 istiyor.
flowchart LR
azkaban(prisoner-of-azkaban) --> |requires| harry-3[harry v3]
Şimdi sorun şu: package'leri local bir virtual environment yerine global (global environment) olarak kurarsanız, harry'nin hangi versiyonunu kuracağınıza karar vermek zorunda kalırsınız.
philosophers-stone'u çalıştırmak istiyorsanız önce harry versiyon 1'i kurmanız gerekir; örneğin:
$ pip install "harry==1"
Sonuç olarak global Python environment'ınızda harry versiyon 1 kurulu olur.
flowchart LR
subgraph global[global env]
harry-1[harry v1]
end
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) -->|requires| harry-1
end
Fakat prisoner-of-azkaban'ı çalıştırmak istiyorsanız, harry versiyon 1'i kaldırıp harry versiyon 3'ü kurmanız gerekir (ya da sadece 3'ü kurmak, otomatik olarak 1'i kaldırabilir).
$ pip install "harry==3"
Sonuç olarak global Python environment'ınızda harry versiyon 3 kurulu olur.
Ve philosophers-stone'u tekrar çalıştırmaya kalkarsanız, harry versiyon 1'e ihtiyaç duyduğu için çalışmama ihtimali vardır.
flowchart LR
subgraph global[global env]
harry-1[<strike>harry v1</strike>]
style harry-1 fill:#ccc,stroke-dasharray: 5 5
harry-3[harry v3]
end
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) -.-x|⛔️| harry-1
end
subgraph azkaban-project[prisoner-of-azkaban project]
azkaban(prisoner-of-azkaban) --> |requires| harry-3
end
/// tip | İpucu
Python package'lerinde yeni versiyonlarda breaking change'lerden kaçınmak oldukça yaygındır; ancak yine de daha güvenlisi, yeni versiyonları bilinçli şekilde kurmak ve mümkünse test'leri çalıştırıp her şeyin doğru çalıştığını doğrulamaktır.
///
Şimdi bunu, projelerinizin bağımlı olduğu daha birçok başka package ile birlikte düşünün. Yönetmesi epey zorlaşır. Sonunda bazı projeleri package'lerin uyumsuz versiyonlarıyla çalıştırıp, bir şeylerin neden çalışmadığını anlamamak gibi durumlara düşebilirsiniz.
Ayrıca işletim sisteminize (örn. Linux, Windows, macOS) bağlı olarak Python zaten kurulu gelmiş olabilir. Bu durumda, sisteminizin ihtiyaç duyduğu bazı package'ler belirli versiyonlarla önceden kurulu olabilir. Global Python environment'a package kurarsanız, işletim sistemiyle gelen bazı programları bozma ihtimaliniz olabilir.
Package'ler Nereye Kuruluyor
Python'ı kurduğunuzda, bilgisayarınızda bazı dosyalar içeren klasörler oluşturulur.
Bu klasörlerin bir kısmı, kurduğunuz tüm package'leri barındırmaktan sorumludur.
Şunu çalıştırdığınızda:
// Don't run this now, it's just an example 🤓
$ pip install "fastapi[standard]"
---> 100%
Bu, FastAPI kodunu içeren sıkıştırılmış bir dosyayı genellikle PyPI'dan indirir.
Ayrıca FastAPI'nin bağımlı olduğu diğer package'ler için de dosyaları indirir.
Sonra tüm bu dosyaları açar (extract) ve bilgisayarınızdaki bir klasöre koyar.
Varsayılan olarak bu indirilip çıkarılan dosyaları, Python kurulumunuzla birlikte gelen klasöre yerleştirir; yani global environment'a.
Virtual Environment Nedir
Global environment'da tüm package'leri bir arada tutmanın sorunlarına çözüm, çalıştığınız her proje için ayrı bir virtual environment kullanmaktır.
Virtual environment, global olana çok benzeyen bir klasördür; bir projenin ihtiyaç duyduğu package'leri buraya kurarsınız.
Böylece her projenin kendi virtual environment'i (.venv klasörü) ve kendi package'leri olur.
flowchart TB
subgraph stone-project[philosophers-stone project]
stone(philosophers-stone) --->|requires| harry-1
subgraph venv1[.venv]
harry-1[harry v1]
end
end
subgraph azkaban-project[prisoner-of-azkaban project]
azkaban(prisoner-of-azkaban) --->|requires| harry-3
subgraph venv2[.venv]
harry-3[harry v3]
end
end
stone-project ~~~ azkaban-project
Virtual Environment'i Aktif Etmek Ne Demek
Bir virtual environment'i örneğin şununla aktif ettiğinizde:
//// tab | Linux, macOS
$ source .venv/bin/activate
////
//// tab | Windows PowerShell
$ .venv\Scripts\Activate.ps1
////
//// tab | Windows Bash
Ya da Windows'ta Bash kullanıyorsanız (örn. Git Bash):
$ source .venv/Scripts/activate
////
Bu komut, sonraki komutlarda kullanılabilecek bazı environment variable{.internal-link target=_blank}'ları oluşturur veya değiştirir.
Bunlardan biri PATH değişkenidir.
/// tip | İpucu
PATH environment variable hakkında daha fazla bilgiyi Environment Variables{.internal-link target=_blank} bölümünde bulabilirsiniz.
///
Bir virtual environment'i aktive etmek, onun .venv/bin (Linux ve macOS'ta) veya .venv\Scripts (Windows'ta) yolunu PATH environment variable'ına ekler.
Diyelim ki environment'i aktive etmeden önce PATH değişkeni şöyleydi:
//// tab | Linux, macOS
/usr/bin:/bin:/usr/sbin:/sbin
Bu, sistemin programları şu klasörlerde arayacağı anlamına gelir:
/usr/bin/bin/usr/sbin/sbin
////
//// tab | Windows
C:\Windows\System32
Bu, sistemin programları şurada arayacağı anlamına gelir:
C:\Windows\System32
////
Virtual environment'i aktive ettikten sonra PATH değişkeni şuna benzer hale gelir:
//// tab | Linux, macOS
/home/user/code/awesome-project/.venv/bin:/usr/bin:/bin:/usr/sbin:/sbin
Bu, sistemin artık programları önce şurada aramaya başlayacağı anlamına gelir:
/home/user/code/awesome-project/.venv/bin
diğer klasörlere bakmadan önce.
Dolayısıyla terminale python yazdığınızda, sistem Python programını şurada bulur:
/home/user/code/awesome-project/.venv/bin/python
ve onu kullanır.
////
//// tab | Windows
C:\Users\user\code\awesome-project\.venv\Scripts;C:\Windows\System32
Bu, sistemin artık programları önce şurada aramaya başlayacağı anlamına gelir:
C:\Users\user\code\awesome-project\.venv\Scripts
diğer klasörlere bakmadan önce.
Dolayısıyla terminale python yazdığınızda, sistem Python programını şurada bulur:
C:\Users\user\code\awesome-project\.venv\Scripts\python
ve onu kullanır.
////
Önemli bir detay: virtual environment yolu PATH değişkeninin en başına eklenir. Sistem, mevcut başka herhangi bir Python'ı bulmadan önce bunu bulur. Böylece python çalıştırdığınızda, başka bir python (örneğin global environment'tan gelen python) yerine virtual environment'taki Python kullanılır.
Virtual environment'i aktive etmek birkaç şeyi daha değiştirir; ancak yaptığı en önemli işlerden biri budur.
Virtual Environment'i Kontrol Etmek
Bir virtual environment'in aktif olup olmadığını örneğin şununla kontrol ettiğinizde:
//// tab | Linux, macOS, Windows Bash
$ which python
/home/user/code/awesome-project/.venv/bin/python
////
//// tab | Windows PowerShell
$ Get-Command python
C:\Users\user\code\awesome-project\.venv\Scripts\python
////
Bu, kullanılacak python programının virtual environment'in içindeki Python olduğu anlamına gelir.
Linux ve macOS'ta which, Windows PowerShell'de ise Get-Command kullanırsınız.
Bu komutun çalışma mantığı şudur: PATH environment variable içindeki her yolu sırayla dolaşır, python adlı programı arar. Bulduğunda, size o programın dosya yolunu gösterir.
En önemli kısım şu: python dediğinizde çalışacak olan "python" tam olarak budur.
Yani doğru virtual environment'da olup olmadığınızı doğrulayabilirsiniz.
/// tip | İpucu
Bir virtual environment'i aktive etmek kolaydır; sonra o Python ile kalıp başka bir projeye geçmek de kolaydır.
Bu durumda ikinci proje, başka bir projenin virtual environment'ından gelen yanlış Python'ı kullandığınız için çalışmayabilir.
Hangi python'ın kullanıldığını kontrol edebilmek bu yüzden faydalıdır. 🤓
///
Neden Virtual Environment'i Deactivate Edelim
Örneğin philosophers-stone projesi üzerinde çalışıyor olabilirsiniz; o virtual environment'i aktive eder, package kurar ve o environment ile çalışırsınız.
Sonra başka bir proje olan prisoner-of-azkaban üzerinde çalışmak istersiniz.
O projeye gidersiniz:
$ cd ~/code/prisoner-of-azkaban
Eğer philosophers-stone için olan virtual environment'i deactivate etmezseniz, terminalde python çalıştırdığınızda philosophers-stone'dan gelen Python'ı kullanmaya çalışır.
$ cd ~/code/prisoner-of-azkaban
$ python main.py
// Error importing sirius, it's not installed 😱
Traceback (most recent call last):
File "main.py", line 1, in <module>
import sirius
Ama virtual environment'i deactivate edip prisoner-of-askaban için yeni olanı aktive ederseniz, python çalıştırdığınızda prisoner-of-azkaban içindeki virtual environment'dan gelen Python kullanılır.
$ cd ~/code/prisoner-of-azkaban
// You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project 😎
$ deactivate
// Activate the virtual environment in prisoner-of-azkaban/.venv 🚀
$ source .venv/bin/activate
// Now when you run python, it will find the package sirius installed in this virtual environment ✨
$ python main.py
I solemnly swear 🐺
Alternatifler
Bu, başlamanız için basit bir rehber ve alttaki mekanizmaların nasıl çalıştığını öğretmeyi amaçlıyor.
Virtual environment'leri, package bağımlılıklarını (requirements) ve projeleri yönetmek için birçok alternatif vardır.
Hazır olduğunuzda ve package bağımlılıkları, virtual environment'ler vb. dahil tüm projeyi yönetmek için bir tool kullanmak istediğinizde, uv'yi denemenizi öneririm.
uv birçok şey yapabilir, örneğin:
- Sizin için Python kurabilir, farklı sürümler dahil
- Projelerinizin virtual environment'ini yönetebilir
- Package kurabilir
- Projeniz için package bağımlılıklarını ve versiyonlarını yönetebilir
- Bağımlılıkları dahil, kurulacak package ve versiyonların tam (exact) bir setini garanti edebilir; böylece geliştirirken bilgisayarınızda çalıştırdığınız projeyi production'da da birebir aynı şekilde çalıştırabileceğinizden emin olursunuz; buna locking denir
- Ve daha birçok şey
Sonuç
Buradaki her şeyi okuduysanız ve anladıysanız, artık birçok geliştiriciden çok daha fazla virtual environment bilgisine sahipsiniz. 🤓
Bu detayları bilmek, ileride karmaşık görünen bir sorunu debug ederken büyük olasılıkla işinize yarayacak; çünkü altta nasıl çalıştığını biliyor olacaksınız. 😎