强基初中数学&学Python——第三十四课 包

    我们现在有了2个数学模块,想把它们放到mymath目录(文件夹)里,就成了一个“包”,随时可以引用:

。在工作目录建一个文本文件work.py,用idle打开:

。运行这个文件:

导入模块测试:

,可以在模块前增加“mymath.”就行了。如果工作目录不同,这个方法需要把要用的模块文件夹拷贝到工作目录下。这很不方便,也容易产生版本混乱。有没有只放在一个地方,不管是什么工作目录都可以使用的方法呢?

    有,就是使用内置sys模块中的path对象的append方法把“mymath”目录所在的目录绝对路径加进去。先在d盘建目录mypython,然后把mymath剪切过去:

。重启work.py文件:

。测试引入模块:

,系统没找到模块。怎么办呢?

    把包所在的目录加到sys.path中:

,

成功了!

    如果想把mymath模块细分到school类别中,对目录结构进行修改:

导入测试:

绝对路径导入模块总结:把模块的全路径分为两部分,前一部分用sys.path.append加入sys.path中,另一部分作为被导入模块的前缀。

    用import导入单个模块测试:

通过import语句导入模块后,要使用不可以直接用模块名称,要连全部前缀都要直接写在代码中。这很不方便,有没有不用写前缀的方法呢?

    有,就用“from 模块所在的目录 import 模块名称”句型:

在这一句语句中,可以同时导入多个模块:

如果想把目录中所有的模块都导入,能否使用通配符呢?测试一下:

可见,程序根本就没导入模块,这是为什么呢?

    原来,包中可以有一个特殊的文件__init__.py,mymath中加入这个文件:

,然后再试试:

还是不行。

    原来要使用这句型的通配符,就需要在__init__.py文件中的__all__列表明确写入通配情况下导入的模块:

现在测试一下:

可见,"from 文件夹 import * "只导入__init__.py中__all__列表中的模块,如果__all__列表为空或没有,或者没有__init__.py文件,这个语句貌似啥都不做。

    模块引用当前目录和子目录中的模块,上面都写明了;如果是子目录中的模块要引用父目录中的模块,那应该怎样呢?在各级目录中添加一个测试模块如下:

。尝试运行最后的模块:

一个点号(.)   表示当前目录,最为main模块使用时出错;注释掉:

然后执行:

两点表示父一层目录,主模块中也不允许;注释掉后:

执行:

三点表示父二层目录,也不行。恢复被注释掉的代码行。

    运行mypython里的测试模块打开新的idle界面:

当执行导入school.mymath.test模块时,这个模块又导入了schooltest模块,执行schooltest模块的“from mymath import zhengshiyunsuan”出错。尝试直接导入看看:

情况一样。采用点号改写schooltest.py:

直接运行出错,在直接导入看看:

成功了。再测试导入school.mymath.test模块:

mypython目录是模块开始,本身不是一个包,所以出现了包穿透的错误。启动新idle,测试:

mypythontest.py中未使用相对目录,所以出错,修正:

再次测试:

成功了!

    旁支目录有会怎样,建一个旁支目录中的模块:

测试一下:

父一层旁支在最前加两点(..),父二层加三点(...),如此类推。

 

    总结:(1)sys.path.append(“包的存放目录”)中的“包的存放目录”不能是包的根目录,也就是说这个目录下的子目录才是各个包的根目录。这样相对目录不能指向“包的存放目录”;(2)这些存放了模块的目录(文件夹)就是包,相对位置表示方法:一小点(.)表示当前包,二小点(..)表示父一层包,三小点(...)表示父二层包,如此类推;(3)主模块(运行时__name__ = "__main__")的import不可以使用小点相对位置,一定要用sys.path.append(“包的存放目录”),import时最前无小点(.);(4)非主模块(在主模块或其他模块通过import导入的模块)一定要使用小点(.)相对位置;(5)使用"from 包 import *"语句时,只有在这个包中定义了__init__.py文件,并且文件中定义了__all__列表,这个语句就导入__all__列表中的模块,否则貌似啥都不做;(6)使用"from 模块 import *"语句时,就不受__init__.py文件的限制,把模块中的公共命名全导入当前命名空间中。

 

练习题:把本课的测试自行测试一次,如果有疑问也可以自行设计测试。

 

    学Python第二阶段到此结束。