gereksinimleri.txt ile setup.py karşılaştırması


121

Python ile çalışmaya başladım. Ben ekledik requirements.txtve setup.pyprojeme. Ancak, her iki dosyanın amacı konusunda hala kafam karışık. setup.pyYeniden dağıtılabilir şeyler için tasarlanmış ve yeniden dağıtılamayan şeyler için tasarlanmış olanları okudum requirements.txt. Ancak bunun doğru olduğundan emin değilim.

Bu iki dosyanın gerçekten nasıl kullanılması amaçlanıyor?


1
Web'de tam olarak başlığınızı kullanarak arama yaptınız mı? Bu makale (araştırdığım ilk hit) konu hakkında okuduğum en iyi makale .
Chris

2
Bu makale yararlı olabilir: caremad.io/posts/2013/07/setup-vs-requirement (üzgünüm, temel bilgileri doğru bir cevaba çıkarmak için fazla tembel). Başka bir şey de, bazı araçların (örneğin test etme) şu ya da bu konuda önyargıları olabilir - ancak Python üzerinde çalışmaya yeni başladıysanız bunun sizi rahatsız etmesine izin vermeyin.
drdaeman

Yanıtlar:


93

requirements.txt:

Bu, geliştirme ortamınızı kurmanıza yardımcı olur.

Gibi programlar pip, dosyada listelenen tüm paketleri tek bir hamlede kurmak için kullanılabilir. Bundan sonra python betiğinizi geliştirmeye başlayabilirsiniz. Başkalarının gelişime katkıda bulunmasını veya sanal ortamları kullanmasını planlıyorsanız özellikle yararlıdır. Bunu nasıl kullanıyorsun:

pip install -r requirements.txt

setup.py:

Bu, yeniden dağıtabileceğiniz paketler oluşturmanıza yardımcı olur.

setup.pyKomut olarak geliştirme ortamı hazırlamak için değil, son kullanıcının sisteminde paketi kurmak anlamına gelir pip install -r requirements.txtyapar. Daha fazla ayrıntı için bu yanıta bakın setup.py.


Projenizin bağımlılıkları her iki dosyada da listelenmiştir.


2
Hangi durumlarda bunlardan sadece birine sahip olurum? İkisine birden sahip olabilirim?
Martin Thoma

31
Hımm ... yerel makinenizde sadece eğlence için komut yazıyorsunuz: Hiçbiri. Komut dosyası birden çok makinede / vitualenvs üzerinde geliştirilir ancak yeniden dağıtılmaz: Requirements.txt Komut dosyası yalnızca makinenizde geliştirilir ancak yeniden dağıtılması gerekir: setup.py. Komut dosyası, birden çok ortamda yeniden dağıtılacak ve geliştirilecektir: Her ikisi.
AndreasT

Bunu cevaba ekler misin?
Martin Thoma

Gerçekten setup.pyonsuz olur muydun requirements.txt? Bunları tamamen anlamayan bir arkadaş istemek.
eric

62

Kısa cevap, requirements.txtyalnızca paket gereksinimlerini listelemek içindir. setup.pydiğer yandan daha çok bir kurulum betiği gibidir. Python kodunu yüklemeyi planlamıyorsanız, genellikle yalnızca ihtiyacınız olur requirements.txt.

Dosya setup.py, paket bağımlılıklarına ek olarak, paketlenmesi (veya yerel modüller olması durumunda derlenmesi (yani C ile yazılması)) gereken dosya ve modül kümesini ve python paket listelerine eklenecek meta verileri ( örneğin paket adı, paket sürümü, paket açıklaması, yazar, ...).

Her iki dosya da bağımlılıkları listelediği için, bu biraz çoğaltmaya yol açabilir. Ayrıntılar için aşağıyı okuyun.

gereksinimler.txt


Bu dosya python paketi gereksinimlerini listeler. Python projenizin paket bağımlılıklarını (satır başına bir tane ) listeleyen düz bir metin dosyasıdır (isteğe bağlı olarak yorumlarla birlikte ). O değil senin piton paket yüklü olduğu yolu tarif eder. Genellikle gereksinimler dosyasını pip install -r requirements.txt.

Metin dosyasının dosya adı keyfidir, ancak genellikle requirements.txtkural gereğidir. Diğer python paketlerinin kaynak kodu depolarını keşfederken, dev-dependencies.txtveya gibi başka adlarla karşılaşabilirsiniz dependencies-dev.txt. Bunlar dependencies.txt, belirli bir paketin geliştiricileriyle aynı amaca hizmet eder, ancak genellikle, yani yayınlamadan önce kaynak kodunu (ör. Pytest, pylint, vb.) Test etmek için ek ilgi bağımlılıklarını listeler. Paketin kullanıcıları genellikle paketi çalıştırmak için tüm geliştirici bağımlılıkları setine ihtiyaç duymazlar.

