如何限制可能抛出的导入

时间:2011-07-22 15:00:54

标签: python

我有一个通常在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
    
  • 将导入和def嵌套在try块中,如果用户尝试在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
    
  • 或其他?

2 个答案:

答案 0 :(得分:5)

  

将导入和def嵌套在try块中,

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

之外执行任何类定义。与您的普通进口处于最顶层。只有一次。

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

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
  

如果用户尝试在Windows环境中运行基本但没有安装win32com,它将会奇怪地失败:

这根本不是真的。

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

其次,您可以检查os.nameplatform.uname()以查看这是否为Win32并根据操作系统更改except块。

答案 1 :(得分:1)

S.Lott有真正的答案,但让我说一下可能的miconception:“将导入嵌入到每个方法中,重复执行:”

虽然从技术上讲,如果嵌入在每个方法中,import语句本身确实会执行多次,但解释器只会在第一次实际处理模块。导入已导入模块的后续调用实际上不会执行任何操作或占用任何可测量的时间。这是出于效率原因而设计的。在第6.1节的http://docs.python.org/tutorial/modules.htm处对此进行了一些讨论。