Python 快速入门笔记(9):模块和包
本系列随笔是本人的学习笔记,初学阶段难免会有理解不当之处,错误之处恳请指正。转载请注明出处:https://www.cnblogs.com/itwhite/p/12302882.html。
目录
一、模块
- 指定导入的符号列表
- 模块查找的路径
- 在模块中插入测试代码
二、包
一、模块
所有 python 程序(.py文件)都可以作为一个模块,例如:
# foo.py
class Foo (object):
def __init__(self):
print("Created a Foo object")
def foo():
print("foo() is called")
FOO = 123
# 测试使用 foo 模块
>>> from foo import * # 导入 foo 模块,即 foo.py 中的内容(注:不会导入以下划线开头的符号)
>>> f = Foo() # 创建 Foo 的实例
Created a Foo object
>>> foo() # 调用 foo.py 中的 foo() 函数
foo() is called
>>> FOO # 直接使用 foo.py 中的全局变量 FOO
123
1. 指定导入的符号列表
从前面可以看到,通过 import * 语句会导入所有(不是以下划线开头的)符号,通过 __all__ 可以限定这种方式导入的符号,例如:
# foo.py
__all__ = ['Foo', 'foo'] # 只导出类名 Foo 和函数 foo() 的符号
class Foo (object):
def __init__(self):
print("Created a Foo object")
def foo():
print("foo() is called")
FOO = 123 # FOO 未被导出
# 测试使用 foo 模块
>>> from foo import * # 导入 foo 模块,即 foo.py 中的内容(注:不会导入以下划线开头的符号)
>>> f = Foo() # 创建 Foo 的实例
Created a Foo object
>>> foo() # 调用 foo.py 中的 foo() 函数
foo() is called
>>> FOO # FOO 未被导出
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'FOO' is not defined
>>> foo.FOO # 只能以模块名限定的形式访问
123
2. 模块查找的路径
通过 sys.path 可以查看和配置 python 解释器查找模块的路径列表:
>>> import sys
>>> sys.path # 搜索路径列表
['', 'C:\\Windows\\system32\\python27.zip', 'C:\\Python27\\DLLs',
'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\\Python27\\lib\\lib-tk',
'C:\\Python27', 'C:\\Python27\\lib\\site-packages']
>>> sys.path.append('C:\\tmp\\python') # 追加一条搜索路径
另一种更常见的办法是通过 PYTHONPATH 环境变量去配置模块查找路径,例如:
export PYTHONPATH=$PYTHONPATH:~/python
3. 在模块中插入测试代码
有时候我们需要为模块写一些测试代码,直接写入模块文件中方便修改,但是不希望 import 时执行,可以通过当前模块名(__name__)来判断当前文件是作为主文件还是模块文件使用的,例如:
# add.py
def add(a, b):
return a + b
# 测试代码,当且仅当直接执行 add.py 才会执行(通过 import 导入 add.py 文件不会执行 if 中的内容)
if __name__ == '__main__':
print "Testing add()"
assert add(1, 2) == 3
print "Passed"
二、包
Python 中的“包”不需要在代码中声明,而是以文件夹的形式存在,只需要在某个文件夹中创建一个 init.py 文件(可以为空文件)即可,然后放入其中的模块文件就属于这个包,例如:
# 目录结构
.
+-- foo # 目录名
| +-- __init__.py # 空文件,python 解释器看到它会认为当前目录是一个包
| +-- bar.py # 模块文件
+-- test.py # 测试文件
# bar.py 文件内容
def qux():
print("qux() is called")
# test.py 文件内容
from foo.bar import qux
qux() # qux() is called
另外,“包”本身也可以作为一个模块,模块内容写入相应的 __init__.py 文件中即可,例如修改上面的文件内容:
# __init__.py 文件内容
def quz():
print("quz() is called")
# test.py 文件内容修改如下
from foo import quz
quz() # quz() is called