模块、包的定义

模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:模块的本质是为了实现一个功能),本质就是.py结尾的python文件 (文件名:test.py,对应的模块名:test)

包:用来打包多个模块(.py文件),本质就是一个目录(必须有__init__.py文件),如果想要导入一个包就是解释(执行)这个包下的__init__.py文件。

导入方法

导入模块:

import module_name   (导入所有)

指定导入:from module_name import * (导入所有);   

导入指定方法:from module_name import abc  

导入模块中的多个方法: from module_name import abc123,abc456

导入模块中的方法:import module_name.abc

导入模块中的变量:import module_name.name

导入多个模块:import module1_name, module2_name

导入后别名: from module1_name import logger as abc123 使用该方式导入的话,需要通过别名来调用,如abc123()

不建议通过from方式来调用函数,假如当前.py文件中有一个叫abc的方法函数,然后我们如果通过使用from module_name import *来调用的话那么,且调用过来的module_name模块中也有个叫abc的方法函数,那么在当前.py文件中来调用abc()函数时就会导致冲突。

如果使用import module_name就不同了,需要使用module_name.abc的方式才可以调用module_name模块的方法函数,即使当前.py文件中有同名的也不会冲突。

import本质

python模板的本质 python中模块的本质_bc

我们在test.py中import time这个模块,其本质意义就是将time模块中的代码解释一遍(运行一遍)然后赋值给一个变量,这个变量就是time

from time import strftime相当于将time模块中的strftime方法给解释了一遍然后放入test.py文件中。

通过from time import strftime方式相当于打开了time模块这个文件然后将strftime给导入到当前所在的test.py文件中,所以在调用的时候直接strftime就可以了

通过直接import time方式后,相当于将time中的代码赋值给了time,所以在当前test.py中调用的时候需要time.strftime才可以调用。

python模板的本质 python中模块的本质_bc_02


需要time.xxx才可以调用

python模板的本质 python中模块的本质_bc_03


直接调用即可

导入模块的本质:就是把python文件解释一遍。

导入包的本质:就是执行包下的init.py文件。

动态路径

1、方法(一)

python模板的本质 python中模块的本质_python模板的本质_04


在新建的包中的init.py写一个print代码

python模板的本质 python中模块的本质_绝对路径_05


test.py与q1这个包在同级目录,所以调用q1是没问题的,可以看到图中下面的执行结果。

python模板的本质 python中模块的本质_绝对路径_06

python模板的本质 python中模块的本质_python模板的本质_07


调用不同目录的模块

python模板的本质 python中模块的本质_bc_08


可以看到无法直接调用不同目录的模块

python模板的本质 python中模块的本质_绝对路径_09


默认先从当前目录去找q1这个目录找,然后在去sys.path(图中圈起来的路径)这些个路径去找,找不到就会报错。

打印的sys.path路径可以看到是一个列表,在列表中没有q2这个目录的路径,所以会找不到for_test.py导致报错。通过os模块来查看当前的绝对路径

python模板的本质 python中模块的本质_bc_10


python模板的本质 python中模块的本质_python模板的本质_11


显示绝对路径,可以看到packet.py

print (os.path.dirname(os.path.abspath(__file__)))

通过os.path.dirname获取(os.path.abspath(file)的目录

python模板的本质 python中模块的本质_绝对路径_12


目前只获取到了q1这个目录,在这个目录下找不到for_test模块

print (os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

多一个os.path.dirname来获取更上一级的目录

python模板的本质 python中模块的本质_bc_13

python模板的本质 python中模块的本质_python模板的本质_14


新建一个与q1同级的mian模块

python模板的本质 python中模块的本质_bc_15


之前讲过sys.path是列表形式,所以需要将动态新生成的路径加入到sys.path中

python模板的本质 python中模块的本质_python模板的本质_16


通过Import main然后在调用,可以看到执行结果#### 2.方法(二)

python模板的本质 python中模块的本质_python_17


通过同样的方式去调用for_test就出现问题了,这是因为for_test在q2这个目录中,不能直接使用import来导入

python模板的本质 python中模块的本质_python_18


需要通过from q2这个目录然后在import,也就是从q2这个包中导入模块。

3.方法(三)

python模板的本质 python中模块的本质_python_19


之前了解过import包就相当于import这个包下的init模块

python模板的本质 python中模块的本质_python_20


执行没有问题

python模板的本质 python中模块的本质_bc_21


在这个init模块下我们使用from . import for_test,也就是说在packet.py中去import q2就相当于调用了init.py,然后init又调用了for_test.py,所以上图中可以通过q2.for_test.login()来调用。

from 后面的那个符号 点 表示从init的当前目录(q2这个包目录)去import

导入优化

python模板的本质 python中模块的本质_python_22


定义aa模块

python模板的本质 python中模块的本质_python模板的本质_23


在bb.py中import aa,然后在bb.py中定义函数并调用aa模块中的方法(函数),不过这样调用的话,在bb.py中的每一个函数都需要先去找aa模块,然后再去找test()这个方法,被调用一次就需要找一次,如果调用次数多的话,就需要大量的重复性工作,这样运行程序相对会比较慢。

python模板的本质 python中模块的本质_python模板的本质_24


使用from方法来导入,相当于把这个test()导入到bb.py文件中了,这样在调用test()这个函数的时候,直接就是从本程序中直接调用,相比上一种方式运行速度会快。

转载于:https://blog.51cto.com/daimalaobing/2046801