如何在windows 10上为嵌入式python设置virtualenv

2024-03-29 01:26:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在Python中嵌入到Wi10中的C++中。我想在虚拟环境中做这件事。我现在面临两个问题,可能第一个问题解决了,第二个问题就消失了,所以我会尝试在这篇文章中介绍这两个问题

以下是我的问题的简短摘要
问题1。当我试图通过c++
使用虚拟环境时,python报告错误,表示没有编码模块 问题2。在安装了虚拟环境

后,C++在加载^ {< CD1>}后无法加载Python模块

以下是完整的描述
我的电脑只有一个python版本,那就是python 3.8

通过cmd.exe在win 10中创建初始虚拟环境

cd C:\Users\A\pythonTest
virtualenv ./venvpy3

C:\Users\A\pythontest\testing.py

def SayHello()
    print("SayHello")

main.cpp

Py_SetPythonHome(L"C:\\Users\\A\\pythonTest\\venvpy3");
Py_Initialize();

CPyObject sys = PyImport_ImportModule("sys");
CPyObject path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyUnicode_FromString("C:\\Users\\A\\pythonTest"));

CPyObject pName = PyUnicode_FromString("testing");
CPyObject pModule = PyImport_Import(pName);

if (pModule)
{
    CPyObject pFunc = PyObject_GetAttrString(pModule, "SayHello");
    if (pFunc && PyCallable_Check(pFunc))
    {
        PyObject_CallObject(pFunc, NULL);
    }
    else
    {
        printf("ERROR: 001\n");
    }
}
else
{
    printf_s("ERROR: Module not imported\n");
}

在所有这些之后,我成功地构建了exe并运行它。python提供的错误消息告诉我C:\Users\A\pythonTest\venvpy3\Lib\中没有编码模块。我试图安装这个软件包,但没有成功。然后,我从C:\Users\A\AppData\Local\Programs\python\...\Lib复制除站点数据包之外的所有文件。然后我再次运行exe,似乎没有问题

然后我将import pandas as pd添加到testing.py。我还将模块安装到virtualenv。我再次运行exe,然后从main.cpp打印错误消息ERROR: Module not imported

现在我真的不知道怎么解决它。而且似乎将所有文件从C:\Users\A\AppData\Local\python...\Lib复制到我的virtualenv不是一种正确的方法

正如其他一些线程所建议的那样,我添加并设置了环境变量PYTHONHOMEPYTHONPATH,但没有任何帮助

当前的变通方法:
我发现,如果我继续使用操作系统默认的python环境,并从虚拟环境添加额外的包,似乎没有问题。不确定这是否是解决问题的正确方法

main.cpp

// Py_SetPythonHome(L"C:\\Users\\A\\pythonTest\\venvpy3");
Py_Initialize();

CPyObject sys = PyImport_ImportModule("sys");
CPyObject path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyUnicode_FromString("C:\\Users\\A\\pythonTest"));
PyList_Append(path, PyUnicode_FromString("C:\\Users\\A\\pythonTest\\venvpy3\\Lib\\site-packages"));

CPyObject pName = PyUnicode_FromString("testing");
CPyObject pModule = PyImport_Import(pName);

if (pModule)
{
    CPyObject pFunc = PyObject_GetAttrString(pModule, "SayHello");
    if (pFunc && PyCallable_Check(pFunc))
    {
        PyObject_CallObject(pFunc, NULL);
    }
    else
    {
        printf("ERROR: 001\n");
    }
}
else
{
    printf_s("ERROR: Module not imported\n");
}

Tags: 模块pathsys虚拟环境errorexeuserspyobject
1条回答
网友
1楼 · 发布于 2024-03-29 01:26:53

tl;博士

检查包含PYTHONPATH的内容。如果是空的,您需要修改venvpy3\Script\activate.bat,并在PYTHONPATH中包含virtualenv的站点包

set "PYTHONPATH=%VIRTUAL_ENV%\Lib\site-packages"

