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.
Yes. As Martijin's answer pointed out that Official Python use this.
__import__() Parameters name - the name of the module you want to import. globals and locals - determines how to interpret name. fromlist - objects or submodules that should be imported by name. level - specifies whether to use absolute or relative imports.
Use: if "sys" not in dir(): print("sys not imported!")
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.
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 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With