PYTHONPATH ile sys.path karşılaştırması


94

Başka bir geliştirici ve ben, Python'un bir kullanıcı (örneğin, geliştirme) dizininde bir Python paketi bulmasına izin vermek için PYTHONPATH veya sys.path'in kullanılması gerektiği konusunda hemfikir değiliz.

Tipik bir dizin yapısına sahip bir Python projemiz var:

Project
    setup.py
    package
        __init__.py
        lib.py
        script.py

Script.py'de yapmamız gerekiyor import package.lib. Paket site paketlerine yüklendiğinde, script.py bulabilir package.lib.

Ancak bir kullanıcı dizininden çalışırken, başka bir şey yapılması gerekir. Benim çözümüm PYTHONPATH'ımı "~ / Project" içerecek şekilde ayarlamak. Başka bir geliştirici, bu kod satırını script.py'nin başına koymak istiyor:

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

Böylece Python package.lib,.

Bunun kötü bir fikir olduğunu düşünüyorum, çünkü bu satır yalnızca yerel bir kopyadan çalışan geliştiriciler veya insanlar için yararlı, ancak bunun neden kötü bir fikir olduğuna dair iyi bir neden veremiyorum.

PYTOHNPATH, sys.path mi kullanmalıyız, yoksa iyi mi?


4
Görünüşe göre oylar ve yanıtlar PYTHON_PATH kullanmaya yönelik çok hafif bir eğilimle oldukça eşit bir şekilde bölünmüş, ancak bu sorudan örnekleme gürültüsü veya istemeden önyargı olabilir.
AJP

Arasındaki fark için PATHve sys.path(ve dolaylı olarak PYTHONPATH) ayrıca bakınız stackoverflow.com/questions/25344841/sys-path-vs-path
tripleee

Yanıtlar:


42

Yolu değiştirmenin tek nedeni, kendi çalışma ağacından çalışan geliştiriciler içinse, ortamınızı sizin için ayarlamak için bir kurulum aracı kullanmalısınız. virtualenv çok popülerdir ve setup.py developkurulum araçlarını kullanıyorsanız, mevcut Python kurulumunuzda çalışma ağacını yarı kurmak için çalıştırabilirsiniz .


11
Bununla ilgili biraz daha açıklama yapabilir misin? Bir conda / virtualenv ortamını ayakta tutsanız bile, bu üst düzey dizini python yolunuza nasıl yerleştirir?
compguy24

38

PYTHONPATH'tan nefret ediyorum. Kullanıcı bazında (özellikle arka plan programı kullanıcıları için) ayarlamayı ve proje klasörleri hareket ederken takip etmeyi kırılgan ve can sıkıcı buluyorum. sys.pathBağımsız projeler için invoke betiklerini ayarlamayı tercih ederim .

Ancak sys.path.appendbunu yapmanın yolu bu değil. Kopyaları kolayca alabilirsiniz ve bu, .pthdosyaları ayıklamaz. Daha iyi (ve daha okunabilir): site.addsitedir.

Ve script.pynormalde bunu yapmak için daha uygun bir yer olmazdı, çünkü yolda mevcut kılmak istediğiniz paketin içindedir . Kütüphane modülleri kesinlikle sys.pathkendilerine değmemelidir. Bunun yerine, normalde uygulamayı başlatmak ve çalıştırmak için kullandığınız paketin dışında bir karma komut dosyası kullanırsınız ve bu önemsiz sarmalayıcı komut dosyasında sys.path-frobbing gibi dağıtım ayrıntılarını koyarsınız.


17
Sorun site.addsitedirbir yapmasıdır appendON sys.pathyüklü bir paket gelişiminde yerel paketin göre öncelikli olacaktır (ve çekme saç söz konusu olabilir) yani. sys.path.insert(0...bunun üstesinden gelmek için gereklidir.
Eli Bendersky

5
@EliBendersky: olmalıdır sys.path.insert(1. stackoverflow.com/q/10095037/125507
endolith

12

Genel olarak, bir ortam değişkeninin (PYTHONPATH gibi) ayarlanmasının kötü bir uygulama olduğunu düşünürdüm. Bu bir defaya mahsus hata ayıklama için iyi olsa da, bunu
düzenli bir uygulama olarak kullanmak iyi bir fikir olmayabilir.

Ortam değişkeninin
kullanılması, kod tabanında bir başkası sorunları rapor ettiğinde "benim için çalışıyor" gibi durumlara yol açar . Ayrıca, test ortamında da aynı uygulama yapılabilir, bu da testlerin belirli bir geliştirici için iyi çalışmasına karşın, bazıları testleri başlattığında muhtemelen başarısız olduğu gibi durumlara yol açabilir.


6

Daha önce bahsedilen diğer birçok nedenin yanı sıra, bu sabit kodlamaya da işaret edebilirsiniz.

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

kırılgandır çünkü script.py'nin konumunu varsayar - yalnızca script.py Proje / paket içinde bulunuyorsa çalışır. Bir kullanıcı script.py'yi (neredeyse) başka bir yere taşımaya / kopyalamaya / sembolik bağlantı kurmaya karar verirse bozulur.


5

Bence bu durumda PYTHONPATH kullanmanın daha iyi bir şey olduğunu düşünüyorum, çünkü çoğunlukla (sorgulanabilir) gereksiz kod ortaya çıkarmıyor.

Sonuçta, eğer düşünürseniz, kullanıcınızın buna ihtiyacı yoktur sys.path, çünkü paketiniz site paketlerine yüklenecektir çünkü bir paketleme sistemi kullanacaksınız.

Kullanıcı, sizin deyiminizle "yerel bir kopyadan" çalıştırmayı seçerse, o zaman gözlemledim ki, normal uygulama, site paketleri dışında kullanılıyorsa, paketin PYTHONPATH'a manuel olarak eklenmesi gerektiğini belirtmektir. .


3

Yukarıda belirtilen nedenlerden dolayı ne hacklemek PYTHONPATHne de sys.pathiyi bir fikirdir. Ve mevcut projeyi site paketleri klasörüne bağlamak için buradapython setup.py develop açıklanandan daha iyi bir yol var :

pip install --editable path/to/project

Projenizin kök klasöründe bir setup.py yoksa, bu başlangıç ​​için yeterince iyidir:

from setuptools import setup
setup('project')
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.