Python’a Derinlemesine Dalış | Virtual Environments

Sanal Ortamlar üzerine bir inceleme

Adem Ok
19 min readMay 10, 2023
Kaynak : https://unsplash.com/photos/toA-KC8Kwys

Merhabalar yazımda, Python projelerimiz için ayrı sanal ortamlar oluşturmak ve yönetmek üzere Python’un venv modülüyle nasıl çalışacağımızı öğreneceğiz. Her ortam(environment), paket bağımlılıklarını ve Python’ın farklı sürümlerini kullanabilir. Sanal ortamlarla çalışmayı deneyimledikten sonra, projelerimizin asla birbirleri için bağımlılık çakışmalarına neden olmadığını gözlemleyeceğiz.

Bu keşif sonunda , gözlemleyeceğimiz konular:

Bir Python sanal ortamı oluşturmak ve etkinleştirmek

Dış bağımlılıkları neden izole etmek istediğimizi açıklamak

Sanal bir ortam oluşturduğumuzda Python’ın ne yaptığını görselleştirmek

Sanal ortamları devre dışı bırakmak ve kaldırmak

Python sürümlerimizi ve sanal ortamlarımızı yönetmek için ek araçlar seçmek

Sanal ortamlar, Python geliştirmede kullanılan yaygın ve etkili bir tekniktir. Nasıl çalıştıklarını, neden onlara ihtiyaç duyduğumuzu ve onlarla neler yapabileceğimizi daha iyi anlamak, Python programlama iş akışımızda uzmanlaşmamıza yardımcı olacaktır.

Python Sanal Ortamıyla Nasıl Çalışabiliriz?

En sevdiğimiz proje üzerinde çalışmaya devam etmek için bir Python sanal ortamını kurup çalıştırmamız gerekiyorsa, bu keşif yazısı bizim için faydalı olabilir.

Bu yazıdaki temel iskelet venv modülü üzerinedir.Bu modül, Python’un standart kitaplığının bir parçasıdır.

Not: Bu yazıda daha sonra hakkında daha fazla bilgi edinebileceğimiz, conda ve virtualenv gibi sanal ortamlar oluşturmaya yönelik başka harika üçüncü şahıs araçlar da vardır. Bu araçlardan herhangi biri bir Python sanal ortamı kurmamıza yardımcı olabilir.

Temel kullanım için, venv mükemmel bir seçimdir çünkü zaten Python kurulumumuzla birlikte varsayılan olarak gelir. Bunu göz önünde bulundurarak, bu yazıda ilk sanal ortamımızı oluşturmaya hazırız.

Devam 😊

Yaratım

Pip ile kurduğumuz dış bağımlılıkları kullanan bir Python projesi üzerinde her çalıştığımızda, önce bir sanal ortam oluşturmak önemlidir:

python -m venv venv

Windows’ta Python kullanıyorsak ve PATH ile PATHEXT değişkenlerini yapılandırmadıysak Python yürütülebilir dosyamızın tam yolunu sağlamamız gerekebilir:

C:\Users\Name\AppData\Local\Programs\Python\Python310\python -m venv venv

Yukarıda gösterilen sistem yolu, Python indirme sayfası tarafından sağlanan Windows yükleyiciyi kullanarak Python 3.10'u yüklediğimizi varsayar. Sistemimizde yürütülebilir Python dosyasına giden yol farklı olabilir. PowerShell ile çalışırken, where.exe python komutunu kullanarak yolu bulabiliriz.

Aktifleştirmek

Harika! Artık projemizin kendi sanal ortamı var. Genel olarak, kullanmaya başlamadan önce, kurulumla birlikte gelen bir komut dosyasını çalıştırarak ortamı etkinleştirebiliriz:

venv\Scripts\activate

Bu komutu çalıştırmadan önce, az önce oluşturduğumuz sanal ortamı içeren klasörde olduğumuzdan emin olalım.

Komut satırında sanal ortamımızın adını (bu durumda (venv)) görebildiğimizde, sanal ortamımızın etkin olduğunu görmüş oluruz. Artık harici paketleri yüklemeye hazırız. 😎👌

Paket Yükleme Aşaması

Sanal ortamımızı oluşturup etkinleştirdikten sonra, artık projemiz için ihtiyaç duyduğumuz harici bağımlılıkları kurabiliriz:

python -m pip install <package-name>

Bu komut, pip ile harici Python paketlerini kurmak için kullanmamız gereken varsayılan komuttur. Sanal ortamı ilk biz oluşturup etkinleştirdiğimiz için, pip paketleri yalıtılmış bir konuma kuracaktır.

Sanal ortamımızı bir Python 3 sürümü kullanarak oluşturduğumuz için, açıkça python3 veya pip3'ü çağırmamız gerekmez. Sanal ortamımız etkin olduğu sürece, python ve pip, python3 ve pip3'ün yaptığı aynı yürütülebilir dosyalara bağlanır.

Artık paketlerimizi sanal ortamımıza kurabiliriz. Bu noktaya gelmek için, venv adlı bir Python sanal ortamı oluşturarak başladık ve ardından onu mevcut etkileşimli kabuk oturumumuzda etkinleştirdiniz.

Terminalimizi kapatmadığımız sürece, kuracağımız her Python modülü, global Python site-packages yerine bu izole ortamda bulunacaktır. Bu, artık bağımlılık çakışmaları hakkında endişelenmeden Python projemiz üzerinde çalışabileceğimiz anlamına gelir. 😊

Pasifleştirme Aşaması

deactivate komutunu yürüttükten sonra, ortam base platformuna döner. Bu değişiklik, sanal ortamımızdan çıktığımız anlamına gelir. Şimdi Python veya pip ile etkileşim kurarsak, global olarak yapılandırılmış Python ortamımızla etkileşim kurmuş oluruz.

