为什么pipenv需要Pipfile和Pipfile.lock?

时间:2018-10-23 14:16:22

标签: python pipenv

(我认为[!])我了解pipenv(和其他venv)背后的原理,并经常使用它们。但是,我从未真正理解为什么pipenv同时需要一个Pipfile和一个Pipfile.lock文件。

This answer暗含,this tutorial

  

现在,一旦在生产中获得代码和Pipfile.lock,   环境,您应该安装最后一个成功的环境   记录:

$ pipenv install --ignore-pipfile

但并不能解释为什么为什么 Pipfile.lock 需要。即.lock文件中包含Pipfile不包含的内容,为什么Pipfile足以与其他开发人员共享:

  

现在,假设另一个开发人员想要对您的产品进行一些补充   码。在这种情况下,他们将获得代码,包括   Pipfile,并使用以下命令:

$ pipenv install --dev

但是还不足以用来在生产环境中复制您的环境吗?

3 个答案:

答案 0 :(得分:2)

官方Pipfile项目has something to say about this

  

Python应用程序的具体要求来自Pipfile。这将包括应从何处获取软件包及其宽松的版本限制。

     

环境的详细信息(所有已安装的带有固定版本的软件包以及其他详细信息)将存储在Pipfile.lock中,以提高可重复性。该文件将自动生成,并且不应由用户修改。

换句话说,Pipfile适用于Pipfile.lock适用于计算机

Pipfile中列出该文件中所需的内容,然后以某种宽松的方式定义它们,例如“ Django版本2或更高版本”。但这还不足以确定性地重现环境。那是“ Django 2.0.3”还是“ Django 2.1.0”?

Pipfile.lock准确地指定了需求,还准确地指定了依赖项。例如,如果您明确希望使用foo并将其放入Pipfile中,则会生成Pipfile.lock并将其锁定为特定版本。如果foo本身依赖于bar,而bar依赖于quuxflorp,则Pipfile.lock文件将锁定barquuxflorp也降低了,因此依存关系的细微差别不会破坏事情。

答案 1 :(得分:0)

正如@Chris所说,Pipfile.lock是用于计算机,而Pipfile是用于人类。如果查看Pipfile.lock文件,您会发现每个依赖项甚至都具有sha256代码!

该文件是人类无法处理的,您只能处理Pipfile。但是Pipfile不够严格,无法再现完全相同的环境。这就是为什么我们还需要Pipfile.lock

答案 2 :(得分:0)

这是npm之类的工具。(也许?)
Pipfile用于标识项目的依赖关系,您将从.lock获取依赖关系树。
但是根据不同的来源,您将获得不同的软件包。因此,您可以从matplotlib = "*" numpy = "*" 文件中获取实际的本地依赖关系。
例如,在Pipfile中,您可以看到类似以下内容的

.lock

但是在"pytz": { "hashes": [ "sha256:a061aa0a9e06881eb8b3b2b43f05b9439d6583c206d0a6c340ff72a7b6669053", "sha256:ffb9ef1de172603304d9d2819af6f5ece76f2e85ec10692a524dd876e72bf277" ], "version": "==2018.5" } 文件中,您将看到实际的依赖项,例如:

Pipfile

简而言之,.lock是为了更兼容,但是e = Embedding(11619, 200, weights=[wv], input_length=sentMax,trainable=False) ## Original Sentence input1=Input(shape=(np.shape(W_train)[1],),name='text') input2=Input(shape=(157,1),name='d1') input3=Input(shape=(157,1),name='d2') x1=e(input1) x2=Dense(1,activation='linear')(input2) x3=Dense(1,activation='linear')(input3) inputs=concatenate([x1,x2,x3],axis=-1,name="concat") t=Bidirectional(LSTM(100,return_sequences=True),merge_mode='concat')(inputs) model=Dropout(0.5, noise_shape=None, seed=None)(t) pool = Attention()(model) ## Help1 Sentence input1_h1=Input(shape=(np.shape(W_h1_train)[1],),name='text_h1') input2_h1=Input(shape=(157,1),name='d1_h1') input3_h1=Input(shape=(157,1),name='d2_h1') x1_h1=e(input1_h1) x2_h1=Dense(1,activation='linear')(input2_h1) x3_h1=Dense(1,activation='linear')(input3_h1) inputs_h1=concatenate([x1_h1,x2_h1,x3_h1],axis=-1,name="concat_h1") t_h1=Bidirectional(LSTM(100,return_sequences=True),merge_mode='concat')(inputs_h1) model_h1=Dropout(0.5, noise_shape=None, seed=None)(t_h1) pool_h1 = Attention()(model_h1) ## Help2 Sentence input1_h2=Input(shape=(np.shape(W_h2_train)[1],),name='text_h2') input2_h2=Input(shape=(157,1),name='d1_h2') input3_h2=Input(shape=(157,1),name='d2_h2') x1_h2=e(input1_h2) x2_h2=Dense(1,activation='linear')(input2_h2) x3_h2=Dense(1,activation='linear')(input3_h2) inputs_h2=concatenate([x1_h2,x2_h2,x3_h2],axis=-1,name="concat_h2") t_h2=Bidirectional(LSTM(100,return_sequences=True),merge_mode='concat')(inputs_h2) model_h2=Dropout(0.5, noise_shape=None, seed=None)(t_h2) pool_h2 = Attention()(model_h2) combined=concatenate([pool,pool_h1,pool_h2],axis=1) X=Dense(300,activation='relu',kernel_regularizer=regularizers.l2(0.0001))(combined) X=Dense(100,activation='relu',kernel_regularizer=regularizers.l2(0.0001))(X) main_output = Dense(5,activation='softmax',kernel_regularizer=regularizers.l2(0.0001))(X) output_model = Model(inputs=[input1,input2,input3,input1_h1,input2_h1,input3_h1,input1_h2,input2_h2,input3_h2], outputs=main_output) 文件是要在本地获得实际的依赖关系。