Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 960
Mateusz Jagiełło Avatar asked Oct 12 '12 14:10

Mateusz Jagiełło


People also ask

Can you import in an if statement Python?

Yes. As Martijin's answer pointed out that Official Python use this.

What is __ import __ in Python?

__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.

How do you check if a library is imported in Python?

Use: if "sys" not in dir(): print("sys not imported!")


2 Answers

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.

like image 193
Martijn Pieters Avatar answered Sep 20 '22 09:09

Martijn Pieters


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 
like image 40
mgilson Avatar answered Sep 17 '22 09:09

mgilson