Birden çok requirements-X.txtvaryant varsa , genellikle biri çalışma zamanı bağımlılıklarını ve diğer oluşturma zamanı veya test bağımlılıklarını listeler. Bazı projeler, gereksinim dosyalarını da basamaklandırır, yani bir gereksinim dosyası başka bir dosya içerdiğinde ( örnek ). Bunu yapmak tekrarı azaltabilir.

setup.py


Bu, setuptoolsmodülü bir python paketini (ad, dahil edilen dosyalar, paket meta verileri ve kurulum) tanımlamak için kullanan bir python betiğidir . Aynı requirements.txtzamanda paketin çalışma zamanı bağımlılıklarını da listeleyecektir. Setuptools, python paketleri oluşturmanın ve kurmanın fiili yoludur, ancak zamanla pip gibi yeni "meta-paket yöneticilerinin" geliştirilmesini sağlayan eksiklikleri vardır. Kurulum araçlarının örnek eksiklikleri, aynı paketin birden çok sürümünü yükleyememesi ve bir kaldırma komutunun olmamasıdır.

Bir python kullanıcısı yaptığında pip install ./pkgdir_my_module(veya pip install my-module), setup.pyverilen dizinde (veya modülde) pip çalışacaktır . Benzer şekilde, bir modülü olan herhangi bir modül , örneğin aynı klasörden çalıştırılarak setup.pykurulabilir .pippip install .

İkisine de gerçekten ihtiyacım var mı?


Kısa cevap hayır, ama ikisine de sahip olmak güzel. Farklı amaçlara ulaşırlar, ancak her ikisi de bağımlılıklarınızı listelemek için kullanılabilir.

Eğer arasındaki bağımlılıkları listenizi çoğaltma önlemek için düşünebilir bir hile vardır requirements.txtve setup.py. setup.pyZaten paketiniz için tam olarak çalışan bir yazdıysanız ve bağımlılıklarınız çoğunlukla dışarıdaysa, requirements.txtyalnızca aşağıdakileri içeren bir Simple'a sahip olmayı düşünebilirsiniz :

 # requirements.txt
 #
 # installs dependencies from ./setup.py, and the package itself,
 # in editable mode
 -e .

 # (the -e above is optional). you could also just install the package
 # normally with just the line below (after uncommenting)
 # .

Bu -e, pip installverilen paketi düzenlenebilir modda kuran özel bir seçenektir . Ne zaman pip -r requirements.txtbu dosya üzerinde çalıştırılır, pip listeye aracılığıyla bağımlılıkları kuracaktır ./setup.py. Düzenlenebilir seçeneği, kurulum dizininize bir sembolik bağlantı yerleştirir (yumurta veya arşivlenmiş bir kopya yerine). Geliştiricilerin, yeniden yüklemeden depodaki kodu yerinde düzenlemelerine olanak tanır.

Paket deponuzda her iki dosya da bulunduğunda, "kurulum araçları ekstraları" denen şeyden de yararlanabilirsiniz. Setup.py'de isteğe bağlı paketleri özel bir kategori altında tanımlayabilir ve bu paketleri pip ile sadece bu kategoriden kurabilirsiniz:

# setup.py
from setuptools import setup
setup(
   name="FOO"
   ...
   extras_require = {
       'dev': ['pylint'],
       'build': ['requests']
   }
   ...
)

ve ardından, gereksinimler dosyasında:

# install packages in the [build] category, from setup.py
# (path/to/mypkg is the directory where setup.py is)
-e path/to/mypkg[build]

Bu, tüm bağımlılık listelerinizi setup.py içinde tutacaktır.

Not : Normalde pip ve setup.py'yi programla oluşturulanlar gibi bir sanal alandan çalıştırırsınız virtualenv. Bu, python paketlerini projenizin geliştirme ortamının bağlamı dışında yüklemekten kaçınacaktır.


7
ve içinde sadece .w / o da olabilir . Bu yöntem, tüm gereksinimleri için yetkilendirir ve kimseyi düzenlenebilir moda zorlamanıza gerek yoktur. Kullanıcılar isterlerse yine de yapabilir . -erequirements.txtsetup.pypip install -e .
stason