Daha önce oluşturduğumuz bir sanal ortama geri dönmek istersek, o sanal ortamın aktivasyon komut dosyasını tekrar çalıştırmamız gerekir.

Sanal Ortamlara Neden İhtiyaç Duyarız?

Python topluluğundaki neredeyse herkes, tüm projelerimiz için sanal ortamlar kullanmamızı önerir.

Ama neden?

Kısa cevap, Python’un bağımlılık yönetiminde harika olmadığında yatar. pip kurduğumuz tüm harici (external) paketleri temel Python kurulumumuzda site-packages/ adlı bir klasöre yerleştirecektir.

Teknik olarak, Python iki site-packages klasörüyle gelir:

  • purelib/ yalnızca saf(pure) Python kodunda yazılmış modülleri içerir
  • platlib/ saf Python’da yazılmamış binary dosyalar, örneğin .dll, .so veya .pydist dosyaları içerir

Bununla birlikte, çoğu işletim sistemi Python’un site-packages konfigürasyonunu uygular, böylece her iki konum da aynı yolu işaret ederek etkili bir şekilde tek bir site-package klasörü oluşturur.

Büyük olasılıkla, her iki çıktı da bize aynı yolu gösterecektir. Her iki çıktı da aynıysa, işletim sistemimiz purelib modüllerini platlib modüllerinden farklı bir klasöre koymaz. İki farklı yol çıkıyorsa işletim sistemimiz bu ayrımı yapıyor demektir.

İşletim sistemimiz ikisi arasında ayrım yapsa bile, tüm purelib modülleri tek bir konuma gideceğinden ve aynı şey platlib modüllerinde de olacağından bağımlılık çakışmaları ortaya çıkacaktır.

Sanal ortamlarla çalışmak için, tek bir site-package klasörünün veya iki ayrı klasörün uygulama ayrıntılarını düşünmemize gerek yoktur. Aslında, muhtemelen bir daha asla düşünmemize gerek kalmayacak. Bununla birlikte, istersek, birisi Python’un site-package dizininden bahsettiğinde, iki farklı dizinden bahsediyor olabileceğini aklımızda bulundurabiliriz.

Sidestep Bağımlılık Çakışmaları

Projelerimizden biri, diğerinden farklı bir harici kütüphane versiyonu gerektirebilir. Paketleri yüklemek için tek bir yerimiz varsa, aynı kütüphanenin iki farklı versiyonuyla çalışamayız. Bu durum Python sanal ortamı kullanma ihtiyacımızın başlıca nedenlerinden biridir.

Bunun neden bu kadar önemli olduğunu daha iyi anlamak için, iki farklı müşteri için Django web siteleri oluşturduğumuzu hayal edelim. Bir müşteri, başlangıçta Django 2.2.26 kullanarak oluşturduğumuz mevcut web uygulamasından memnun ve bu müşteri, projesini modern bir Django sürümüne güncellemeyi reddediyor. Başka bir müşteri, web sitesine yalnızca Django 4.0'dan itibaren kullanılabilen zaman uyumsuz işlevsellik eklememizi istiyor.

Django’yu global olarak kurduysak, iki versiyondan yalnızca birine sahip olabiliriz:

python -m pip install django==2.2.26
python -m pip list
Package Version
---------- -------
Django 2.2.26
pip 22.0.4
pytz 2022.1
setuptools 58.1.0
sqlparse 0.4.2
python -m pip install django==4.0.3
python -m pip list
Package Version
---------- -------
asgiref 3.5.0
Django 4.0.3
pip 22.0.4
pytz 2022.1
setuptools 58.1.0
sqlparse 0.4.2
tzdata 2022.1

Yukarıda görüldüğü gibi global’e kurulan django versiyonlarının tekil tutulduğu gözlemleniyor.

Global Python ortamımıza aynı paketin iki farklı versiyonunu kurarsak, ikinci kurulum birincinin üzerine yazar yani onu ezer. Aynı nedenle, her iki istemci için de tek bir sanal ortama sahip olmak da işe yaramaz. Tek bir Python ortamında aynı paketin iki farklı versiyonuna sahip olamayız.

Görünüşe göre bu kurulumdan sonra iki projeden biri üzerinde çalışamayacağız. Ancak, müşterilerimizin projelerinin her biri için sanal izole bir ortam oluşturursak, her birine farklı bir Django versiyonu kurabiliriz:

İki sanal ortamdan birini etkinleştirirsek, o zaman onun hala kendi özel Django versiyonunu elinde tuttuğunu fark edeceğiz. İki ortamın da farklı bağımlılıkları vardır ve her biri yalnızca Django’nun o versiyonu için gerekli olan bağımlılıkları içerir.

Bu kurulumla, bir proje üzerinde çalışırken bir ortamı, başka bir proje üzerinde çalışırken başka bir ortamı etkinleştirebiliriz.

Tüm paketlerimiz tek bir konumda bulunuyorsa, yalnızca tek bir projeyle ilgili bağımlılıkları sabitlemek zor olacaktır.

Bir süre Python ile çalıştıysak, global Python ortamımız zaten her tür üçüncü şahıs paketini içeriyor olabilir.

Bir Python ortamını birden çok projede paylaşırken karşılaşabileceğimiz yeniden üretilebilirlik sorunlarının neler olduğunu açıklığa kavuşturmak için, bundan sonra örnek bir durumu inceleyeceğiz.İki bağımsız projede çalıştığımızı hayal edelim:

  1. Pandas ile Veri Analizi Projesi
  2. PySpark ile Büyük Veri Analizi Projesi

Sanal ortamlardan habersiz, gerekli tüm paketleri global Python ortamımıza kurduk:python -m pip install beautifulsoup4 requests
python -m pip install flask

python -m pip install pandas
python -m pip install pyspark

