开发者

How to limit import that may throw

I have a class that will normally run under Windows and uses the win32com module. I also have a mock version 开发者_StackOverflow中文版of this class, both for testing and for demo purposes, which imports from the original, and should be able to run anywhere. So, it's like this, in two files:

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

The problem with this is when the mock version is loaded in an environment without win32com, the import win32com.client statement throws.

My question is, what's the correct approach to limiting the application of that import?

  • embed the import inside each of the methods, where it will be executed repeatedly:

    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
    
  • nest the import and the def's inside a try block, where it will fail strangely if user tries to run basic in a Windows environment but doesn't happen to have win32com installed:

    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
    
  • or other?


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

This is the standard approach that most people use.

Do this outside any class definitions. At the very top level with your ordinary imports. Once only.

Use the two functions within any class definition which occurs after this in the module.

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:

This is not true at all.

First, you can examine the why variable.

Second, you can examine os.name or platform.uname() to see if this is Win32 and alter the except block based on operating system.


S.Lott has the real answer, but let me adress a possible miconception: "embed the import inside each of the methods, where it will be executed repeatedly:"

While technically the import statement itself would indeed execute multiple times if imbedded in each method, the interpreter will only actually process the module the first time. Subsequent calls to import an already imported module won't actually do anything or take any measurable time. This was designed for effeciency reasons. There is some discussion of this at: http://docs.python.org/tutorial/modules.htm under section 6.1.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