1
"-E" ile ilginç bir numara. Required.txt, ancak bu, requirements.txt'nin amacının tam sistem özellikleri olmasını engellemez mi? Bu durumda neden bir tane bile var?
Ben Ogórek

Setup.py içinde tam sistem gereksinimlerine sahip olabilirsiniz. "." Requirements.txt dosyası, geçerli klasördeki setup.py'yi kullanmasını sağlar. Kullanımı -e .da bağımlılıkları bulmak için setup.py'yi kullanır, ancak bir kopya almak yerine pip yükleme klasöründeki geçerli klasörü (yerinde, bir symlink ile) bağlar - -egenellikle yalnızca paketi geliştiriyorsanız kullanırsınız. İle -e, python paket dosyalarınızdaki (* .py) değişiklikler, her değişiklikten sonra paketi yeniden yüklemeye zorlamak yerine pip ortamınızda hemen etkili olur.
init_js

@init_js, pip çağrılan gereksinimler dosyası veya CWD'ye göre "geçerli klasör" mü? Yani eğer yaparsanız, cd foo && pip install -r ./bar/requirements.txtiçinde setup.py foo/barveya foo? İkincisi ise, birincisine ulaşmanın bir yolu var mı?
Dan M.

pip -r REQREQ'nun bulunduğu dizini umursamıyor. İstediğiniz bile Fifo bir onu besleyebilir: pip install -r <(echo "mylib1"; echo "mylib2";). <(CMD)Bash komut ikamesi nerede , stdin yönlendirmesi değil.
init_js

14

Tamlık adına, işte onu 3 4 farklı açıdan nasıl görüyorum .

  1. Tasarım amaçları farklı

Bu, resmi belgelerden alıntılanan kesin tanımdır (vurgu benim):

İnstall_requires (setup.py içinde) tek bir proje için bağımlılıkları tanımlarken , Gereksinim Dosyaları genellikle eksiksiz bir Python ortamı için gereksinimleri tanımlamak için kullanılır .

İnstall_requires gereksinimleri minimum düzeydeyken, gereksinim dosyaları genellikle tam bir ortamın tekrarlanabilir yüklemelerini elde etmek amacıyla sabitlenmiş sürümlerin kapsamlı bir listesini içerir.

