WSL 上的 Virtualenv 创建的文件与 PowerShell 上的 Virtualenv 不同

Virtualenv on WSL creates different files than Virtualenv on PowerShell

我的系统上安装了 WSL Python 3.7.3 运行,而 Python 在我的主系统上运行 3.7.4。两个系统都安装了 pip(或 pip3)以及 virtualenv 16.x.x 及更高版本。我的问题是,在 WSL 上使用 virtualenv env 会创建一个与在 PowerShell 上不同的文件夹结构,但问题不在于不同的路径,而在于在 lib 文件夹中创建的文件。

我已经尝试通过 pip3 uninstall virtualenv 在 WSL 上重新安装 virtualenv,但是问题仍然存在。

https://imgur.com/a/P8SfXUX这是WSL和PowerShell的图片。

如您所见,WSL 创建的文件大小为 0-1KB,无法被 Windows 识别,而 PowerShell 创建的文件功能完备。

有人可以向我解释为什么会这样吗?谢谢。

在 Windows 子系统中为 Linux 创建一个 virtualenv 将创建一个用于 Linux 上 运行 的 virtualenv,而不是 Windows 上的 virtualenv。这就是为什么 Windows 无法识别由 virtualenv 在 WSL 上创建的文件(并且由 virtualenv 在 Powershell 上创建的文件将无法在 WSL 中使用)。

至于为什么Windows virtualenv中的文件这么大,是因为更多的是编译后的二进制文件和库文件,而不是脚本。

我的双启动机器上有两个 virtualenvs,所以我们可以查看它们以进行等效比较。 (一个是Python3.6,一个是Python3.7,不过这不是太重要。)

这里是 Windows virtualenv 的文件:

   2315 activate*
   1067 activate.bat*
   1755 activate.ps1*
   1517 ativate_this.py*
   1159 activate.xsh*
    603 deactivate.bat*
 102783 easy_install-3.7.exe*
 102783 easy_install.exe*
 103281 f2py.exe*
 102765 pip3.7.exe*
 102765 pip3.exe*
 102765 pip.exe*
3748368 python37.dll*
  58896 python3.dll*
  99856 python.exe*
  98320 pythonw.exe*
 102761 wheel.exe*

这里是 Linux virtualenv 的文件:

   2219 activate
   1438 activate.csh
   3103 activate.fish
   1751 activate.ps1
   1517 activate_this.py
   1160 activate.xsh
    259 easy_install*
    259 easy_install-3.6*
    242 f2py*
    242 f2py3*
    242 f2py3.6*
    150 get_env_details*
    246 pip*
    246 pip3*
    246 pip3.6*
     72 postactivate
     74 postdeactivate
     69 preactivate*
     75 predeactivate
      7 python -> python3*
4526456 python3*
      7 python3.6 -> python3*
   2348 python-config*
    237 wheel*

如您所见,Linux virtualenv 的文件比 Windows 的小得多。这是正常的,不是问题。

原因是 Linux virtualenvs 中的更多文件是脚本,而不是二进制文件。脚本是包含将由解释器 运行 代码的文件,而二进制文件是编译代码,将直接 运行 (如 .exe 文件)或用作库(如.dll 个文件)。

在 Windows virtualenv 上,activateactivate.batactivate.ps1activate_this.pyactivate.xshdeactivate.bat 是脚本。您可以看到它们的大小在 0.6 到 2.3 kB 之间,相当小。 easy_install-3.7.exeeasy_install.exef2py.exepip3.7.exepip3.exepip.exepython.exepythonw.exewheel.exe,另一方面,都是二进制可执行文件。您可以看到它们的范围从 98 到 103 kB,这比脚本大得多。 python37.dllpython3.dll是库文件,也是编译好的二进制文件,但不能直接执行,而且也比较大。 python3.dllpython37.dll 小很多,所以 python3.dll 可能只是引用 python37.dll,但即便如此,与脚本相比 python3.dll 仍然很大。

另一方面,在 Linux virtualenv 上,所有文件都是脚本,除了 pythonpython3python3.6python3 是二进制可执行文件,pythonpython3.6 只是 python3.

的符号链接

脚本通常较小的原因是因为它们 运行 实际上在解释器中的代码没有包含在文件本身中的代码。例如,让我们看一下 pip.

以下是 Linux virtualenv 上文件 pip 的内容:

#!/home/nog642/.virtualenvs/virtualenv-name/bin/python3
# -*- coding: utf-8 -*-
import re
import sys

from pip._internal.main import main

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
    sys.exit(main())

这是一个 python 脚本,它 运行 在 vi​​rtualenv 的 python 解释器中。它导入 pip 模块,它包含在 virtualenv 结构的其他地方,然后 运行 在对命令行参数进行一些解析之后是主要方法。

pip 的实际代码在其他地方,运行 的实际可执行文件是 python3,然后 运行 解释器中的脚本。这就是文件最终只有 246 字节的原因。

另一方面,Windows virtualenv 中的

pip.exe 是 102,765 字节。这是因为它本身是一个可执行二进制文件,而不是脚本。它包含已编译的 运行 所需的所有代码。由于它是独立的,并且不依赖于文件结构中其他地方的代码,因此它最终变得更大。