Veri analizi uygulamamızın oldukça yararlı olduğu ortaya çıktı, bu nedenle diğer geliştiriciler de üzerinde çalışmak istiyor. Üzerinde çalışmak için kullandığımız ortamı yeniden üretmeleri gerekir. Devam etmek ve projemizi çevrimiçi paylaşabilmek için bağımlılıklarımızı sabitlemek istiyoruz:

python -m pip freeze
beautifulsoup4==4.10.0
certifi==2021.10.8
charset-normalizer==2.0.12
click==8.0.4
colorama==0.4.4
Flask==2.0.3
idna==3.3
itsdangerous==2.1.1
Jinja2==3.0.3
MarkupSafe==2.1.1
requests==2.27.1
soupsieve==2.3.1
urllib3==1.26.9
Werkzeug==2.0.3
pandas==2.0.0
pyspark== 3.4.0

Bu paketlerden hangileri veri analizi uygulamamızla alakalı ve hangileri büyük veri projemiz nedeniyle burada?

Tüm dış bağımlılıkların tek bir platfromda yaşadığını söylemek zor.

Bunun gibi tek bir ortamla, bağımlılıkları manuel olarak gözden geçirmemiz ve projemiz için hangilerinin gerekli, hangilerinin olmadığını bilmemiz gerekir.

Projelerimizin her biri için ayrı bir sanal ortam kullanıyorsak, sabitlenmiş bağımlılıklarımızdan proje gereksinimlerini okumak daha kolay olacaktır. Bu, harika bir uygulama geliştirdiğimizde başarımızı paylaşabileceğimiz ve başkalarının bizimle işbirliği yapmasını mümkün kılabileceği anlamına gelir!

Sanal ortamlar kullanıyorsak, kullanıcı ayrıcalıklarımız kapsamında harici paketler kurmamıza ve bunlarla çalışmamıza olanak tanıyan yeni bir kurulum konumu oluştururuz.

İster kendi makinemizde hobi olarak kodlama yapalım, ister müşterilerimiz için web siteleri geliştirelim, ister kurumsal bir ortamda çalışalım, sanal bir ortam kullanmak bizi uzun vadede birçok dertten kurtaracaktır.

Python Sanal Ortamı Nedir?

Sanal bir ortam kullandığımızda ne ile çalışıyorsunuz? Python sanal ortamlarının ne olduğunu anlamak istiyorsak biraz daha detaya dalalım.

Python sanal ortamının ne olduğu sorusunun kısa cevabı;

Bir Python sanal ortamının, hafif ama yalıtılmış bir Python ortamını çalıştırmak için ihtiyacımız olan her şeyi bize veren bir klasör yapısı olduğudur.

Klasör Yapısı

venv modülünü kullanarak yeni bir sanal ortam oluşturduğumuzda, Python bağımsız bir klasör yapısı oluşturur ve Python yürütülebilir dosyalarını bu klasör yapısına kopyalar veya sembolik bağlar kurar.

Detaylamasına incelememizi aşağıdaki gibi yapalım;

Sanal Ortam Dosya Yapısı;

Komut satırımızda, sanal ortamımızı içeren klasöre gidelim. Derin bir nefes alalım ve kendimizi motive edelim, ardından dizinin tüm içeriğini görüntülemek için tree komutunu çalıştırın:

tree venv /F

tree komutu, venv dizininin içeriğini çok uzun bir ağaç yapısında görüntüler.

Fakat venv/ klasörünün tüm içeriğini görüntülersek, ne bulduğumuza şaşırabiliriz. Çünkü orada çok sayıda dosya vardır.

Bir sanal ortam klasörü çok sayıda dosya ve klasör içerir, ancak bu ağaç yapısını bu kadar uzun yapan şeylerin çoğunun site-packages/ klasörünün içinde olduğunu fark edebiliriz. Oradaki alt klasörleri ve dosyaları kırparsak, daha yalın bir ağaç yapısı elde ederiz:

Bu yalınlatılmış ağaç yapısı, sanal ortam klasörümüzde neler olup bittiğine dair daha iyi bir genel bakış sunar:

venv\

├── Include\

├── Lib\
│ │
│ └── site-packages\
│ │
│ ├── _distutils_hack\
│ │
│ ├── pip\
│ │
│ ├── pip-22.0.4.dist-info\
│ │
│ ├── pkg_resources\
│ │
│ ├── setuptools\
│ │
│ ├── setuptools-58.1.0.dist-info\
│ │
│ └── distutils-precedence.pth


├── Scripts\
│ ├── Activate.ps1
│ ├── activate
│ ├── activate.bat
│ ├── deactivate.bat
│ ├── pip.exe
│ ├── pip3.10.exe
│ ├── pip3.exe
│ ├── python.exe
│ └── pythonw.exe

└── pyvenv.cfg

Include\ Python’un C uzantılarına bağlı olarak yükleyebileceğiniz paketler için C başlık dosyalarını dahil etmek için kullandığı, başlangıçta boş bir klasördür.

Lib\ Sanal ortamımızı oluşturmamızın ana nedenlerinden biri olan site-packages\ klasörünü içerir. Bu klasör, sanal ortamımızda kullanmak istediğimiz harici paketleri kuracağımız yerdir. Varsayılan olarak, sanal ortamımız pip ve setuptools olmak üzere iki bağımlılıkla önceden yüklenmiş olarak gelir. Birazdan onlar hakkında daha fazla şey öğreneceğiz.

Scripts\ Sanal ortamımızın yürütülebilir (executable) dosyalarını içerir. En dikkate değer Python yorumlayıcısı (python.exe), çalıştırılabilir pip dosyası (pip.exe) ve farklı kabuklarla çalışmamıza izin vermek için birkaç farklı türde gelen sanal ortamımız için activation komut dosyasıdır. Bu yazıda, çoğu kabukta Windows için sanal ortamımızın etkinleştirilmesini yöneten activate komutunu kullandım.

