为什么我突然收到 win32com.client 的无属性“CLSIDToPackageMap”错误?

问题描述 投票:0回答:4

代码

import win32com.client as win32 
Excel = win32.gencache.EnsureDispatch('Excel.Application') 

曾经可以工作,但现在会产生错误:

AttributeError: 'module' object has no attribute 'CLSIDToPackageMap'

发生什么事了?

python-3.x win32com
4个回答
50
投票

删除

C:\Temp\gen_py
后,上面的代码又可以工作了。希望可以省去麻烦!

PS. 或者,您可以尝试在

gen_py
文件夹中搜索
%TEMP%


9
投票

我在Github讨论上找到了一个更优雅的解决方案,并将其合并到一个函数中。为我工作。

def dispatch(app_name:str):
    try:
        from win32com import client
        app = client.gencache.EnsureDispatch(app_name)
    except AttributeError:
        # Corner case dependencies.
        import os
        import re
        import sys
        import shutil
        # Remove cache and try again.
        MODULE_LIST = [m.__name__ for m in sys.modules.values()]
        for module in MODULE_LIST:
            if re.match(r'win32com\.gen_py\..+', module):
                del sys.modules[module]
        shutil.rmtree(os.path.join(os.environ.get('LOCALAPPDATA'), 'Temp', 'gen_py'))
        from win32com import client
        app = client.gencache.EnsureDispatch(app_name)
    return app

8
投票

出现此属性错误的主要原因是您的 COM 服务器已从后期绑定(动态)转变为早期绑定(静态)。

  • 在后期绑定中,每当调用方法时,都会在对象中查询该方法,如果成功,则可以进行调用。
  • 在早期绑定中,对象模型的信息是根据对象调用提供的类型信息预先确定的。早期绑定使用 MakePy。此外,早期绑定区分大小写。

有两种方法可以解决此问题:

  1. 使用动态模块强制您的代码以面向后期绑定的方式工作。使用示例:

    "win32com.client.Dispatch()" instead of "win32.gencache.EnsureDispatch('Excel.Application')" 
    
  2. 使用驼峰式敏感关键字进行早期绑定方式。使用示例:

    "excel.Visible()" instead of "excel.VISIBLE()" or "excel.visible()"
    

我猜,代码在删除 gen_py 文件夹后第一次运行时有效,但第二次运行时会抛出错误,因为 win32.gencache.EnsureDispatch 是早期绑定调度,将再次创建 gen_py 文件夹。


-1
投票

谢谢 - 添加功能并进行此更改后,效果非常好:

#excel = win32.gencache.EnsureDispatch('Excel.Application')    
excel = dispatch('Excel.Application')

真诚的,

js

© www.soinside.com 2019 - 2024. All rights reserved.