Python-在if中导入

Python-在if中导入,python,if-statement,python-import,Python,If Statement,Python Import,我为urllib(python3)编写了小包装器。在if中导入模块是否适当和安全 我没有找到任何关于这段代码的鼓动。不过,这让我很烦恼。当然,没关系。甚至在模块有初始化代码而您并不总是想运行的情况下,它也是必要的。这实际上是一个相当常见的习惯用法。您有时会看到在不同模块之间进行选择: if system == 'linux': import linuxdeps as deps elif system == 'win32': import win32deps as deps 然后,假

我为urllib(python3)编写了小包装器。在if中导入模块是否适当和安全


我没有找到任何关于这段代码的鼓动。不过,这让我很烦恼。

当然,没关系。甚至在模块有初始化代码而您并不总是想运行的情况下,它也是必要的。

这实际上是一个相当常见的习惯用法。您有时会看到在不同模块之间进行选择:

if system == 'linux':
   import linuxdeps as deps
elif system == 'win32':
   import win32deps as deps
然后,假设
linuxdeps
win32deps
具有相同的函数,您可以使用它:

deps.func()
这甚至用于在标准库中获取
os.path
(以下是
os
的一些源代码):


Python标准库使用它,因此它绝对是正确和安全的。有关一个优秀的示例,请参见:

在python中有条件地导入模块是很常见的。除了ImportError:组合之外,您通常会看到一个
try:
/
组合,而不是
if

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
测试的道德等价物:如果您可以导入
检查输出
,那么就这样做,否则在这里定义完整的函数

导入语句只是将外部代码段重新绑定到本地名称。在这方面,使用
if
控制流来控制导入与在
if
语句中分配变量没有什么不同。您需要确保在未定义名称的情况下不会使用该名称。

安全吗?对正如前面所指出的,官方Python使用这种方法

这合适吗?视情况而定。指出,尽管python可以避免导入相同的模块,但仍然存在开销


所以我相信你应该问问自己,if的陈述有多少次是正确的。如果非常频繁,那么会有很大的开销,您应该在文件的开头导入它。如果不经常,那么在If语句中导入是明智的选择。

只要确保不要调用来自此包的任何函数,如果它没有被导入是的。你为什么不高兴?我想问问你,确定一下。也许我应该用“担心”这个词。英语不是我的母语。我认为它让人们感到困扰,因为在其他语言中,类似于“import”的结构是静态声明,而在python中它们是可执行的。提示:您可以在函数中执行“从x导入*”。但是不要。因为这意味着该函数现在有一个局部变量集,在编译该函数时无法确定该局部变量集,因此该函数有不同的内部结构,这些内部结构更混乱、更慢,并且局部变量可能会被删除。(如果在func中执行“exec”而不使用“in”,则相同)。这些用法已被弃用。+1--
try/except importorror
也是我回答这个问题的第一反应。
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 '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
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