对于包于模块的定义:http://www.imooc.com/article/247114这里写的还是不错的。
这个参考链接也很不错,讲的很清楚了为什么相对路径不能直接用脚本的形式执行。
https://www.jianshu.com/p/04bac02ae3f0
以前用Python的标准库import XXX
或者from xxx import xxx
其实具体里面的使用方法于技巧没有系统性的学习过,一直认为能用就ok了
刚到了Python cookbook里面有相对来说比较详细的介绍,我挑一些简单的给自己一些记录。
首先Python有Python的环境变量,我们能够从外部from或者import的都在Python的环境变量里面,下面是我的IPython环境变量。
In [5]: sys.path Out[5]: ['/usr/local/bin', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '', '/usr/local/lib/python3.7/site-packages', '/usr/local/lib/python3.7/site-packages/IPython/extensions', '/Users/shijianzhong/.ipython']
Python有一个很有意思的tip,就是当你运行某个文件,那个文件的文件夹就会加入PythonPATH里面。
shijianzhongdeMacBook-Pro:formats shijianzhong$ python3 jpg.py ['/Users/shijianzhong/study/PythonCookbook/charter_10/t_10_1_2/graphics/formats',
'/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
'/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
'/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/usr/local/lib/python3.7/site-packages'] shijianzhongdeMacBook-Pro:formats shijianzhong$ pwd /Users/shijianzhong/study/PythonCookbook/charter_10/t_10_1_2/graphics/formats
这是我的一个比较里面的文件,他还是把自己的文件夹(这是一个顶层的文件夹)当做包,放入了Python环境变量中。
这个文件夹下面所有的包以及模块都能够被导入。
我用Pycharm新建了一个工作文件,Pycharm默认的设置会把这个目录添加到Python工作环境中,我的是
/Users/shijianzhong/study/PythonCookbook/charter_10/t_10_1_2
下面的文件内容为:
└── graphics ├── __init__.py ├── __pycache__ │ └── __init__.cpython-37.pyc ├── formats │ ├── __init__.py │ ├── jpg.py │ └── png.py └── primitive ├── __init__.py ├── __pycache__ │ └── __init__.cpython-37.pyc ├── fill.py ├── line.py └── text.py
首先我准备通过这个事例来简单的说明一下。
In [1]: import sys In [2]: sys.path Out[2]: ['/usr/local/bin', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '', '/usr/local/lib/python3.7/site-packages', '/usr/local/lib/python3.7/site-packages/IPython/extensions', '/Users/shijianzhong/.ipython']
很明显,ipython的python环境里面没有我刚才新建的工作路径目录。
In [7]: cd ~ /Users/shijianzhong In [8]: from graphics import primitive --------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) <ipython-input-8-e5e5ddc40003> in <module> ----> 1 from graphics import primitive ModuleNotFoundError: No module named 'graphics'
很明显,因为没有这个环境的路径,导包失败。那就添加路径:
In [9]: sys.path.append('/Users/shijianzhong/study/PythonCookbook/charter_10/t_10_1_2') In [10]: from graphics import primitive In [11]: primitive Out[11]: <module 'graphics.primitive' from '/Users/shijianzhong/study/PythonCookbook/charter_10/t_10_1_2/graphics/primitive/__init__.py'>
添加了环境变量的路径,这个工作目录下面的所有的模块于包都能只能导入。
为了测试是否能导入模块,我新建了一个文件在顶层目录下(t.py):
. ├── __pycache__ │ └── t.cpython-37.pyc ├── graphics │ ├── __init__.py │ ├── __pycache__ │ │ └── __init__.cpython-37.pyc │ ├── formats │ │ ├── __init__.py │ │ ├── __pycache__ │ │ │ └── __init__.cpython-37.pyc │ │ ├── jpg.py │ │ └── png.py │ └── primitive │ ├── __init__.py │ ├── __pycache__ │ │ └── __init__.cpython-37.pyc │ ├── fill.py │ ├── line.py │ └── text.py └── t.py
In [4]: import t I am t
导入模块后,直接输出里面的内容,说明模块已经运行了。
从这里可以说明,一般情况下,我的主运行文件应该建立在顶层,这样的话,在运行这个文件的时候,能够正确的把这个脚本的工作环境添加到Python环境中。
避免后期的一些导包错误(可能是绝对路径的导包错误)。
在这样的情况下,我可以通过顶层包,非常轻松的导入模块
有了这个,后面能够更好的理解绝对路径导入模块。
在我们对一个包的文件夹进行导入的时候,其实导入的是__init__文件,每次都会运行里面的文件内容。
from graphics.formats import jpg
I am graphics package I am formats package
当我导入graphics包下面的formats包下面的jpg模块,这两个包里面的__init__全部执行了。
这个__init__文件可以方便的让你通过包,管理包里面的模块,只需要通过相对路径from . import xxx
同级别的木块就会导入这个包内,
后期导入这个包可以通过包名字.xxx调用这个模块。
包于模块的使用还是非常丰富的,Pythoncookbook书中介绍比较详细,自己也前面简单的看了一些,难的等以后用到再补充。