Ancak yine de anlaşılması kolay olmayabilir, bu nedenle bir sonraki bölümde, 2 yaklaşımın nasıl farklı şekilde kullanılması gerektiğini gösteren 2 gerçek örnek var.

  1. Dolayısıyla gerçek kullanımları farklıdır (olması gerekir)

    • Projeniz foobağımsız bir kitaplık olarak yayınlanacaksa (yani, başkaları muhtemelen yapacak import foo), o zaman siz (ve aşağı akış kullanıcılarınız) esnek bir bağımlılık bildirimine sahip olmak isteyeceksiniz, böylece kitaplığınız bunu yapmayacaktır (ve ) SİZİN bağımlılıklarınızın tam olarak hangi versiyonu olması gerektiği konusunda "seçici" olun. Bu nedenle, tipik olarak, setup.py dosyanız şuna benzer satırlar içerir:

      install_requires=[
          'A>=1,<2',
          'B>=2'
      ]
      
    • Uygulamanız için KESİN mevcut ortamınızı bir şekilde "belgelemek" veya "sabitlemek" istiyorsanız bar, yani siz veya kullanıcılarınız uygulamanızı barolduğu gibi kullanmak , yani çalışır durumda python bar.py, ortamınızı dondurmak isteyebilirsiniz. hep aynı şekilde davranırdı. Böyle bir durumda, gereksinimler dosyanız şöyle görünecektir:

      A==1.2.3
      B==2.3.4
      # It could even contain some dependencies NOT strickly required by your library
      pylint==3.4.5
      
  2. Gerçekte, hangisini kullanıyorum?

    • barTarafından kullanılacak bir uygulama geliştiriyorsanız python bar.py, bu "eğlence için komut dosyası" olsa bile, yine de Required.txt kullanmanız önerilir çünkü, kim bilir, gelecek hafta (Noel olur) bir Hediye olarak yeni bir bilgisayar, böylece tam ortamınızı orada yeniden kurmanız gerekir.

    • Eğer bir kütüphane geliştiriyorsanız footarafından kullanılacak import foo, bir setup.py hazırlamalıyız. Dönem. Ancak yine de aynı anda bir requirements.txt sağlamayı seçebilirsiniz, bu da:

      (a) ya A==1.2.3stilde (yukarıda # 2'de açıklandığı gibi);

      (b) veya sadece büyülü bir single içerir .

      .
      

      bu, çoğaltma olmadan "gereksinimleri setup.py'ye dayalı olarak yükleme" ye eşittir. Şahsen ben bu son yaklaşımın çizgiyi bulanıklaştırdığını, kafa karışıklığına katkıda bulunduğunu ve gerçekten değer katmadığını düşünüyorum, ancak yine de Python ambalaj geliştiricisi Donald'ın blog yazısında bahsettiği bir yaklaşımdan türetilen bir hile .

  3. Farklı alt sınırlar.

    Eğer 3 kritere yukarıda takip ve doğru kütüphane karar verdik sonra bile hybrid-enginebir kullanırsınız setup.pyolan bağımlılığını ilan etmek engine>=1.2.0, ve örnek uygulama reliable-carkullanmak istiyorsunuz requirements.txtolan bağımlılığını ilan etmek engine>=1.2.3son sürümü olsa bile, engine1.4.0 de zaten. Gördüğünüz gibi, alt sınır sayıları için seçiminiz hala ince bir şekilde farklı. Ve işte nedeni.

    • hybrid-enginebağlıdır engine>=1.2.0varsayımsal konuşuyorum, çünkü gerekli "içten yanmalı" özelliği ilk tanıtıldı engine 1.2.0ve bu kabiliyet gerekliliğidir hybrid-enginebakılmaksızın böyle versiyonu içinde bazı (küçük) hatalar olabilir bakılmaksızın, ve sonraki sürümlerinde 1.2.1 düzeltildi , 1.2.2 ve 1.2.3.

    • reliable-carengine>=1.2.3Şimdiye kadar bilinen sorunlar OLMADAN en eski sürüm olduğu için buna bağlıdır . Elbette sonraki sürümlerde yeni yetenekler var, mesela "elektrik motoru" ve tanıtılmış engine 1.3.0"nükleer reaktör" engine 1.4.0, ancak bunlar proje için gerekli değil reliable-car.


"kütüphaneniz, SİZİN bağımlılıklarınızın tam olarak hangi sürümünün olması gerektiği konusunda 'seçici' olmayacaktır (ve olmamalıdır)." Bu noktayı biraz açar mısınız? Kodunuz genellikle yalnızca belirli bağımlılık sürümleriyle test edilir ve bu yaklaşım biraz tehlikeli olabilir. Bir kitaplığın çeşitli sürümlerle çalışması gerektiğini varsayıyorum çünkü çok fazla bağımlılık sürümü yüklemek istemiyorsunuz? Disk alanından tasarruf etmek için?
Taro Kiritani

@TaroKiritani Aslında yan yana 2 farklı senaryo listeledim, kütüphane vakası ve uygulama vakası. Belki daha önce bir kütüphane üzerinde çalışmadınız? Bir kütüphane olarak, aşağı akışlı paketler tarafından tüketilmesi beklenir. Dolayısıyla A==1.2.3, SİZİN bağımlılığınızı sabitlemek için seçici iseniz ve ardından kitaplığınızın aşağı akış paketi buna bağlıysa A==1.2.4, artık her ikisini de tatmin etmenin bir yolu olmayacaktır. Bu çatışmayı en aza indirmenin çözümü, kitaplığınızın işe yarayacağını bildiğiniz bir aralığı tanımlamasıdır. Aşağıdaki zaten birçok memba kütüphane varsayarsak semver.org , A>=1,<2çalışacak.
RayLuo

Tek bir ortama bir paketin yalnızca bir sürümünün kurulabileceğini bilmiyordum. stackoverflow.com/a/6572017/5686692 Açıklama için teşekkürler.
Taro Kiritani

1
@TaroKiritani, evet, aksi uygulamanızın nasıl biliyorum hangi sürümünün olacağını foomu import foosize? Sağladığınız bağlantıdaki hilekarca kabul edilen yanıt, paket bakımcısının neden "seçici olmaması ve seçmemesi" gerektiğinin mükemmel bir örneğidir. :-) Şimdi sizin olumlu oyunuzu alabilir miyim?
RayLuo

1
Bu yeni düşünce hakkında da yorum yapabilirim, ancak bu yorumlar bölümü zaten konu dışı ve yeni gelenlerin takip etmesi zor. Yeni bir soru sormanızı öneririm "Kütüphanemin çeşitli bağımlılık kombinasyonları üzerinde çalışmasını garanti etmek için toks veya başka bir şey kullanmalı mıyız" ve sonra insanlar
içeri girebilir
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.