virtualenv在将虚拟环境添加到Python3.3之前,这似乎可以正常使用该模块。有轶事证据表明,Python
site.py曾经从可执行文件中向上查找,直到找到可以满足导入要求的目录为止。然后将其用于
sys.prefix,这对于PythonService.exe来说足以找到它所在的virtualenv并使用它。
如果是这种情况,那么
site.py在引入
venv模块后似乎不再这样做。相反,它
pyvenv.cfg仅在一种情况下向上一级查找文件并为虚拟环境进行配置。当然,这对于PythonService.exe无效,后者已被埋藏在site-
packages下的pywin32模块中。
要解决此问题,我改编了
activate_this.py原始
virtualenv模块随附的代码。它用于引导嵌入在可执行文件中的解释器(PythonService.exe就是这种情况)以使用virtualenv。不幸的是,
venv不包括此。
这对我有用。请注意,这假定虚拟环境名为my-venv,并且位于源代码位置的上方一层。
import osimport sysif sys.executable.endswith("PythonService.exe"): # Change current working directory from PythonService.exe location to something better. service_directory = os.path.dirname(__file__) source_directory = os.path.abspath(os.path.join(service_directory, "..")) os.chdir(source_directory) sys.path.append(".") # Adapted from virtualenv's activate_this.py # Manually activate a virtual environment inside an already initialized interpreter. old_os_path = os.environ['PATH'] venv_base = os.path.abspath(os.path.join(source_directory, "..", "my-venv")) os.environ['PATH'] = os.path.join(venv_base, "scripts") + os.pathsep + old_os_path site_packages = os.path.join(venv_base, 'Lib', 'site-packages') prev_sys_path = list(sys.path) import site site.addsitedir(site_packages) sys.real_prefix = sys.prefix sys.prefix = venv_base new_sys_path = [] for item in list(sys.path): if item not in prev_sys_path: new_sys_path.append(item) sys.path.remove(item) sys.path[:0] = new_sys_path困扰我的另一个因素-Twisted伙计们提供了pywin32的新pypi轮,可以更轻松地安装pip。与使用easy_install将正式win32
exe软件包安装到虚拟env中时得到的软件包相比,该软件包中的PythonService.exe行为异常(调用时找不到pywin32 dll)。



