最近遇到了很多关于python模块导入的问题,这里记录一下
一个 module 内的 Python 代码通过 importing 操作就能够访问另一个模块内的代码。 import
语句是发起调用导入机制的最常用方式,但不是唯一的方式。 importlib.import_module()
以及内置的 __import__()
等函数也可以被用来发起调用导入机制。
关键字
使用all = ['','']
name
name 是一个全局变量,代表模块的名字,即命名空间。
Python有一个经典的判断语句 if name == main:,当Python文件被当做脚本直接执行时,name变量的值会变为main,从而使该判断语句成立,并执行该语句下的其他代码; 而当Python文件被当做模块/包导入时,它的值表示的是模块名.
import
import关键字是Python中用来导包的,常见的import语句有四种:
1.import module: 这种形式会导入module下所有文件,如果module下有很多模块,而你并没有全部用到,显然会浪费很多内存(加载代码)。
2.from module import sub_module/func:这种形式是导入module下的某个子模块,或者定义的某个函数,因为只是导入我们需要的模块,所以并不会像第一种方式很浪费内存,也推荐这种方式。
3.from module import sub_module/func as new_module:这种形式与第二种形式差不多,但是可以使用我们自定义的名称,看个人需求。
4.from module import *:这种形式也是导入module下所有文件,不同于第一种,这种不需要加上module前缀。举个例子,比如module下有个test函数,第一种方式是这样的module.test();而第四种方式是这样的test()。
sys.path
一个由字符串组成的列表,用于指定模块的搜索路径。初始化自环境变量 PYTHONPATH
,再加上一条与安装有关的默认路径。
sys.path 是一个列表,它的作用是存储Python模块的搜索路径。一般情况下,该变量存储的路径有当前路径,内置模块路径等。
我们经常报模块找不到,很大程度可以通过设置sys.path变量来解决。
命令行参数
在Python的模块导入中,还有两个命令行参数也被多次提到,分别是 -c
和 -m
。
python -c:传递一个字符串形式的Python程序,并执行
python -c "import sys; print(sys.path)"
python -m:将一个Python模块当成脚本使用,具体可以参见这篇文章。
sys.moudles
sys.modules是一个全局字典,该字典是python启动后就加载在内存中。每当程序员导入新的模块,sys.modules都将记录这些模块。字典sys.modules对于加载模块起到了缓冲的作用。当某个模块第一次导入,字典sys.modules将自动记录该模块。当第二次再导入该模块时,python会直接到字典中查找,从而加快了程序运行的速度。
import()
import(name, globals=None, locals=None, fromlist=(), level=0)
该函数会导入 name 模块,有可能使用给定的 globals 和 locals 来确定如何在包的上下文中解读名称。 fromlist 给出了应该从由 name 指定的模块导入对象或子模块的名称。 标准实现完全不使用其 locals 参数,而仅使用 globals 参数来确定
import
语句的包上下文。
level 指定是使用绝对还是相对导入。0
(默认值) 意味着仅执行绝对导入。 level 为正数值表示相对于模块调用__import__()
的目录,将要搜索的父目录层数 (详情参见 PEP 328)。
当 name 变量的形式为package.module
时,通常将会返回最高层级的包(第一个点号之前的名称),而 不是 以 name 命名的模块。 但是,当给出了非空的 fromlist 参数时,则将返回以 name 命名的模块。
importlib.import_module
importlib.import_module(name, package=None)
导入一个模块。参数 name 指定了以绝对或相对导入方式导入什么模块 (比如要么像这样 pkg.mod
或者这样 ..mod
)。如果参数 name 使用相对导入的方式来指定,那么那个参数 packages 必须设置为那个包名,这个包名作为解析这个包名的锚点 (比如 import_module('..mod', 'pkg.subpkg')
将会导入 pkg.mod
)。
import_module()
函数是一个对 importlib.__import__()
进行简化的包装器。 这意味着该函数的所有主义都来自于 importlib.__import__()
。 这两个函数之间最重要的不同点在于 import_module()
返回指定的包或模块 (例如 pkg.mod
),而 __import__()
返回最高层级的包或模块 (例如 pkg
)。
如果动态导入一个自从解释器开始执行以来被创建的模块(即创建了一个 Python 源代码文件),为了让导入系统知道这个新模块,可能需要调用 invalidate_caches()
。
在 3.3 版更改: 父包会被自动导入。