模块2----模块包和高级模块话题
模块包:包是通过使用“点模块名称”创建Python模块命名空间的一种方法
基础:
1.导入指定目录路径也叫包导入,实际上,包导入就是把计算机上的目录变成另一个Python命名空间,而属性则对应目录中所包含的子目录和模块文件。
比如导入:dir0/die1/dir2/mod.py
import dir1.dir2.mod
form语句:from dir1.dir2.mod import func
容器目录dir0需要添加在模块搜索路径中(除非这是顶层文件的主目录)。
__init__.py包文件:
1.结构:包导入语句的路径内的每个目录内部必须有__init__.py文件,否则包导入失败。所以上面的目录结构应该是这样:
dir0\
dir1\
__init__.py
dir2\
__init__.py
mod.py
2.__init__.py的作用:
2.1 包的初始化,Python首次导入某个目录时,会自动执行该目录下__init__.py文件中的所有程序代码。
包对应的from和import
import 跟包一起使用时,你会经常重复输入完整路径,比如:
import dir1.dir2.mod
dir1.dir2.mod.fun1()
dir1.dir2.mod.fun2()
这时我们有两种方法来变得方便:
1.使用from(因为from是赋值一个新的变量名);
2.使用别名:import dir1.dir2.mod as mod;
from dir1.dir2.mod import func as f
高级模块话题:
1.最小化和最大化from*:
1.1 把下划线放在变量名前面(比如_x),可以防止客户端使用from * 语句导入模块时,把这些变量名复制出去(即_x是指不被复制出去的变量名);
1.2 与_x相反的是__all__,from *只会把__all__列表中的变量名复制出来(__all__ = ['func']);
1.3 python会先寻找模块内的__all__列表,如果没有定义的话,from* 就会复制那些开头没有单下划线的所有变量名。
2.__name__和__mainz__:
2.1 每个模块都有个名为__name__的内置属性,Python会自动设置该属性:
2.1.1 如果文件是以顶层程序文件执行的,那么__name__就会设置成字符串'__main__';
2.1.2 如果文件是被导入的,那么__name__就会设置为模块名。
3.修改模块搜索路径:
3.1.sys.path 的设置方法只在修改的Python会话(即进程)中才会存续,在Python结束后,不会保留下来。
3.2.而PYTHONTHAN和.pth文件路径配置是保存在操作系统中,而不是在执行中的程序,在程序结束后,他们还存在着。
3.3 我们前面说的模块搜索路径(主目录》pythonpath》...)都会在运行时添加到sys.path,然后搜索时就是在sys.pyth中搜索。
3.4 在sys.path中添加:
import sys
sys.appe
sys.path。append(dirname+)
在pythonpath中添加永久路径:
在环境变量中找到Pythonpath(没有就新建),然后把自己想要添加的路径添加进去。
4.相对导入和绝对导入:
4.1.相对路径是相对结构目录(a.b.v),绝对路径既是真实路径(c:\\hk\ad);
4.2.模块包会以绝对导入为默认情况,缺少点号语法时,导入会跳过所在的包,而去sys.path搜索路径上寻找。
4.3 相对导入和绝对导入都是对同一个包内(有__init__)而言的,只有from . 和 from .. import 两种写法是相对导入的,其他的都是绝对导入的。(一个点是当前所在同一个包内,两个点是当前包的上层目录找)
4.4 在python2.6及以前,在一个包内导入相同目录下的模块优先级最高,享受直接导入的主目录下的待遇. 但是这时候我要导入标准库的同名模块,不要导入“同包”的模块怎么办?
python3.0开始包内导入默认实行绝对导入,即在dir0.dir1的py文件里面执行import string不考虑“同包”的string模块。
如果要导入同包的string用明确的 from . import string语法,这样能精确控制了。
2.5-2.7可以通过from future import absolute_import 改变包导入的行为为绝对导入。
5.通过变量名字符串导入模块
有时候我们想要通过运行时产生的字符串去动态加载模块,通常我们有两种做法:
5.1 使用exec语句(或者和它作用相同的eval表达式函数):
module = "string "
exec "import "+module
5.2 使用内置的__import__函数(会更快一点):
module = "string "
string = __import__(module)
6.不要使用递归形式的from import(即不要两个模块相互导入),但import可以,因为import会将模块整个取出,而from只能读取模块中已经赋值的变量名(即已经执行的语句)
# a1.py
x=1
import a2
y=2
# a2.py
from a import y

浙公网安备 33010602011771号