在PyWin32存在的情况下,我应该如何(或者我应该)完成python?

时间:2013-01-10 12:11:13

标签: python pywin32

我们有一段使用PyWin32的代码,偶尔会调用Py_Finalize()和Py_Initialize()来重新初始化python。我们发现了一个错误,其中一个动态创建的类class error是在pywintypes(PyWinTypesmodule.cpp,第860行)中使用PyRun_String()的字符串创建的,不会在之后重新创建重新初始化。此类最终在重新初始化后使用,并在尝试调用函数len()时抛出“NoneType不可调用”错误。

我们观察到,如果在调用Py_Finalize()之前,我们调用PyWinTypes导出PyWinGlobals_Free(),该错误就会停止发生,该导出位于上面链接的同一源文件中。

在PyWin32代码库的另一个地方(在dllmain.cpp中),有以下函数,在regsvr32.exe中进行COM注册/取消注册后清理时调用:

void PyCom_DLLReleaseRef(void)
{
    /*** NOTE: We no longer finalize Python EVER in the COM world
         see pycom-dev mailing list archives from April 2000 for why
    ***/
    // Must be thread-safe, although cant have the Python lock!
    // only needed when we finalize.
    //  CEnterLeaveFramework _celf;
    LONG cnt = InterlockedDecrement(&g_cLockCount);
    // Not optimal, but anything better is hard - g_cLockCount
    // could always transition 1->0->1 at some stage, screwing this
    // up.  Oh well...
    if (cnt==0) {
        // Send a quit message to the registered thread (if we have one)
        if (dwQuitThreadId)
            PostThreadMessage(dwQuitThreadId, WM_QUIT, 0, 0);
        /*** Old finalize code
             if (bDidInitPython) {
             PyEval_RestoreThread(ptsGlobal);
             PyWinGlobals_Free();
             FreeGatewayModule();
             Py_Finalize();

             bDidInitPython=FALSE;
             }
        ***/
    }
}

这里有两件值得注意的事情:

  1. 顶部有一个神秘的评论,暗示在这种情况下没有最终确定Python的原因。不幸的是,它所指的“pycom-dev”邮件列表似乎不再存在。我认为this是相关主题的正确链接,但pythonpros.com似乎是一些sedo域名停放的东西。

  2. 注释掉的“旧的终结代码”确实在最终化python之前调用了PyWinGlobals_Free(),这表明我们可能正在使用我们的修复程序。但是,除了源代码中这个神秘的代码片段之外,我们还无法在Web上找到任何文档或信息,表明在使用PyWin32时最终确定python之前必须做任何特殊操作。还有一些其他的调用:FreeGatewayModules()和PyEval_RestoreThread()。我不确定我们是否应该自己打电话。

  3. 我们的解决方案似乎有效,如果没有更多信息,我们可能会继续使用它,但获得一些确认会很好。

1 个答案:

答案 0 :(得分:1)

答案来自python-win32邮件列表:http://mail.python.org/pipermail/python-win32/2013-January/012671.html

  

不幸的是,反复初始化有很多问题   最终确定Python,因此你在pywin32中看到的代码不再存在   试图支持它。简短的故事就是这样做   不支持使用pywin32(至少在Python中的问题之前)   通过支持这个的新模块API修复,pywin32是   相应调整)

     马克[哈蒙德]