python包
包的每一层下面都有一个名为__init__.py的模块,该模块可以为空,用于标识python包
以下为调用方式 从test包下调用a文件中调用a方法
from test.a import a
目录结构如下

test目录下__init__.py内容为空
test目录下a.py内容
def a(): print('a')
test目录同级目录中test.py内容
from test.a import a a()
执行 python.exe test.py 结果如下:

结果没有问题,程序运行也正常。
如果在test文件下有10个xxx.py文件,还要写10个 from test import a,xxx,或者写10个 from test import a 这样的语句,这太繁琐。
或许使用 from test import * 这样的语句也不错
test目录下__init__.py内容为空
test目录下a.py内容
def a():
print('a')
dir目录下test.py内容
from test import *
a.a()
执行 python.exe test.py 结果如下:

错误提示:a 这个名字没有定义
为什么行不通呢?
python不建议使用 from test import * 这种方式编程,但在开发测试中,这种方式极为方便。
但,python 已经解决了这个问题,解决的途径就是__init__.py 这个标识文件
说明,python命名空间
在python中有可以使用__all__来显式指定 import * 中 导入的成员,未被指定的不能被导入,这样可以保护模块安全
test目录下__init__.py内容:
__all__ = ['a']
test目录下a.py内容
def a():
print('a')
dir目录下test.py内容
from test import * a.a()
执行 python.exe test.py 结果如下:

定义 all 需要注意的地方
如上所述,__all__ 应该是 list 类型的
不应该动态生成 __all__,比如使用列表解析式。__all__ 的作用就是定义公开接口,如果不以字面量的形式显式写出来,就失去意义了。
即使有了 __all__ 也不应该在非临时代码中使用 from xxx import * 语法,或者用元编程手段模拟 Ruby 的自动 import。Python 不像 Ruby,没有 Module 这种成员,模块就是命名空间隔离的执行者。如果打破了这一层,而且引入诸多动态因素,生产环境跑的代码就充满了不确定性,调试也会非常困难。
按照 PEP8 建议的风格,__all__ 应该写在所有 import 语句下面,和函数、常量等模块成员定义的上面。
如果一个模块需要暴露的接口改动频繁,__all__ 可以这样定义:
__all__ = [ "a", "b", "c", ]
参考网址:
https://blog.csdn.net/qq_32166627/article/details/59481503
https://blog.csdn.net/hang916/article/details/79474821
浙公网安备 33010602011771号