pyvenv.cfg sanal ortamımız için çok önemli bir dosyadır. Python’un, geçerli Python oturumunun hangi Python yorumlayıcısını ve hangi site paketleri dizinini kullanacağını belirleyen değişkenleri sys modülünde ayarlamak için kullandığı yalnızca birkaç key-value çifti içerir. Sanal ortamın nasıl çalıştığını okuduğumuzda bu dosyadaki konfigürasyonlar hakkında daha fazla bilgi edineceğiz.

Sanal ortam klasörümüzün içeriğinin bu kuşbakışı görünümünden, bir Python sanal ortamının üç temel parçası olduğunu keşfetmek için daha da uzaklaşabiliriz:

-Python ikili dosyasının bir kopyası veya sembolik bağlantısı

-Bir pyvenv.cfg dosyası

-Bir site-packages dizini

site-packages\ içinde kurulu paketler isteğe bağlıdır, ancak makul bir varsayılan olarak gelir. Fakat, bu dizin boş olsaydı, sanal ortamımız yine de geçerli bir sanal ortam olurdu ve herhangi bir bağımlılık kurmadan onu oluşturmanın yolları vardır.

Varsayılan ayarlarla, venv hem pip hem de setuptools’u yükleyecektir. Pip kullanmak, Python’da paketleri kurmanın önerilen yoludur ve setuptools, pip için bir bağımlılıktır. Diğer paketleri yüklemek, Python sanal ortamları için en yaygın kullanım durumu olduğundan, pip erişimine sahip olmak isteyeceğiz.

pip listesini kullanarak Python’ın hem pip hem de setuptools’u sanal ortamınıza yüklediğini tekrar kontrol edebiliriz:

Yukarıdaki görselde sanal ortamımızda yüklü olan paketleri gözlemledik.

Versiyon numaraları farklı olabilir, ancak bu çıktı, sanal ortamı varsayılan ayarlarla oluşturduğumuzda Python’un her iki paketi de yüklediğini onaylar.

Pip ve setuptools için {name}-{version}.dist-info/ dizinleri, kurulu paketler hakkındaki bilgileri kaydetmek için var olan paket dağıtım bilgilerini içerir.

Bütünlük adına bu ek dosya ve klasörleri öğreniyoruz. Sanal ortamlarmızla etkili bir şekilde çalışmak için bunları hatırlamamız gerekmeyecek. site-packages/dizinimizde önceden yüklenmiş paketlerin, diğer paketlerin yüklenmesini daha kullanıcı dostu hale getiren standart araçlar olduğunu akılda tutmamız yeterlidir.

Bu noktada, yerleşik venv modülünü kullanarak kurduysak, bir Python sanal ortamını oluşturan tüm dosya ve klasörleri görmüşsüzdür.

Sanal ortamımızın sadece bir klasör yapısı olduğunu, yani onu istediğimiz zaman silip yeniden oluşturabileceğimizi unutmayalım.

Peki neden bu özel klasör yapısı ve bu neyi mümkün kılıyor?

İzole Python Kurulumu

Python sanal ortamları, hızlı bir şekilde oluşturabileceğimiz ve artık ihtiyacımız olmadığında atabileceğimiz light, yalıtılmış bir Python ortamı sağlamayı amaçlar. Yukarıda gördüğümüz klasör yapısı, üç temel parça sağlayarak bunu mümkün kılar:

  • Python binary dosyasının bir kopyası veya sembolik bağlantısı
  • Bir pyvenv.cfg dosyası
  • Bir site-packages dizininden

Yüklediğimiz herhangi bir harici paketin global site-packages ile çakışmaması için yalıtılmış bir ortam elde etmek istiyoruz. Venv’in bunu mümkün kılmak için yaptığı şey;

Standart bir Python kurulumunun oluşturduğu klasör yapısını yeniden oluşturmaktır.

Bu yapı, Python binary dosyasının ve Python’un harici paketleri kurduğu site-packages dizininin kopyasının veya sembolik bağlantısının konumunu açıklar.

Ayrıca Python binary dosyasına ve site-packages dizinine ek olarak, pyvenv.cfg dosyası yalnızca birkaç anahtar/değer çifti içeren küçük bir dosyadır. Ancak, bu ayarlar sanal ortamımızın çalışması için çok önemlidir:

Yeni oluşturduğumuz sanal ortamımızın klasör yapısını yakından incelediğimizi varsayalım. Bu durumda, bu basit kurulumun güvenilir standart kitaplık modüllerinden hiçbirini içermediğini fark edebiliriz.

Ancak Python yorumlayıcısını sanal ortamımızdan başlatırsak standart kitaplıktan tüm özelliklere erişmeye devam edebiliriz:

Yukarıdaki örnek kod parçacığında, hem ppprint modülünü hem urllib modülünü hem de pp() metodunu başarıyla içe aktarabildik. Sonra urllib modülünü incelemek için dir() metodunu kullandık.

Her iki modül de standart kitaplığın parçasıdır, peki Python sanal ortamımızın klasör yapısında olmasalar bile bunlara nasıl oluyor da erişebiliyoruz?

Python’ın standart kitaplık modüllerine erişebiliriz, çünkü sanal ortamımız Python’ın yerleşiklerini ve sanal ortamımızı oluşturduğumuz Python kurulumundaki standart kitaplık modüllerini yeniden kullanır.

Sanal ortamımızı oluşturmak için her zaman mevcut bir Python kurulumuna ihtiyacımız olduğundan venv, yeni sanal ortamımıza kopyalama ek yükünden kaçınmak için mevcut standart kitaplık modüllerini yeniden kullanmayı tercih eder.

Standart kitaplık modüllerine ek olarak, ortamı oluştururken bir bağımsız değişken aracılığıyla isteğe bağlı olarak sanal ortamımıza temel kurulumun site-packages erişim izni verebiliriz:

