如何修改 virtualenv 中的 pip?

How to modify pip in a virtualenv?

我正在尝试修改 pip,以便在每次安装或卸载后,我的 requirements.txt 都会得到更新。

为此,我修改了虚拟环境 bin/ 中的 pip 文件。

pip:

#!/Users/username/ProjectEnv/bin/python3

# -*- coding: utf-8 -*-
import re
import sys

from pip import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    status = main()
    if status == 0 or status is None:
        sys.argv = ['pip', 'freeze', '>', '../Project/requirements.txt']
        sys.exit(main())

这没有用。我试过打印命令行参数并设置断点,但效果不佳。

pip:

#!/Users/username/ProjectEnv/bin/python3

# -*- coding: utf-8 -*-
import re
import sys
import pdb
pdb.set_trace()

from pip import main

if __name__ == '__main__':
    for arg in sys.argv:
        print(arg)
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    status = main()
    if status == 0 or status is None:
        sys.argv = ['pip', 'freeze', '>', '../Project/requirements.txt']
        sys.exit(main())

我做错了什么?

在pip库中自己调用freeze方法即可。它将 return 一个生成器,为您提供 line-by-line 在 pip --freeze 中打印到屏幕上的输出。

from pip.operations import freeze

packages = freeze.freeze()
with open('../Project/requirements.txt', 'w') as f:
    for x in packages:
        f.write(x)
        f.write('\n')

问题是我修改了错误的文件。我修改了 ProjectEnv/bin/ 中的 pip,但那不是我键入 pip install some_module.

时正在执行的文件

花了一段时间才发现这一点,因为 which pip 也输出了 /Users/username/ProjectEnv/bin/pip

type pip已经证明了真相。它输出:pip is aliased to 'pip3'.

所以,这是一个很好的例子,说明了为什么我们应该将 which 别名为 type。或者,为什么我们应该完全停止使用 which 而总是使用 type.

我认为您最好使用 bash 脚本,例如 pip_with_autofreeze.sh:

#!/usr/bin/env sh
pip $@ && pip freeze > requirements.txt
例如

运行它与./pip_with_autofreeze.sh install flask

将脚本放在 $PATH 中的某个合适位置,例如 ~/bin,以后您可以从您创建的任何 virtualenv 中调用它们。 Pip 将引用 virtualenv 指向的任何内容。