一:什么叫包
理解:包含__init__.py的文件就称为包,包以及包里面的文件,一般情况下,是不会手动执行的,是为了被引用,然后由入口函数统一执行。
test1.py
def add1(): print("add1")
test2.py test3.py test4.py 和test1函数一样,函数名分别为 add2,add3,add4 ,__ini__.py为空
一:在test1里面使用test2.py的add2()函数
from test2 import add2def add1(): print("add1") add2()if __name__ == '__main__': add1()# 结果add1add2
二:在test1里面使用test3.py的add3()函数
from test3 import add3def add1(): print("add1") add3()if __name__ == '__main__': add1()# 报错ModuleNotFoundError: No module named 'test3'
原因是 from test3 import add3 执行的过程是这样的,去test1当前所在的目录下,找test3,找到后进入使用里面的add3()函数,可是根本找不到,因为 test1所在的目录下只有三个文件,tes1.py、test2.py、demo文件夹。
from demo.test3 import add3def add1(): print("add1") add3()if __name__ == '__main__': add1()# 结果add1add3
成功的原因是:先在当前目录下找到了demo,然后在demo目录下找到了test3,最后找到了add3,导包的起始点,是执行导包的这个文件的所在目录下,进行寻找,找不到就报错。
from demo import test3def add1(): print("add1") test3.add3()if __name__ == '__main__': add1()# 结果add1add3
也可以这种形式,同样的先去找demo,通过demo找到test3,最终找到add3()
三:在test3里面使用test4的add4()函数
from test4 import add4 # 但是 test4和add4都是有红波浪线的def add3(): print("add3") add4()if __name__ == '__main__': add3()# 结果add3add4
虽然能成功,但是还是有一些问题,当手动执行test3.py时候,没问题,可以输出,但是当test3也是要被别人当包使用的时候,就会出问题了,不更改test3.py
让test1来使用使用test3里面的add3
from demo import test3def add1(): print("add1") test3.add3()if __name__ == '__main__': add1()# 报错Traceback (most recent call last): File "C:/Users/Administrator/PycharmProjects/untitled/test1.py", line 1, in <module> from demo import test3 File "C:\Users\Administrator\PycharmProjects\untitled\demo\test3.py", line 1, in <module> from test4 import add4ModuleNotFoundError: No module named 'test4'
因为此时的导包入口是test1所在的文件夹,首先通过demo找到了test3,然后执行test3里面的第一行代码,from test4 import add4 这里就出问题了,此时还是从test1所在的文件夹去找test4,所以就出错了。
如果要正常执行的话,可以加. 此时就要修改test3.py
from .test4 import add4def add3(): print("add3") add4()if __name__ == '__main__': add3()
然后执行test1.py
from demo import test3def add1(): print("add1") test3.add3()if __name__ == '__main__': add1()# 结果add1add3add4
成功的原因是:进入test3.py后,执行第一句代码的时候,from .test4 import add4,这个.起了很大的作用,表示当前文件所在的文件夹,先读了.找到了test3.py的所在文件夹,demo,然后从demo里面找test4,肯定能够成功。
四:导包中的__all__
__all__
是一个字符串list,用来定义模块中对于from XXX import *
时要对外导出的符号,即要暴露的借口,但它只对import *
起作用,对from XXX import XXX
不起作用。
例如,给__init__.py里面增加__all__ = [test3.py],然后执行 test1.py
from demo import *def add1(): print("add1") test3.add3()if __name__ == '__main__': add1()# 结果add1add3add4
from demo import *def add1(): print("add1") test4.add4()if __name__ == '__main__': add1()# 结果add1Traceback (most recent call last): File "C:/Users/Administrator/PycharmProjects/untitled/test1.py", line 9, in <module> add1() File "C:/Users/Administrator/PycharmProjects/untitled/test1.py", line 5, in add1 test4.add4()NameError: name 'test4' is not defined
__all__是为了保护包,避免所有的东西暴露,只有在列表里面指定的方法名,变量名才允许被使用
修改__init__.py 为 __all__=["test3","test4"]
继续执行test1.py
from demo import *def add1(): print("add1") test4.add4()if __name__ == '__main__': add1()#结果add1add4
# TODO
来源:https://www.icode9.com/content-4-672401.html联系客服