Venv’i çağırdığımızda — system-site-packages eklersek Python, pyvenv.cfg’deki include-system-site-packages değerini true olarak ayarlar. Bu ayar, temel Python’ımıza kurduğunuz tüm harici paketleri sanal ortamımıza kurmuş gibi kullanabileceğimiz anlamına gelir.

Bu bağlantı sadece bir yönde çalışır. Sanal ortamımıza kaynak Python’ın site-packages klasörüne erişim izni versek bile, sanal ortamımıza yüklediğimiz hiçbir yeni paket oradaki paketlerle karışmaz. Python, sanal ortamımıza yapılan kurulumların yalıtılmış doğasına saygı gösterecek ve bunları sanal ortamdaki ayrı site-packages dizinine yerleştirecektir.

Bir Python sanal ortamının yalnızca konfigürasyon dosyası içeren bir klasör yapısı olduğunu gördük. Önceden yüklenmiş pip ile gelebilir veya gelmeyebilir ve yalıtılmış kalırken kaynak Python’un site packages dizinine erişimi vardır.

Sanal Ortam Nasıl Çalışır?

Burada, pyvenv.cfg dosyamızdaki klasör yapısının ve ayarların, harici bağımlılıkları kurmak için yeniden üretilebilir ve yalıtılmış bir alan sağlamak üzere Python ile nasıl etkileşime girdiğini inceleyeceğiz.

venv kullanarak bir sanal ortam oluşturduğumuzda.Modül ,işletim sistemimizde standart bir Python kurulumunun dosya ve klasör yapısını yeniden oluşturur. Python ayrıca kendi adlandırdığımız Python yürütülebilir dosyasını bu klasör yapısına kopyalar veya sembolik bağlar kurar:


venv\

├── Include\

├── Lib\
│ │
│ └── site-packages\

├── Scripts\
│ ├── Activate.ps1
│ ├── activate
│ ├── activate.bat
│ ├── deactivate.bat
│ ├── pip.exe
│ ├── pip3.10.exe
│ ├── pip3.exe
│ ├── python.exe
│ └── pythonw.exe

└── pyvenv.cfg

İşletim sistemimizde sistem genelindeki Python kurulumunu bulur ve oradaki klasör yapısını incelersek, sanal ortamınızın bu yapıya benzediğini görebiliriz.

pyvenv.cfg içerisinde home seçeneği altında bulabileceğimiz yola giderek sanal ortamımızın dayandığı temel Python kurulumunu bulabiliriz.

Windows’ta, temel Python kurulumumuzdaki python.exe’nin Scripts\ içinde olmadığını, ancak bir klasör düzeyinde olduğunu fark edebiliriz. Yürütülebilir dosya, sanal ortamımızda kasıtlı olarak Scripts\ klasöründe bulunur.

Klasör yapısındaki bu küçük değişiklik, sanal ortamı etkinleştirmek için kabuk PATH değişkenimize yalnızca tek bir dizin eklememiz gerektiği anlamına gelir.

Temel Python kurulumumuzda bazı ek dosya ve klasörler bulabilirken, standart klasör yapısının sanal ortamımızdakiyle aynı olduğunu fark etmiş olacağız, venv bu klasör yapısını, Python’ın beklendiği gibi, izolasyonda, birçok ek değişiklik yapmaya gerek kalmadan çalışmasını sağlamak için oluşturur.

Standart klasör yapısı uygulandığında, sanal ortamımızdaki Python yorumlayıcısı ilgili tüm dosyaların nerede olduğunu anlayabilir. Bunu, venv spesifikasyonuna göre önek bulma sürecinde yalnızca küçük uyarlamalarla yapar.

Python yorumlayıcısı, standart kitaplığın konumunu belirlemek için os modülünü aramak yerine önce bir pyvenv.cfg dosyası arar. Yorumlayıcı bu dosyayı bulursa ve bir giriş anahtarı içeriyorsa, yorumlayıcı bu anahtarı iki değişkenin değerini ayarlamak için kullanır:

sys.base_prefix pyvenv.cfg’de ana anahtar altında tanımlanan yolda bulabileceğimiz bu sanal ortamı oluşturmak için kullanılan Python yürütülebilir dosyasının yolunu sağlayacaktır.

sys.prefix pyvenv.cfg’yi içeren dizine işaret edecektir

Yorumlayıcı bir pyvenv.cfg dosyası bulamazsa, bunun sanal bir ortamda çalışmadığını belirler ve ardından hem sys.base_prefix hem de sys.prefix aynı yolu gösterir.

Çıktı:

C:\Users\adem.ok\AppData\Local\anaconda3
C:\Users\adem.ok\calisma_env

Python sanal ortamları, hızlı bir şekilde oluşturabileceğimiz ve artık ihtiyacımız olmadığında silebileceğimiz yalıtılmış bir Python ortamı sağlamanın basit bir yolu olmayı amaçlar. Bunu mümkün kılmak için venv yalnızca minimum düzeyde gerekli olan dosyaları kopyalar:

En basit haliyle Python sanal ortamı;

bir pyvenv.cfg dosyası ve bir site-packages dizini ile birlikte Python binary dosyasının bir kopyası veya sembolik bağlantısından başka bir şey içermez.

Sanal ortamımızdaki yürütülebilir Python, ortamı temel aldığımız Python kurulumunun standart kitaplık modüllerine erişime sahiptir. Python, pyvenv.cfg’deki home ayarında çalıştırılabilir temel Python’un dosya yoluna işaret ederek bunu mümkün kılar:

pyvenv.cfg’de vurgulanan satırın yol değerine gidip klasörün içeriğini listelersek, sanal ortamımızı oluşturmak için kullandığımız temel Python yürütülebilir dosyasını buluruz. Oradan, standart kitaplık modüllerimizi içeren klasörü bulmak için gezinebiliriz:

