Python-импорт в if
Я написал небольшую обертку для urllib (python3). Это правильный и безопасное импортировать модуль в if?
if self.response_encoding == 'gzip':
import gzip
Я не нашел никакого PEP об этом коде. Однако меня это беспокоит.
4 ответов
стандартная библиотека Python использует его, поэтому он наиболее определенно правильный и безопасный. Вижу os
модуль отличный пример:
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
это довольно распространено для условного импорта модулей в python. Вместо if
, вы часто будете видеть try:
/except ImportError:
сочетание тоже:
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
здесь мы в основном используем моральный эквивалент if
ТЕСТ: Если вы можете импортировать check_output
, сделайте так, в противном случае определите полная функция здесь.
оператор import-это просто повторная привязка внешнего фрагмента кода к локальному имени. С помощью if
поток управления для управления импортом ничем не отличается от назначения переменной в if
заявление в этой связи. Вам нужно убедиться, что вы не используете имя без его определения в любом случае.
это довольно распространенная идиома на самом деле. Иногда вы увидите его, чтобы выбрать между различными модулями:
if system == 'linux':
import linuxdeps as deps
elif system == 'win32':
import win32deps as deps
затем, предполагая, что оба linuxdeps
и win32deps
имеют такие же функции, вы можете просто использовать это:
deps.func()
это даже используется, чтобы сделать os.path
в стандартной библиотеке (часть исходного кода для os
ниже):
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
Конечно, все в порядке. Это может быть даже необходимо в тех случаях, когда модуль имеет код инициализации, который вы не всегда хотите запускать.
Это безопасно? Да. As Martijin это указал, что официальный Python использует это.
разве это правильно? Зависит. Python performance docs указывает, что, хотя python может избежать импорта того же модуля, все еще есть накладные расходы.
поэтому я считаю, что вы должны спросить себя, как часто если утверждение верно. Если очень часто, то будут большие накладные расходы, и вы должны импортировать его в начале файла. Если не часто, то импорт в if оператор является мудрым выбором.