18. 模块

在Python中,一个.py文件就称之为一个模块(Module)。

如果不同的人编写的模块名相同怎么办?

为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)

举个例子,一个abc.py的文件就是一个名字叫abc的模块,一个xyz.py的文件就是一个名字叫xyz的模块。
现在,假设我们的abc和xyz这两个模块名字与其他模块冲突了,于是我们可以通过包来组织模块,避免冲突。方法是选择一个顶层包名,比如mycompany,按照如下目录存放:

mycompany
  __init__.py
  abc.py
  xyz.py

引入了包以后,只要顶层的包名不与别人冲突,那所有模块都不会与别人冲突。现在,abc.py模块的名字就变成了mycompany.abc,类似的,xyz.py的模块名变成了mycompany.xyz。

注意: 每一个包目录下面都会有一个__init__.py的文件,这个文件是必须存在的,否则,Python就把这个目录当成普通目录,而不是一个包。__init__.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany

使用模块

以内建的sys模块为例,编写一个hello的模块:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
' a test module '
__author__ = 'Michael Liao'
import sys
def test():
	args = sys.argv
	if len(args)==1:
		print('Hello, world!')
	elif len(args)==2:
		print('Hello, %s!' % args[1])
	else:
		print('Too many arguments!')
if __name__=='__main__':
	test()

第1行和第2行是标准注释,第1行注释可以让这个hello.py文件直接在Unix/Linux/Mac上运行,第2行注释表示.py文件本身使用标准UTF-8编码;

第4行是一个字符串,表示模块的文档注释,任何模块代码的第一个字符串都被视为模块的文档注释;

第6行使用__author__变量把作者写进去

以上就是Python模块的标准文件模板.

sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称。

  • 运行python3 hello.py获得的sys.argv就是['hello.py'];
  • 运行python3 hello.py Michael获得的sys.argv就是['hello.py', 'Michael]。

最后,注意到这两行代码:

if __name__=='__main__':
	test()

当我们在命令行运行hello模块文件时,Python解释器把一个特殊变量__name__置为__main__,而如果在其他地方导入该hello模块时,if判断将失败,因此,这种if测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。

作用域

在一个模块中,我们可能会定义很多函数和变量,但有的函数和变量我们希望给别人使用,有的函数和变量我们希望仅仅在模块内部使用。在Python中,是通过_前缀来实现的。

  • 正常的函数和变量名是公开的(public),可以被直接引用。
  • 类似_xxx和__xxx这样的函数或变量就是非公开的(private),不应该被直接引用,比如_abc,__abc等;

模块搜索路径

默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中:

>>> import sys
>>> sys.path
['', '/Library/Frameworks/Python.framework/Versions/3.4/lib/python34.zip', 
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4', 
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/plat-darwin', 
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/lib-dynload', 
 '/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages']

如果我们要添加自己的搜索目录,有两种方法:

  • 一是直接修改sys.path,添加要搜索的目录:
>>> import sys
>>> sys.path.append('/Users/michael/my_py_scripts')

这种方法是在运行时修改,运行结束后失效。

  • 第二种方法是设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。
posted @ 2020-08-28 15:31  马里奥本奥  阅读(88)  评论(0编辑  收藏  举报