Python - import in if

后端 未结 4 1801
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-15 16:18

I wrote little wrapper for urllib (python3). Is it proper and safe to import module in if?

if self.response_encodi         


        
相关标签:
4条回答
  • 2020-12-15 16:46

    The Python standard library uses it, so it is most definitely proper and safe. See the os module source for an excellent example:

    if 'posix' in _names:
        name = 'posix'
        linesep = '\n'
        from posix import *
        try:
            from posix import _exit
        except ImportError:
          pass
        import posixpath as path
        import posix
        __all__.extend(_get_exports_list(posix))
        del posix
    

    It's quite common to conditionally import modules in python. Instead of if, you'll often see a try:/except ImportError: combination too:

    try:
        from subprocess import check_output
    except ImportError:
        # Python 2.6 and before
        def check_output(*popenargs, **kwargs):
            from subprocess import Popen
            if 'stdout' in kwargs:
                raise ValueError('stdout argument not allowed, it will be '
                                 'overridden.')
            process = Popen(stdout=PIPE, *popenargs, **kwargs)
            output, unused_err = process.communicate()
            retcode = process.poll()
            if retcode:
                cmd = kwargs.get("args")
                if cmd is None:
                    cmd = popenargs[0]
                raise CalledProcessError(retcode, cmd)
            return output
    

    Here, we basically use the moral equivalent of an if test: If you can import check_output, do so, otherwise define the full function here.

    An import statement is just a re-binding of an external piece of code to a local name. Using an if control flow to control the import is no different from assigning a variable in an if statement in that regard. You need to make sure you don't end up using the name without it being defined either way.

    0 讨论(0)
  • 2020-12-15 16:47

    This is a reasonably common idiom actually. You'll sometimes see it to pick between different modules:

    if system == 'linux':
       import linuxdeps as deps
    elif system == 'win32':
       import win32deps as deps
    

    Then, assuming both linuxdeps and win32deps have the same functions, you can just use it:

    deps.func()
    

    This is even used to get os.path in the standard library (some of the source code for os follows):

    if 'posix' in _names:
        name = 'posix'
        linesep = '\n'
        from posix import *
        try:
            from posix import _exit
        except ImportError:
            pass
        import posixpath as path
    
        import posix
        __all__.extend(_get_exports_list(posix))
        del posix
    
    elif 'nt' in _names:
        name = 'nt'
        linesep = '\r\n'
        from nt import *
        try:
            from nt import _exit
        except ImportError:
            pass
        import ntpath as path
    
        import nt
        __all__.extend(_get_exports_list(nt))
        del nt
    
    0 讨论(0)
  • 2020-12-15 16:50

    Sure, that's fine. It can even be necessary in cases where the module has initialization code that you don't always want to run.

    0 讨论(0)
  • 2020-12-15 16:52

    Is it safe? Yes. As Martijin's answer pointed out that Official Python use this.

    Is it proper? Depends. Python performance docs points out that even though python can avoid import the same module, there is still overhead.

    So i believe you should ask yourself, how often the if statement is true. If very often, then there will be large overhead, and you should import it at the beginning of the file. If not often, then import in if statement is a wise choice.

    0 讨论(0)
提交回复
热议问题