python-3.x 为什么我在使用win32com.client时突然收到一个没有属性的“CLSIDToPackageMap”错误?

inb24sb2  于 2023-01-18  发布在  Python
关注(0)|答案(4)|浏览(375)

守则

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

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

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

这是怎么回事?

wydwbb8l

wydwbb8l1#

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

vvppvyoh

vvppvyoh2#

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

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

有两种方法可以解决此问题:
1.使用动态模块强制代码以面向后期绑定的方式工作。使用示例:

"win32com.client.Dispatch()" instead of "win32.gencache.EnsureDispatch('Excel.Application')"

1.使用区分大小写的camelcase关键字作为早期绑定的方式。使用示例:

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

我猜,删除gen_py文件夹后第一次运行的代码工作正常,但第二次运行时抛出错误,因为win32.gencache.EnsureDispatch是早期绑定Dispatch,将再次创建gen_py文件夹。

bxjv4tth

bxjv4tth3#

我在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
f3temu5u

f3temu5u4#

谢谢-添加您的功能并进行此更改后,工作起来很有魅力:

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

真诚的
日本

相关问题