Python,ilgili yolu sys.path’e ekleyerek bu modülleri bulacak şekilde ayarlamıştır. Başlatma sırasında Python, bu bağımsız değişken için varsayılanları ayarlayan site modülünü otomatik olarak içe aktarır.

Python oturumumuzun sys.path içinde erişebildiği yollar, Python’un modülleri hangi konumlardan içe aktarabileceğini belirler.

Sanal ortamımızı etkinleştirir ve bir Python yorumlayıcısına girersek, temel Python kurulumumuzun standart kitaplık klasörüne giden yolun mevcut olduğunu onaylayabiliriz:import sys
from pprint import pp
pp(sys.path)

import sys
from pprint import pp
pp(sys.path)

Standart kitaplık modüllerimizi içeren dizinin yolu sys.path içinde bulunduğundan, sanal ortamımızdan Python ile çalışırken bunlardan herhangi birini içe aktarabileceğiz.

Çalıştırmak istediğimiz betiklerin sanal ortamımızda Python yorumlayıcısını kullandığından emin olmak için venv, sys.path kullanarak erişebileceğimiz PYTHONPATH ortam değişkenini değiştirir.

Bu değişkeni etkin bir sanal ortam olmadan incelersek, varsayılan Python kurulumumuz için varsayılan yol konumlarını görürürüz:

site-packages dizinine giden yolu temsil eden vurgulanmış satırlara dikkat ediyoruz. Bu klasör, örneğin pip kullanarak kuracağımız harici modülleri içerir. Etkinleştirilmiş bir sanal ortam olmadan, bu dizin Python yürütülebilir dosyasıyla aynı klasör yapısı içinde yer alır.

Ancak, başka bir yorumlayıcı oturumu başlatmadan önce sanal ortamımızı etkinleştirir ve aynı komutları tekrar çalıştırırsak, farklı çıktılar alırız:

Venv Dışında Başka Hangi Popüler Seçenekler Var?

venv modülü, Python sanal ortamlarıyla çalışmanın harika bir yoludur. Başlıca avantajlarından biri, venv’nin 3.3 sürümünden başlayarak Python ile önceden yüklenmiş olarak gelmesidir. Ancak sahip olduğumuz tek seçenek bu değil. Python’da sanal ortamlar oluşturmak ve yönetmek için diğer araçları da kullanabiliriz.

Bu bölümde iki popüler araç hakkında bilgi edineceğiz. Farklı kapsamları vardır ancak her ikisi de yaygın olarak venv modülüyle aynı amaç için kullanılır:

  • Virtualenv, venv’in bir üst kümesidir ve uygulanması için temel sağlar. İzole Python ortamları oluşturmak için güçlü, genişletilebilir bir araçtır
  • Conda ,Python ve diğer diller için paket, bağımlılık ve ortam yönetimi sunar

Venv’e göre bazı avantajları vardır, ancak standart Python kurulumumuzla birlikte gelmezler, bu nedenle bunları ayrıca kurmamız gerekir.

Virtualenv Projesi

Virtualenv, yalıtılmış Python ortamları oluşturmak için özel olarak yapılmış bir araçtır. Python topluluğu içinde uzun süredir favori olmuştur ve yerleşik venv modülünden önce gelir.

Paket, venv kullanarak yapabileceğimiz her şeyi ve daha fazlasını yapmamızı sağlayan bir venv üst kümesidir. Virtualenv şunları yapmamızı sağlar:

Daha hızlı şekilde sanal ortamlar oluşturur

Mutlak path’i sağlamaya gerek kalmadan Python’un kurulu sürümlerini keşfetmeye yarar

Aracı pip kullanarak yükseltir

Aracın işlevselliğini kendimiz genişletebiliriz

Python projelerimiz üzerinde çalışırken bu ek fonksiyonlardan herhangi biri kullanışlı olabilir. Hatta yeniden üretilebilirliğe yardımcı olması için virtualenv’nin bir planını projemizle birlikte kod halinde kaydetmek isteyebiliriz. Virtualenv, sanal ortamları oluşturmadan tanımlamamıza izin veren zengin bir programatik API’ye sahiptir.

virtualenv’i sistemimize kurduktan sonra, venv kullanarak yaptığımıza benzer şekilde yeni bir sanal ortam oluşturabilir ve etkinleştirebiliriz:

Virtualenv’in yalıtılmış ortamının yerleşik venv modülünden çok daha hızlı oluşturduğunu fark edebiliriz; bu, aracın hızla okuyabileceği platforma özgü uygulama verilerini önbelleğe alması nedeniyle mümkündür.

virtualenv’in venv’ye göre iki ana kullanıcı avantajı vardır:

Hız →Virtualenv ortamları çok daha hızlı oluşturur.

Güncellemeler → virtualenv’in yerleşik wheels lar sayesinde, sanal ortamı ilk kurduğumuzda internete bağlanmamıza gerek kalmadan güncel pip ve kurulum araçlarını alabiliriz.

Python’da sanal ortamlara yeni başlıyorsak yerleşik venv modülüne bağlı kalmak isteyebiliriz. Ancak, bir süredir kullandıysak ve aracın sınırlamalarıyla karşılaşıyorsak, virtualenv’yi kullanmaya başlamak harika bir fikirdir.

Conda Paketi ve Ortam Yöneticisi

Conda bize alternatif bir paket ve ortam yönetimi yaklaşımı sunar. Araç öncelikle veri bilimi topluluğu ve Anaconda Python dağıtımıyla ilişkili olsa da, potansiyel kullanım durumları bu topluluğun ötesine ve yalnızca Python paketlerini kurmanın ötesine uzanır:

Python paketlerini kurmak için yalıtılmış bir ortam oluşturmak için conda’yı da kullanabiliriz, ancak bu, aracın özelliklerinden yalnızca biridir:

pip, python paketlerini bir ortama kurar; conda, conda ortamlarında herhangi bir paketi kurar.

