Python与非latin-1 PYTHONHOME路径

时间:2016-05-19 06:58:29

标签: python windows utf-8 latin1

在我的情况下,我将Python嵌入到我的应用程序中。当我的应用程序的路径包含一个非latin-1字符 Py_Initialize 在内部调用exit(1)时(以后的更多信息)。

所以我检查了是否可以使用标准解释器可执行文件重现这一点。

当PYTHONHOME的路径包含latin-1字符集之​​外的字符时,Windows上的Python-2.7.x似乎不起作用。问题是无法找到并导入模块 site 。由于变音符号似乎有效,这里的实际限制是什么?只支持latin-1吗?那为什么它可以在OSX上运行呢?

C:\Users\ъ\Python27\python.exe    // fails to start (KOI8-R)
         ^
C:\Users\ġ\Python27\python.exe    // fails to start (latin-3)
         ^
C:\Users\ä\Python27\python.exe    // works fine (latin-1)
         ^

有什么想法吗?

背景

我还没有完成代码,但是当 site 不可用时,Python 2.6和Python 2.7的行为也不同。 Py 2.6只打印一条消息,Py 2.7拒绝启动。

static void
initsite(void)
{
    PyObject *m;
    m = PyImport_ImportModule("site");
    if (m == NULL) {
        ...

        // Python 2.7 and later
        exit(1);

        // Python 2.6 and prior
        PyFile_WriteString("'import site' failed; traceback:\n", f);
    }
    ...
}

Python 2.7 https://github.com/enthought/Python-2.7.3/blob/master/Python/pythonrun.c#L725

Python 2.6 https://github.com/python-git/python/blob/master/Python/pythonrun.c#L705

2 个答案:

答案 0 :(得分:2)

我认为问题在于内部,Python2将所有内容处理为平台系统编码中的字节字符串(在西欧)CP1252是Latin-1的变体。因此,它无法正确处理包含其他字符的PYTHONHOME路径

但是,当我年轻的时候,我已经习惯了旧的8.3格式的MS / DOS文件......

我仍然可以在控制台(CMD.EXE)窗口中的{7}的Windows 7框中看到(并使用它们)。此格式仅使用ASCII大写字符和tilda(DIR /X),因此可以将其用作解决方法:只需在环境变量PYTHONHOME中声明8.3路径,然后使用该8.3路径启动python。

顺便说一下,建议PYTHONHOME使用既不包含特殊字符也不包含空格的路径。它可以工作,但它可能会导致其他模块出现问题

答案 1 :(得分:2)

查看PyImport_ImportModule function version 2.7给出了这个定义:

PyObject *
PyImport_ImportModule(const char *name)
{
    PyObject *pname;
    PyObject *result;

    pname = PyString_FromString(name);
    if (pname == NULL)
        return NULL;
    result = PyImport_Import(pname);
    Py_DECREF(pname);
    return result;
}

查看PyImport_ImportModule function version 3.5时除了

之外,给出了相同的内容
pname = PyUnicode_FromString(name);

而不是

pname = PyString_FromString(name);

你可以看一下the code for PyString_FromStringthe code for PyUnicode_FromString,但很明显python 2不使用unicode和python 3,但是我无法找到这导致你描述的行为。

PyImport_Import(module_name) function (version 2.7)仅使用module_name,如此:

r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
                          globals, silly_list, 0, NULL);

传递责任......