运维驿站Linux运维进阶-Python,Docker,Shell

理解python的import与__import__

2020-04-02  本文已影响0人  My熊猫眼

import 和“__import__”都是用来导入module的,但是二者还是有所不同, 可以查看帮助文档来了解其不同.
先通过 help("import") 查看其帮助,可以找到如下的说明:

The basic import statement (no "from" clause) is executed in two
steps:
1. find a module, loading and initializing it if necessary
2. define a name or names in the local namespace for the scope  where the "import" statement occurs.

上面描述了import 做的两步工作,首先是 查找一个模块,然后初始化这个模块,我个人对这一步的理解是这样的
首先是根据sys.path的值,在相应的目录下查找以module name 命名的.pyc/.py 文件或者目录,如果找到的是.py/.pyc 文件(比如socket 模块), 那么就执行这个.py/.pyc 文件,从而完成导入;如果找到的是以module name 命名的目录,这个目录里面通常包含一个 __init__.py / __init__.pyc 的文件, 就是调用这个文件来完成模块导入以及初始化的(比如 pkg_resources 模块). import 除了载入模块并完成初始化,还做了step 2 的工作:在import 发生的scope, 定义相应的namespace.

再通过help(__import__) 查看其帮助,我们可以看到如下的片段:

    __import__(name, globals=None, locals=None, fromlist=(), level=0) -> module
    Import a module. Because this function is meant for use by the Python
    interpreter and not for general use it is better to use
    importlib.import_module() to programmatically import a module.

这里可以看到 __import__ 是一个方法,这是__builtins__ 模块内置的一个方法,返回值是一个module,所以可以通过 __import__(ModuleName).Method的方式来使用,比如在一些项目中会看到__import("pkg_resources")__.run_script() 这样的方式来使用这种导入

既然两者都可以导入module, 那么使用上怎么选择呢?
import 导入模块之后,就在相应的namespace 中存在了,除非明确用del 从当前的namespace中移出,否则始终可以访问到;
而用__import__ 导入,返回的是一个 模块,可以引用这个模块,但是这个模块并不会“驻留”到相应的namespace. 也就是常用于 动态加载模块,从而可以根据需要 动态使用,节省系统资源;比如某个python 程序需要引用20个模块,但是这20个模块都只是引用其中某一个方法,那么完全没有必要 让这20个模块一直驻留在相应的namespace, 从而节省系统资源;

本文原创,转载请注明出处.

上一篇下一篇

猜你喜欢

热点阅读