Bu alıntıdan da anlayabileceğimiz gibi, conda bu izolasyonu venv modülü ve virtualenv projesinden farklı bir şekilde gerçekleştirmektedir.

Conda, pip ile ilgisi olmayan bir projedir. Conda’yı sistemimizde çalıştırmak için minimum gereksinimleri beraberinde getiren Miniconda yükleyicisini kullanarak sistemimize kurabiliriz.

Deafult konfigürasyonunda, conda paketlerini PyPI yerine repo.anaconda.com’dan alır. Bu alternatif paket dizini, Anaconda projesi tarafından korunur ve benzer bir PyPI’dir, ancak aynısı değildir.

Conda, Python paketleriyle sınırlı olmadığından, conda’nın farklı dillerde yazılmış paket dizininde genellikle veri bilimi ile ilgili başka paketler bulabiliriz. Tersine, PyPI’de bulunan ve conda kullanarak yükleyemeyeceğimiz Python paketleri de vardır çünkü bunlar o paket deposunda yoktur. Conda ortamımızda böyle bir pakete ihtiyacımız varsa, bunun yerine pip kullanarak kurabiliriz.

Veri bilimi alanında ve diğer veri bilimi projelerinin yanı sıra Python ile çalışıyorsak;

conda, platformlar ve diller arasında çalışan mükemmel bir seçimdir.

Anaconda veya Miniconda’yı kurduktan sonra bir conda ortamı oluşturabiliriz:

conda create -n <venv-name>

Anaconda’yı başarıyla yükledikten sonra standart PowerShell oturumumuzun conda komutunu tanımadığını varsayalım. Bu durumda, programlarımızda Anaconda PowerShell İstemi’ni arayabilir ve bunun yerine onunla çalışabiliriz.

Bu komut, bilgisayarımızda merkezi bir konumda yeni bir conda ortamı oluşturur.

Tüm conda ortamları aynı konumda yaşadığından, tüm ortam adlarının benzersiz olması gerekir. Bu nedenle, herhangi bir conda ortamı venv’i çağırmak yerine onlara açıklayıcı adlar vermemiz en iyisidir.

Yeni conda ortamımızda çalışmak için onu etkinleştirmemiz gerekir:

conda activate <venv-name>

Ortamı etkinleştirdikten sonra, paketleri conda’nın paket deposundan o ortama kurabiliriz:

“medium” sanal ortamında yüklü paketleri listeledik;

numpy paketi yüklendikten sonra bağımlı paketleriyle birlikte listeyi gözlemleyebildik.

Install komutu, conda’nın paket havuzundan aktif conda ortamımıza bir üçüncü şahıs paketi kurar.

Ortamda çalışmayı bitirdiğimizde devre dışı bırakmamız gerekir:

Genel fikrin, venv kullanarak oluşturduğumuz Python sanal ortamlarıyla çalışmaya benzer olduğunu fark edebiliriz. Komutlar biraz farklıdır, ancak gerektiğinde silip yeniden oluşturabileceğimiz yalıtılmış bir ortamda çalışmanın aynı faydalarını elde edebiliriz.

Öncelikle veri bilimi projeleri üzerinde çalışıyorsak ve zaten Anaconda ile çalışıyorsak, venv ile çalışmak zorunda kalmayabiliriz. Bu durumda, conda ortamları ve bunlarla makinemizde etkin bir şekilde nasıl çalışacağımız hakkında daha fazla bilgi edinebiliriz.

Yalnızca saf Python bağımlılıklarımız varsa ve daha önce Anaconda ile çalışmadıysak, daha light olan venv modülünü doğrudan kullanmak veya virtualenv’i denemek daha iyidir.

Sanal Ortamlarımızı Nasıl Yönetebiliriz?

Bu bölümde, sanal ortam klasörümüzü istediğimiz zaman ve herhangi bir bilgisayarda hızlı bir şekilde silip yeniden oluşturabilmemiz için sanal ortamımızın temel bilgilerini tek bir dosyaya nasıl çıkaracağımızı göreceğiz.

Ayrıca, sanal ortam klasörlerimizi nerede tutacağımızı düzenlemenin iki farklı yolunu ve sanal ortamlarımızı yönetmemize yardımcı olabilecek bazı popüler üçüncü şahıs araçlarını da göreceğiz.

Ortam Klasörlerimizi Nerede Oluşturacağımıza Karar Vermek

Bir Python sanal ortamı yalnızca bir klasör yapısıdır. Sistemimizde herhangi bir yere yerleştirebiliriz. Ancak tutarlı bir yapı yardımcı olabilir ve sanal ortam klasörlerimizi nerede oluşturacağımız konusunda öne çıkan iki görüş vardır:

  • Her bir proje klasörünün içinde
  • Tek bir konumda, örneğin ana dizininizin bir alt klasöründe

Bunların her ikisinin de avantajları ve dezavantajları vardır ve tercihiniz nihayetinde iş akışınıza bağlı olacaktır.

Proje klasörü yaklaşımında, projenin kök klasöründe bu sanal ortamı aşağıdakiler için kullanacak yeni bir sanal ortam yaratırız:

project_name/

├── venv/

└── src/

Sanal ortam klasörü, o proje için yazacağımız herhangi bir kodla yan yana yaşar.

Bu yapının avantajı, hangi sanal ortamın hangi projeye ait olduğunu bilmemiz ve proje klasörüne girdikten sonra kısa bir göreli yol kullanarak sanal ortamımızı etkinleştirebilmemizdir.

Tek klasör yaklaşımında, tüm sanal ortamlarımızı tek bir klasörde, örneğin giriş dizinimizin bir alt klasöründe tutarız:

C:\USERS\USERNAME\

├── .local\

├── Contacts\

├── Desktop\

