python包
python包
一、包的定义
需要强调的是:
-
在python3中,即使包下没有__init__.py文件,import 包仍然不会报错,而在python2中,包下一定要有该文件,否则import 包报错
- 创建包的目的不是为了运行,而是被导入使用,记住,包只是模块的一种形式而已,包的本质就是模块的一种形式
二、包的使用
sendmsg.py文件里的内容如下:
def send_msg(): print('——————sendmsg方法被调用了——————')
recvmsg.py文件里的内容如下:
def recv_msg(): print('——————recvmsg方法被调用了——————')
可以使用以下几种方法来导入模块,使用模块里的方法:
1、直接使用包名.模块名导入指定的模块
import newmsg.sendmsg newmsg.sendmsg.send_msg()
2、使用from xxx improt xxx 方式导入指定模块
from newsmsg import sendmsg,recvmsg sendmsg.send_msg() #此时不需要写包名,直接写模块名 recvmsg.recv_msg()
3、使用__init__.py ,导入包里的指定模块。
在__init__.py文件里编写代码:
from . import sendmsg #导入指定的模块 .代表的是当前文件夹
test.py文件里的代码:
import newmsg #导入时,只需要输入包名即可。在包名的__init__.py文件里,导入了指定模块 newmsg.sendmsg.send_msg() #可以直接调用对应的方法 newmsg.recvmsg.recv_msg() #报错,不可以使用recvmsg模块,因为__init__.py文件没有导入这个模块
包属于模块的一种,因而包以及包内的模块均是用来被导入使用的,而绝非被直接执行,首次导入包(如import newmsg)同样会做三件事:
1、执行包下的__init__.py文件2、产生一个新的名称空间用于存放__init__.py执行过程中产生的名字
3、在当前执行文件所在的名称空间中得到一个名字newmsg,该名字指向__init__.py的名称空间,例如newmsg.xxx和newmsg.yyy中的xxx和yyy都是来自于newmsg下的__init__.py,也就是说导入包时并不会导入包下所有的子模块与子包4、newmsg.sendmsg.send_msg() 要求newmsg下有名字sendmsg,进而newmsg.sendmsg下有名字send_msg。newmsg.sendmsg下已经有名字send_msg了,但newmsg下没有名字sendmsg,因此需要在包中的__init__.py文件中导入模块sendmsg(from . import sendmsg)
5、关于包相关的导入语句也分为import和from ... import ...两种,但是无论哪种,无论在什么位置,在导入时都必须遵循一个原则:凡是在导入时带点的,点的左边都必须是一个包,否则非法。可以带有一连串的点,如import 顶级包.子包.子模块,但都必须遵循这个原则。但对于导入后,在使用时就没有这种限制了,点的左边可以是包,模块,函数,类(它们都可以用点的方式调用自己的属性)。
6、包A和包B下有同名模块也不会冲突,如A.a与B.a来自两个命名空间。7、import导入文件时,产生名称空间中的名字来源于文件,import 包,产生的名称空间的名字同样来源于文件,即包下的__init__.py,导入包本质就是在导入该文件
3.1绝对导入与相对导入
针对包内的模块之间互相导入,导入的方式有两种:
a、绝对导入:以顶级包为起始(因为包已经被使用者放入sys.path路径中)
# newmsg下的__init__.py from newmsg import recvmsg
b、相对导入:. 表示当前文件所在目录,.. 代表当前目录的上一级目录,以此类推
# newmsg下的__init__.py
from . import recvmsg
同理,针对package1.package2.moudle.fuction(),则需要
# 操作package1下的__init__.py,保证package1.package2 from . import package2 或 from package1 import package2 #操作package2下的__init__.py,保证package1.package2.moudle from . import moudle 或 from package1.package2 import moudle
针对包内部模块之间的相互导入推荐使用相对导入,需要特别强调:
- 相对导入只能在包内部使用,用相对导导入不同目录下的模块是非法的(包内模块之间的导入,推荐使用相对导入)
-
无论是import还是from-import,但凡是在导入时带点的,点的左边必须是包,否则语法错误
- 相对导入不能跨出包,所以相对导入仅限于包内模板彼此之间使用
-
绝对导入是没有任何限制的,所以绝对导入是一种通用的导入方式
3.2__init__.py其他用途
print('hello,wold!')
别的模块在引入这个包的时候,会自动调用这段代码:
from newmsg import sendmsg,recvmsg sendmsg.send_msg()
3.3__all__变量的使用
在__init__.py文件中,定义一个__all__变量,它控制着from 包名 import * 时导入的模块。
__init__.py文件:
__all__=['sendmsg']
test.py文件
from newmsg import * sendmsg.send_msg() recvmsg.recv_msg() #报错,recvmsg模块没被导入