在编写大点儿的Python程序时,势必会使用Python程序的层次结构,此时我们就不可避免的会导入包模块,会考虑Python解释器是怎么找到自己的模块的。事实上,模块搜索路径有下面四种方式:
最后,这四个组件组合起来就成了sys.path。搜索路径的第一个和第三个元素是自动定义的,但是Python会从头到尾搜索这些组件的组合结果,第二和第四个元素,就可以用于扩展,从而包含你自己的源代码路径。其中,sys.path.append("/root/python")是一次性的,仅对当前Python运行环境有效;PYTHONPATH则是最常用的,下面就对PYTHONPATH进行细说;.pth文件不是很常用。
sys.path.append("/root/python")是一次性的,仅对当前Python运行环境有效,或仅对当前Python解释器有效,而/root/python目录包含需要的包或模块。
import sys sys.path.append("/root/python")
.pth文件时最简单的方式,但是却不常用,可能会产生大量的.pth文件。Python 在遍历已有的库文件目录(sys.path中指定)过程中,如果见到一个 .pth 文件,就会将该文件中所记录的路径加入到 sys.path 设置中,这样 .pth 文件说指明的库也就可以被 Python 运行环境找到。因此,.pth文件需要放在Python的site-package目录下。
如添加一行包或模块所在的路径在test.pth中:
/root/python
PYTHONPATH是设置在环境变量中的。一般情况下,会先把/usr/local/lib/pythonx.x/site-packages添加到PYTHONPATH中,再把需要的模块的路径(如/root/python)添加到PYTHONPATH中,如:
PYTHONPATH=/usr/local/lib/python3.4/site-packages export PYTHONPATH=$PYTHONPATH:/root/python
下面用一个例子就行说明,/root/python中包的结构如下:
edu/ __init__.py model1.py model2.py test/ __init__.py test.py
__init__.py文件控制包的导入行为,可以为空,也可以添加代码,但是不可以删除。它会在导入包模块时,最先执行。
edu包中的文件如下
__init__.py:
#使用相对路径 from .model1 import add, sub #使用绝对路径 from edu.model2 import multiply, divide print("edu package")
def add(a, b): return a + b def sub(a, b): return a - b
def multiply(a, b): return a * b def divide(a, b): if b != 0: return a / b else: raise Exception("b = 0")
from edu.model1 import add, sub #使用“.”代表上一级目录 #from ..model1 import add, sub print("test package")
test.py:
from edu import model1 as md import edu import edu.test as test import numpy as np if __name__ == "__main__": #不使用__init__.py print(md.sub(3,0)) #因为import edu.test as test #并且test包下的__init__.py文件中预先导入了add、sub方法 print(test.add(1, 2)) #因为import edu #并且edu包下的__init__.py预先导入了模块model1和model2中的add、sub、multiply、divide方法 print(edu.multiply(2, 2)) print(edu.add(2, 4)) print(np.array([1,2]))