我为 urllib (python3) 编写了小包装器。在 if中导入模块是否正确且安全?
if self.response_encoding == 'gzip':
import gzip
我没有找到有关此代码的任何 PEP。然而,它困扰着我。
我为 urllib (python3) 编写了小包装器。在 if中导入模块是否正确且安全?
if self.response_encoding == 'gzip':
import gzip
我没有找到有关此代码的任何 PEP。然而,它困扰着我。
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
测试的道德等价物:如果您可以 import check_output
,请这样做,否则在此处定义完整功能。
导入语句只是将外部代码重新绑定到本地名称。在这方面,使用控制流来控制导入与在语句中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
当然,那很好。在模块具有您并不总是想要运行的初始化代码的情况下,它甚至可能是必要的。
安全吗?是的。正如Martijin的回答所指出的,官方Python使用了这个。
合适吗?依靠。Python 性能文档指出,即使 python 可以避免导入相同的模块,仍然存在开销。
所以我相信你应该问问自己,if 语句多久是真的。如果经常,那么会有很大的开销,你应该在文件的开头导入它。如果不经常,那么在 if 语句中导入是一个明智的选择。