Mateusz Jagiełło Mateusz Jagiełło - 10 days ago 5
Python Question

Python - import in if

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

if self.response_encoding == 'gzip':
import gzip


I didn't find any PEP about this code. However, it bothers me.

Answer

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.

Comments