请记住,一旦您通过修改venvpy3\Script\deactivate.bat停止virtualenv,请将其取消设置

set PYTHONPATH=

解释

我尝试在我的计算机(Python 3.8.2,Windows 10)中复制您的问题

设置

首先,我创建了虚拟环境venvpy3

cd project
virtualenv venvpy3

然后我写了这些文件:

main.cpp

#include "Python.h"
#include "pyhelper.hpp"

int main(){
    Py_Initialize();
    CPyObject sys = PyImport_ImportModule("sys");
    CPyObject path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path, PyUnicode_FromString("C:\\project"));
    CPyObject pName = PyUnicode_FromString("testing");
    CPyObject pModule = PyImport_Import(pName);
    
    if (pModule){
        CPyObject pFunc = PyObject_GetAttrString(pModule, "SayHello");
        if (pFunc && PyCallable_Check(pFunc)){
            PyObject_CallObject(pFunc, NULL);
        }
        else{
            printf("ERROR: 001\n");
        }
    }
    else{
        printf_s("ERROR: Module not imported\n");
    }
    return 0;
}

测试.py

import pandas

def SayHello():
    print("SayHello")

if __name__ == "__main__":
    SayHello()

(我将跳过pyhelper.hpp和Makefile)编译并运行。是的,二进制代码运行,但python代码不会运行,因为我没有在系统中安装pandas ERROR: Module not imported。好的激活virtualenv并安装pandas的时间到了

venvpy3\Script\activate.bat
pip install pandas

是的,当我的系统没有安装pandasERROR: Module not imported时,我仍然有同样的问题

解决方案

好的,是时候检查一下我的PYTHONPATH发生了什么

echo %PYTHONPATH%

它是空的。是时候修改venvpy3\Script\activate.bat并包含我的virtualenv Python包了。在文件的末尾,我包括

set "PYTHONPATH=%VIRTUAL_ENV%\Lib\site-packages"

在进入virtualenv之前,我的PYTHONPATH是空的,所以我需要在完成会话时取消设置它。编辑venvpy3\Script\deactivate.bat的时间到了

set PYTHONPATH=

好的,该测试了

venvpy3\Script\deactivate.bat
venvpy3\Script\activate.bat

运行并成功,程序说SayHello。最后一次考试的时间到了

venvpy3\Script\deactivate.bat

运行并失败:ERROR: Module not imported

但是如果我的PYTHONPATH有一些以前的信息怎么办

好的,在附加virtualenv Python包之前,我们需要保留以前的信息,以便在离开virtualenv时恢复原始信息

需要在venvpy3\Script\activate.bat中追加的代码如下所示:

if not defined _OLD_PYTHONPATH goto ENDIFPYPATH1
    set "PYTHONPATH=%VIRTUAL_ENV%\Lib\site-packages;%PYTHONPATH%"
:ENDIFPYPATH1
if defined _OLD_PYTHONPATH goto ENDIFPYPATH2
    set "_OLD_PYTHONPATH=%PYTHONPATH%"
    set "PYTHONPATH=%VIRTUAL_ENV%\Lib\site-packages"
:ENDIFPYPATH2

这个代码在venvpy3\Script\deactivate.bat

if defined _OLD_PYTHONPATH goto ENDIFPYPATH1
    set PYTHONPATH=
:ENDIFPYPATH1
if not defined _OLD_PYTHONPATH goto ENDIFPYPATH2
    set "PYTHONPATH=%_OLD_PYTHONPATH%"
    set _OLD_PYTHONPATH=
:ENDIFPYPATH2

虽然,说实话,它需要更多的测试

在嵌入Python时,是否每次创建新环境时都必须修改activate.bat/deactivate.bat

可悲的是,是的。理论上,生成最终脚本的基本脚本必须在某个地方,但我不知道在哪里,可能在二进制virtualenv.exe中

相关问题 更多 >