使用tensorflow有一段时间了,但对python的库的管理基本没有深入学习,在写库的时候经常遇到无法找到引用的尴尬情况。今天抽出一点时间整理一下python的package的编写和引用。使用pycharm IDE。
1.准备工作
首先建立一个package,并在package内创建两个.py文件,外部创建一个.py文件,生成的文件列表如下:
可以看到在建立package的同时系统自动生成了一个__init__.py空文件。在class1.py和class2中各建立一个类。
2.两种import方式的不同
我们清楚在package内的文件可以相互引用,不再赘述。下面我们验证在package外的文件引用package时候两种引用方式的不同
很显然,from引用之后不必再加package层名,但直接import不可以。
3.__init__.py的作用
在路径上,当包被引用时, 当前路径为调用包的路径,这一点在相对路径使用上非常重要。首先,这个文件会在package第一次被使用(注意,不是被引用)的时候首先执行,然后再执行使用的类和函数。在__init__.py和test.py分别写入:
testclass1和testclass2分别在执行时会输出文件名,则输出为:
第二,文件中使用__all__可以定义package的模糊导入对象。在__init__.py写入:
__all__= ["class1", "class2"]
则在test.py中使用可以写成:
*是模糊引用的用法,包含了所有写入__all__中的类,可以通过调整写入的类名决定被模糊引用的类。注意在__init__.py中是无法使用模糊引用的。在__init__.py文件中写下面代码的时候,会将两个类引用到该文件中,同时也会将两个class都添加进入__all__:
import package1.class1
import package1.class2
最后,在__init__.py文件中可以使用
if__name__ == '__main__':
而在包内的其他文件是不能使用的。因此在将包作为独立程序执行时,可以将__init__.py文件视为main.
4.同级包的调用
假设两个包有如下包含情况:
--parent
--package1
--__init__.py
--fun1.py
--fun2.py
--package2
--__init__.py
--fun3.py
如果fun3想调用fun1,可以用os.path.append()将package1的路径添加到系统路径,但这并不是安全的做法。
正确做法在python2中应该有:
from package1 import fun1
python3中除了上述写法,也可以写成:
from parent.package1 import fun1
同一个包内文件相互调用也要带包名。如fun1调用fun2:
from package1 import fun2