通常来说一个模块对应一个python源码文件,可通过sys.modules
查看当前python解释器可导入的模块。
In [16]: sys.modules
{...
'sys': <module 'sys' (built-in)>,
'sysconfig': <module 'sysconfig' from '/usr/lib/python2.7/sysconfig.pyc'>,
'tempfile': <module 'tempfile' from '/usr/lib/python2.7/tempfile.pyc'>,
'textwrap': <module 'textwrap' from '/usr/lib/python2.7/textwrap.pyc'>,
'thread': <module 'thread' (built-in)>,
'threading': <module 'threading' from '/usr/lib/python2.7/threading.pyc'>,
'time': <module 'time' (built-in)>,
'token': <module 'token' from '/usr/lib/python2.7/token.pyc'>,
'tokenize': <module 'tokenize' from '/usr/lib/python2.7/tokenize.pyc'>,
...}
import
from...import
import...as
from...import...as
__import__() # import其实调用的是该方法
reload() # 模块源码变动后可用此方法重新导入模块, 参数不能是字符串,必须是不包含引号的模块名。
注:不推荐用"import *",因为这样会导入不需要的对象,还可能与当前模块中成员命名发生冲突。 (可以试试python解释器里导入from sys import *
, 然后exit
)
- 当前目录
- PYTHONPATH指定目录
- python标准库
- 第三方模块(site-packages下)
可通过sys.path
查看python搜索路径,sys.path
是一个列表,可以通过append
添加自定义搜索路径,也可以删除某路径(参照列表操作)。
sys.path.append("a path")
python模块第一次被导入的时候会生成py[co]字节码文件。pyc文件是平台无关的,运行的时候再由python解释器生成机器码。由于python程序执行的时候读的是pyc字节码文件,所以发布程序的时候如果不想被人看到代码可以只发布字节码文件。(注:pyo是优化后的字节码文件,可用python -O -m modulename
生成)
使用import 导入的时候实际导入的是目标模块名字空间中的成员(没带下滑线的),所以如果目标模块导入了其它模块中的成员,这些成员也会被导入到当前模块中。解决该问题可用__all__
,显式指定可用导出的成员。如果定义了__all__
,想导入不在__all__
中的成员,或者想导入私有成员,只能显示导入。
all = ["hello"]
注:还有一些更深入的模块导入方面的问题,参照《python学习笔记》
__name__
:模块名称__file__
:模块对应文件(为什么sys没有该属性TODO)__doc__
:模块文档字符串__dict__
:模块名字空间:(和vars(modulename)返回一样)
包含__init__.py
的目录,就是python包(我是这么认为的)。
在导入包或者包里面的模块的时候首先会执行__init__.py
,它可用于包环境初始化或存放包的文档字符串等信息。通常__init__.py
文件就是一个空文件。
一个包里可包含多个模块,也可以包含子包。
包的引入可以解决如下问题:(摘自《Python核心编程》第二版321页)
- 为平坦的名称空间加入有层次的组织结构。
- 允许程序员把有联系的模块组合到一起。
- 允许分发者使用目录结构而不是一大堆混乱的文件。
- 帮助解决有冲突的模块名称。
**注:**在python2中包的模块中导入其它模块默认是先搜索本包中的模块(相对导入),然后再搜索包的搜索路径中的模块(绝对导入)。但python3中默认搜索的是搜索路径中的模块(绝对导入)。python3中如想用相对导入,需用点号from .module import func
。显示的使用相对导入可避免因模块名字冲突造成的导入错误。
test
__init__.py
main.py
string.py
如上,如果在main中想导入标准库的stringimport string
,可根据导入规则,先搜到的是本目录中的string模块,于是会发生导入错误。python3就不会出这种问题,因为是绝对导入。如果想在python3中导入本目录的string,需用import .string
安装工具
虚拟环境
# pip settings for virtualenv
# Installation: pip install virtualenv
# Require an activated virtualenv
export PIP_REQUIRE_VIRTUALENV=true
# Auto switch to virtualenv
export PIP_RESPECT_VIRTUALENV=true
# virtualenvwrapper setting
# Installation: pip install virtualenvwrapper
# USAGE:
# workon list env
# workon <envname> start/switch env
# mkvirtualenv <envname> mk env
# rmvitualenv <envname> rm env
# deactivate exitenv
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh