为什么我突然收到 win32com.client 的无属性 'CLSIDToPackageMap' 错误?
Why am I suddenly getting a no attribute 'CLSIDToPackageMap' error with win32com.client?
代码
import win32com.client as win32
Excel = win32.gencache.EnsureDispatch('Excel.Application')
曾经有效,但现在产生错误:
AttributeError: 'module' object has no attribute 'CLSIDToPackageMap'
怎么回事?
删除C:\Temp\gen_py后,上面的代码又可以运行了。希望能省事!
此属性错误的主要原因是您的 COM 服务器已从后期绑定(动态)转变为早期绑定(静态)。
- 在后期绑定中,每当调用一个方法时,都会查询对象以查找该方法,如果成功,则可以进行调用。
- 在早期绑定中,对象模型的信息是根据对象调用提供的类型信息预先确定的。早期绑定使用 MakePy。此外,早期绑定区分大小写。
有两种方法可以解决此问题:
使用动态模块强制您的代码以面向后期绑定的方式工作。使用示例:
"win32com.client.Dispatch()" instead of "win32.gencache.EnsureDispatch('Excel.Application')"
早期面向绑定的方式使用驼峰敏感关键字。使用示例:
"excel.Visible()" instead of "excel.VISIBLE()" or "excel.visible()"
我猜,代码在删除 gen_py 文件夹后适用于第一个 运行,但从第二个 运行 开始会抛出错误,因为 win32.gencache.EnsureDispatch 是早期绑定 Dispatch , gen_py 文件夹将被重新创建。
我在 Github discussion 上找到了一个更优雅的解决方案并将其合并到一个函数中。为我工作。
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
代码
import win32com.client as win32
Excel = win32.gencache.EnsureDispatch('Excel.Application')
曾经有效,但现在产生错误:
AttributeError: 'module' object has no attribute 'CLSIDToPackageMap'
怎么回事?
删除C:\Temp\gen_py后,上面的代码又可以运行了。希望能省事!
此属性错误的主要原因是您的 COM 服务器已从后期绑定(动态)转变为早期绑定(静态)。
- 在后期绑定中,每当调用一个方法时,都会查询对象以查找该方法,如果成功,则可以进行调用。
- 在早期绑定中,对象模型的信息是根据对象调用提供的类型信息预先确定的。早期绑定使用 MakePy。此外,早期绑定区分大小写。
有两种方法可以解决此问题:
使用动态模块强制您的代码以面向后期绑定的方式工作。使用示例:
"win32com.client.Dispatch()" instead of "win32.gencache.EnsureDispatch('Excel.Application')"
早期面向绑定的方式使用驼峰敏感关键字。使用示例:
"excel.Visible()" instead of "excel.VISIBLE()" or "excel.visible()"
我猜,代码在删除 gen_py 文件夹后适用于第一个 运行,但从第二个 运行 开始会抛出错误,因为 win32.gencache.EnsureDispatch 是早期绑定 Dispatch , gen_py 文件夹将被重新创建。
我在 Github discussion 上找到了一个更优雅的解决方案并将其合并到一个函数中。为我工作。
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