项目文件组织形式

Python 项目主要通过包和模块来组织其代码,一般可以按照功能对代码进行分组形成模块和包。

既然是一个完整的项目,那么仅有包和模块提供功能是不够的,还需要在项目根目录下提供一个项目入口文件,供解释器加载。

模块

模块是一个包含所有你定义的函数和变量的文件,其后缀名是`.py}。模块可以被别的程序引入以使用该模块中函数等功能。这也是 Python 功能库的组成方法。

模块中除了可以包含方法定义以外,还可以包含可执行的代码,用于在第一次导入时初始化模块使用。每个模块都有独立的符号表,在模块内部为所有的函数当作全局符号来使用,所以在模块内部可以放心大胆的使用这些全局变量。

在阅读其他作者书写的模块时,常常会在模块的结尾看到以下格式的代码段。

if __name__ == '__main__':
    pass

这是利用__name__属性来判断模块是独立运行还是被另一个程序引入执行。具体可以参考以下示例。

if __name__ == '__main__':
    print('程序独立运行')
else:
    print('来自另一个模块')

利用这项功能,可以为模块的不同运行模式进行不同的初始化工作。

包是管理 Python 模块命名空间的形式,采用package.module(点模块名称)的格式。比如一个模块的名称是A.B,则表示包 A 中的子模块 B。

使用点模块名称的好处是不用担心不同库之间的模块重名的情况。

包在文件系统中,就是一个普通的目录,其中需要放置一个__init__.py文件作为包的标记,并且其中可以放置包的初始化代码,在一般情况下,只需要放置一个空白的__init__.py即可。并且包中可以有子包存在,例如下面的包结构。

father_package/
    __init__.py
    father_module.py
    father_module_another.py
    child_package/
        __init__.py
        child_module.py
        child_module_another.py
这里的示例在后文中还会使用。

在导入一个包的时候,实际上是导入了它的__init__.py文件,所以可以在__init__.py中批量导入需要的模块,而不用再次一一导入。此外,__init__.py中还有一个重要的变量:__all__,它接受一个字符串列表作为它的值,凡是出现在其中的内容,都会在使用from ... import *导入时被全部导入,所有没有列入__all__的不会被导入。但是__all__不会影响明确列明要导入内容的模块,例如上例中的import father_package.father_module

文件编码

Python2 是不支持 UTF-8 格式的源代码文件的,所有出现和使用 UTF-8 内容的位置都需要采用转义的方式表示。在 Python3 中这一情况有了极大的改观,因为 Python3 默认采用 UTF-8 作为源代码的编码格式。

如果需要使用其他的编码格式保存源代码文件,需要在源代码文件首行使用以下格式的标记来声明要使用的编码格式。

# -*- coding: gbk -*-

Warning

注意,Python 很计较空格,以上声明标记中的空格一个都不要少。

代码格式

Python 有一套详细而具体的编码规范可供参考和遵循,具体见后文对于 PEP8 的阐述。这里只针对一般常用的基本代码格式做一个介绍。

标识符

第一个字符必须是字母或者下划线,其他字符可以由字母、数字和下划线组成。Python 的标识符是大小写敏感的。

注释

有单行注释和多行注释两种类型。其中单行注释以#开头,而多行注释既可以以#开头,也可以直接使用"""三引号字符串。

缩进

这是 Python 的一大特色。Python 不使用大括号来表示代码块,而是使用缩进来表示代码块。相同的缩进数量表示一个代码块。如果缩进的空格数不一致,并且没有新代码块的引导语句,那么 Python 将会报错。这一点需要在日常的练习和编码中多加体会。

语句 Python 的语句不使用分号等任何符号结尾,每行中建议仅书写一条语句。如果需要书写多条语句,那么语句之间需要使用分号隔开。如果语句过长需要分行书写,可以在每行的末尾使用反斜线进行分行标记。