Python模块与包的使用:从基础概念到作用域控制
本文详解Python模块与包的核心概念。介绍如何通过.py文件组织代码,利用包(Package)解决命名冲突,并规范__init__.py的使用。深入解析sys模块中argv参数的读取方法,以及__name__变量在区分直接运行与模块导入时的关键作用。最后阐述通过下划线前缀实现函数与变量的公开与私有封装,提升代码可维护性。
模块
为了提升代码的可维护性,通常会将大量函数进行分类,并分别存放于不同的文件中。这种组织方式使得每个文件包含的代码量相对较少,也是众多编程语言采用的通用实践。在Python中,一个独立的.py文件即被视为一个模块(Module)。
使用模块有什么好处?
当模块编写完成后,即可被其他程序引用。在开发过程中,我们经常需要引用其他模块,这既包括Python内置的标准库模块,也涵盖来自第三方的扩展模块。
模块的使用还能有效避免函数名和变量名的冲突。即使名称相同,只要它们存在于不同的模块中,就可以共存。不过,仍需注意尽量避免使用与Python内置函数同名的标识符。
如果不同开发者编写的模块名称发生冲突,该如何处理?为了解决这一问题,Python引入了按目录结构组织模块的方法,这种结构被称为包(Package)。
假设我们的abc和xyz这两个模块名称与其他现有模块发生了冲突,我们可以通过包来重新组织它们以规避冲突。具体做法是选择一个顶层包名(例如mycompany),并按照特定的目录结构存放文件。

引入包之后,只要顶层包名不与其他人冲突,其下的所有模块都不会产生命名冲突。此时,abc.py模块的完整名称变为mycompany.abc,同理,xyz.py的模块名变为mycompany.xyz。
需要注意的是,每个包目录下必须包含一个__init__.py文件,否则Python会将该目录视为普通目录而非包。__init__.py可以是空文件,也可以包含Python代码。因为__init__.py本身也是一个模块,其模块名即为顶层包名(如mycompany)。
使用模块
!/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行是一个字符串,用于表示模块的文档注释。在Python中,任何模块代码中的第一个字符串都被自动识别为该模块的文档注释。
第6行使用__author__变量记录作者信息,这样在公开源代码后,他人即可查看作者署名。
上述内容构成了Python模块的标准文件模板。
使用sys模块的第一步是导入该模块import sys。导入sys模块后,我们便拥有了一个指向该模块的变量sys,通过sys变量可以访问sys模块提供的所有功能。
sys模块包含一个argv变量,它是一个列表,存储了运行模块时命令行输入的所有参数。argv列表中至少包含一个元素,因为第一个元素始终是.py文件的名称。
运行python3 hello.py获得的sys.argv就是['hello.py'];
运行python3 hello.py Michael获得的sys.argv就是['hello.py', 'Michael]。
工具脚本通常通过sys.argv来读取和使用参数。
最后,需要注意以下两行代码的作用。
if __name__=='__main__':
test()
当我们在命令行直接运行hello模块文件时,Python解释器会将特殊变量__name__设置为__main__。而如果从其他位置导入该hello模块,__name__的值则为导入它的模块名。因此,if判断会失败,这种if测试机制允许一个模块在通过命令行运行时执行额外的代码,最常见的用途就是运行测试。
例如:
如果直接在命令行使用python3 hello.py,__name__为__main__,则满足if条件,执行test()函数。
如果从test.py导入并使用hello.py模块,__name__的值将变为test,不满足if条件,因此不会执行test()函数。
作用域
在一个模块中,我们可能定义了许多函数和变量。其中一些希望对外公开供他人使用,而另一些仅希望在模块内部使用。在Python中,这是通过前缀下划线_来实现的。 正常的函数和变量名是公开的(public),可以直接被引用,例如:abc,x123,PI等。
类似__xxx__形式的变量属于特殊变量,虽然可以直接引用,但具有特定用途。例如前文提到的__author__和__name__就是特殊变量。hello模块定义的文档注释也可以通过特殊变量__doc__访问,但在自定义变量时,一般应避免使用这种命名方式。
类似_xxx和__xxx形式的函数或变量属于非公开(private)的,原则上不应被直接引用,例如_abc,__abc等。
之所以说私有函数和变量“不应该”被直接引用,而非“不能”,是因为Python并未提供强制限制访问私有函数或变量的机制。然而,从编程规范的角度出发,不应直接引用私有函数或变量。
换言之,这仅是一种声明约定,实际上仍可访问。那么,私有函数或变量的作用是什么?
ef _private_1(name):
return 'Hello, %s' % name
def _private_2(name):
return 'Hi, %s' % name
def greeting(name):
if len(name) > 3:
return _private_1(name)
else:
return _private_2(name)
我们在模块中公开greeting()函数,而将内部逻辑封装在私有函数中。这样,调用greeting()函数时无需关心内部私有函数的具体细节。这是一种非常有用的代码封装和抽象方法,即:
外部无需引用的函数全部定义为私有(private),只有外部需要调用的函数才定义为公开(public)。
以上就是关于Python模块的详细介绍,更多关于Python模块的资料请查阅本站其他相关文章。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









