Skip to main content
 首页 » 编程设计

python之如何限制可能抛出的导入

2025年05月04日17exmyth

我有一个通常在 Windows 下运行并使用 win32com 模块的类。我还有一个此类的模拟版本,用于测试和演示目的,它从原始版本导入,并且应该能够在任何地方运行。所以,它是这样的,在两个文件中:

import win32com.client 
class basic(): 
    def local_instance(self): 
        # called once during setup of execution 
        res = win32com.client.Dispatch('Foo.Bar') 
    def res_attrib(self): 
        # called repeatedly by threads; must re-instantiate COM obj 
        return win32com.client.Dispatch('Foo.Bar').Attribute 
    def otherstuf(self): 
        ... 
 
======================= 
from basic import basic 
 
class mock(basic): 
    def local_instance(self): 
        res = mock_foobar()    # mock implementation with .Attribute 
    def res_attrib(self): 
        return res.Attribute   # mock implementation, this is OK 
    # otherwise uses otherstuf() unchanged 

问题是当在没有 win32com 的环境中加载模拟版本时,import win32com.client 语句会抛出。

我的问题是,限制该导入应用的正确方法是什么?

  • 将导入嵌入到每个方法中,它将被重复执行:

    def local_instance(self): 
        import win32com.client 
        res = win32com.client.Dispatch('Foo.Bar') 
    def res_attrib(self): 
        import win32com.client 
        return win32com.client.Dispatch('Foo.Bar').Attribute 
    
  • 将 import 和 def 嵌套在 try block 中,如果用户尝试在 Windows 环境中运行 basic 但碰巧没有安装 win32com,它将奇怪地失败:

    try: 
        import win32com.client 
        def local_instance(self): 
            res = win32com.client.Dispatch('Foo.Bar') 
        def res_attrib(self): 
            return win32com.client.Dispatch('Foo.Bar').Attribute 
    except: 
        # alternate or no defs 
    
  • 还是其他?

请您参考如下方法:

nest the import and the def's inside a try block,

这是大多数人使用的标准方法。

在任何类定义之外执行此操作。在最顶层的普通进口。一次而已。

在模块中之后出现的任何类定义中使用这两个函数。

try: 
    import win32com.client 
    def local_instance(): 
        res = win32com.client.Dispatch('Foo.Bar') 
    def res_attrib(): 
        return win32com.client.Dispatch('Foo.Bar').Attribute 
except ImportError, why: 
    # alternate or no defs 

where it will fail strangely if user tries to run basic in a Windows environment but doesn't happen to have win32com installed:

这根本不是真的。

首先,您可以检查 why 变量。

其次,您可以检查 os.name 或 platform.uname() 以查看这是否是 Win32 并更改基于 except 的 block 在操作系统上。