一. 路径问题
使用 import
语句时,搜索模块的路径顺序如下:
- 搜索程序运行时的路径(当前路径);
-
sys.path
提供的路径; - 搜索内置模块;
因此,为了让程序找到自定义的模块,我们可以使用安装的方法,将模块放到 sys.path
的任意一个路径下。另外,也可以扩展sys.path的路径:
>> import sys
>> sys.path.append('path of module')
二. 模块的导入和执行过程
2.1 模块的加载
在模块导入时,模块所有语句会执行;如果一个模块已经被导入,再次导入时不会重新执行模块内的语句。如果需要在运行时重新加载某个模块,可以使用 imp.reload
方法:
>> import mymod
>> import imp
>> imp.reload(mymod) # 在运行时重新加载mymod模块
2.2 模块被导入和执行的过程
- 搜索相关路径找到模块的
.py
文件; - 判断是否有此模块对应的
.pyc
文件; - 如果
.pyc
文件比.py
文件新,则直接加载.pyc
文件;否则用模块的.py
文件生成.pyc
并加载执行。
完整的过程即:.py
----> 编译 ----> .pyc
----> 解释执行 ----> Python。
三. 模块的属性
3.1 模块的隐藏属性
模块中以 _
开头的属性,在 from xxx import *
导入时将不被导入,通常这些属性称为隐藏属性。
定义一个模块 mymod.py
如下:
def my_func1():
print('my func1')
def _my_func2():
print('my _func2')
def __my_func3():
print('my __func3')
name1 = 'Alex'
_name2 = 'Bob'
__name3 = 'Chandler'
在该模块所在路径下启动一个 Python Shell:
3.2 模块的 __all__
属性
模块的 __all__
属性绑定的是一个列表,用来存放可导出属性的字符串列表。限定当用 from xxx import *
语句导入时,只导入 __all__
列表内的属性。
将模块 mymod.py
的内容更新为:
__all__ = ['my_func1', 'my_func2', 'name1', 'name2']
def my_func1():
print('my func1')
def my_func2():
print('my func2')
def my_func3():
print('my func3')
name1 = 'Alex'
name2 = 'Bob'
name3 = 'Chandler'
运行结果:
3.3 模块的其它属性
__doc__
属性:绑定模块的文档字符串,模块内第一个没有赋值给任何变量的字符串为文档字符串。
__file__
属性:绑定模块对应的文件路径。
__name__
属性:记录模块的名称,常用来判断是否为主模块:当此模块为主模块(也就是第一个运行的模块)运行时,__name__
绑定 __main__
;当此模块不是主模块时,__name__
绑定模块名,即文件名去掉 .py
后缀。