├── Documents\
│ │
│ └── Projects\
│ │
│ ├── django-project\
│ │
│ ├── flask-project\
│ │
│ └── pandas-project\

├── Downloads\

├── Favorites\

├── Links\

├── Music\

├── OneDrive\

├── Pictures\

├── Searches\

├── venvs\
│ │
│ ├── django-venv\
│ │
│ ├── flask-venv\
│ │
│ └── pandas-venv\

└── Videos\

Bu yaklaşımı kullanırsak, oluşturduğumuz sanal ortamları takip etmek daha az çaba gerektirebilir. Tüm sanal ortamları incelemek ve hangilerinin tutulup hangilerinin silineceğine karar vermek için işletim sistemimizde tek bir konuma gidebiliriz.

Öte yandan, proje klasörümüze gittiğimizde göreli bir yol kullanarak sanal ortamımızı hızlı bir şekilde etkinleştiremeyiz. Bunun yerine, ilgili sanal ortam klasöründeki etkinleştirme komut dosyasına giden mutlak yolu kullanarak etkinleştirmek en iyisidir.

İki yaklaşımdan birini kullanabilir ve hatta karıştırıp eşleştirebiliriz.

Sanal ortamlarımızı sistemimizin herhangi bir yerinde oluşturabiliriz. Açık bir yapının, klasörleri nerede bulacağımızı bilmemizi daha kullanıcı dostu hale getireceğini unutmayalım.

Üçüncü bir seçenek, bu kararı tümleşik geliştirme ortamımıza (IDE) bırakmaktır. Bu programların çoğu, yeni bir projeye başladığımızda bizim için otomatik olarak bir sanal ortam oluşturma seçenekleri içerir.

Favori IDE’mizin sanal ortamları nasıl ele aldığı hakkında daha fazla bilgi edinmek için konuyla ilgili online belgelere bakabiliriz. Örneğin, VS Code ve PyCharm’ın sanal ortamlar oluşturmaya yönelik kendi yaklaşımları vardır.

Onları Tek Kullanımlık Olarak Değerlendirelim

Sanal ortamlar, kod projemizle ilgili bilgileri kaybetmeden istediğimiz zaman güvenle silip yeniden oluşturabilmemiz gereken tek kullanımlık klasör yapılarıdır.

Bu, genellikle sanal ortamımıza manuel olarak herhangi bir ek kod veya bilgi koymadığımız anlamına gelir. Oraya giren her şey, genellikle pip veya conda olacak olan paket yöneticimiz tarafından ele alınmalıdır.

Ayrıca sanal ortamımızı sürüm kontrolüne tabi tutmamalı ve projemizle birlikte teslim etmemeliyiz.

Sanal ortamlar, projelerimizi geliştirmek için light, tek kullanımlık ve yalıtılmış ortamlardır.

Ancak, programımızı çalıştırabilmemiz veya geliştirmeye devam edebilmemiz için Python ortamımızı farklı bir bilgisayarda yeniden oluşturabilmemiz gerekir. Sanal ortamımızı tek kullanımlık olarak ele aldığımızda ve onu sürüm kontrolüne tabi tutmadığımızda bunu nasıl gerçekleştirebiliriz?

Bağımlılıkları Sabitlemek

Sanal ortamımızı yeniden üretilebilir hale getirmek için içeriğini tanımlamanın bir yoluna ihtiyacımız var. Bunu yapmanın en yaygın yolu, sanal ortamımız etkinken bir requirements.txt dosyası oluşturmaktır:

Python’da requirement.txt dosyası, genellikle belirli bir projeyi geliştirirken kullanılan tüm kütüphaneler, modüller ve paketler hakkındaki bilgileri kendi içinde depolayan bir nevi metadata bilgisi taşıyan bir dosya türüdür. Ayrıca, o projenin bağımlı olduğu veya çalıştırılması gereken tüm dosyaları ve paketleri depolar. Genellikle bu “requirements.txt” dosyası projelerinizin kök dizininde depolanır.

pip freeze > requirements.txt komutu ile yüklediğimiz ve kullandığımız modülleri ve versiyonları bu dosyada depolayabiliriz.

Bu komut, pip freeze çıktısını requirements.txt adlı yeni bir dosyaya aktarır. Dosyayı açarsak, sanal ortamımızda o anda yüklü olan dış bağımlılıkların bir listesini içerdiğini fark edebiliriz.

Bu liste, hangi paketin hangi versiyonunun kurulacağını bilmek için pip için bir reçetedir. Bu gereksinimleri.txt dosyasını güncel tuttuğumuz sürece, sanalortam klasörünü sildikten veya tamamen farklı bir bilgisayara taşıdıktan sonra bile çalıştığımız sanal ortamı her zaman yeniden oluşturabiliriz:

requirements.txt ile sanal ortamın tekrardan ayağa kalkması:

deactivate
python -m venv new-venv
new-venv\Scripts\activate
python -m pip install -r requirements.txt

Yukarıdaki örnek kod parçacığında, new-venv adlı yeni bir sanal ortam oluşturduk, etkinleştirdik ve daha önce requirements.txt dosyamıza kaydettiğimiz tüm dış bağımlılıkları yeni sanal ortama yükledik.

Önemli 2 Not:

Bu “requirements” dosyası, sanal ortamı oluştururken temel Python yorumlayıcımız olarak hangi Python sürümünü kullandığımız hakkında bilgi içermez

Requirements dosyamızı nasıl oluşturduğumuza bağlı olarak, bağımlılıklarımızın alt bağımlılıkları hakkında versiyon bilgisi içermeyebilir

Yazı boyunca;

  • sanal ortamların ne olduğu
  • neden onlara ihtiyaç duyduğumuz
  • nasıl çalıştıkları ve bunları sistemimizde nasıl yönetebileceğimiz

konusunda kapsamlı bir inceleme yapmış olduk.

Sevgiler 🤗

--

--