很多初学者都会使用PyCharm作为自己学习Python的IDE。 每当创建一个Python Package(Python包)的时候, Pycharm就会创建一个文件夹,并且在文件夹内自动生成一个__init__.py文件。但你是否真正了解__init__.py文件的作用呢? 让我们今天就来扒一扒。
Python代码情况如下:
- test_package是一个简单的Python包, 包内新建了两个Python文件test_class1.py和test_class_2.py,test_class1.py内定义了类TestClass1和TestClass2, test_class_2.py中定义了类TestClass3
- test.py是外部调用test_package的Python文件
1. __init__.py是Python包的标志
什么意思呢? 也就是说IDE如果发现目标文件夹的根目录下存在__init__.py,那就会认为该文件夹是Python包,否则那这个文件夹就是一个普通的文件夹。
那文件夹和Python包在Python开发中又有什么区别? 区别在于后者可以在工程中使用import关键字在Python包外部导入这个包,而文件夹不支持这样的操作。
2. __init__.py支持集中导入整个package下所有类和方法等
不妨在__init__.py中添加如下代码:
from test_class1 import * from test_class3 import *
然后在test.py中导入test_package:
from test_package import * if __name__ == "__main__": TestClass1().say1() TestClass2().say2() TestClass3().say3() 输出: TestClass1 TestClass2 TestClass3
当然__init__.py不光支持集中导入Python包内部的类,也支持集中导入系统包,其它外部package,以及常量等,有兴趣的同学可以深入探索。
3. 在__init__.py中通过定义__all__来控制外部调用者能够调用的范围
不妨在__init__.py中添加如下代码:
from test_class1 import * from test_class3 import * __all__ = ['TestClass1', 'TestClass2']
然后在test.py中导入test_package:
from test_package import *
if __name__ == "__main__":
TestClass1().say1()
TestClass2().say2()
TestClass3().say3()
输出:
TestClass1 TestClass2 TestClass3().say3() NameError: name 'TestClass3' is not defined
TestClass3因为没有包含在__all__中,所以在test.py中无法调用。
4. __init__.py可以作为一个普通的Python文件来进行编程,但并不推荐将过多的代码逻辑放进__init__.py, 轻量级的__init__.py始终是开发者应该追求的目标。
不妨在__init__.py中添加如下代码:
from test_class1 import *
from test_class3 import *
print("Just for test")
然后在test.py中导入test_package:
from test_package import *
if __name__ == "__main__":
TestClass1().say1()
TestClass2().say2()
TestClass3().say3()
输出:
Just for test TestClass1 TestClass2 TestClass3
说明在执行from test_package import *时, 不但导入了我们需要calss, 也执行了print("Just for test")语句。
知识点
1. 导入Python包和导入python文件
import Python包内的类: from test_package import TestClass1
import Python文件内的类: from test_package.test_class3 import TestClass3
test_package是Python包名,而test_package.test_class3标识的是Python包命名空间内的python文件
2. 导入Python包内的所有类,方法,常量等等
import包内的所有类,方法,常量等等: from test_package import *
import包内的特定类: from test_package import TestClass1