参考:
1、 有趣的Python爬虫和Python数据分析小项目
2、 python基础6–目录结构
3、 开篇python–明白python文件如何组织,理解建立源文件
4、 Open Sourcing a Python Project the Right Way
5、 python模块和包,项目结构
6、 Python Guide 系列 2.1:结构化你的项目
7、 requests 库项目参考
8、 Requests源码阅读
9、 我的项目:weibo-friends-analysis
PyCharm 里,右键点击文件夹(存放源代码的文件夹),Make Directory As -> Sources Root
一 基本概念
- 包、模块、类:
包:
文件夹中包含多个.py
文件,一个__init__.py
文件(内容可以为空)。模块:
模块对应的是一个.py
文件。类:
包含函数、变量。类中有属性和方法。一个对象就是一个类的实例。
- import 优先级:
- 当前文件目录
- 环境变量 PYTHONPATH
- sys.path(list 类型)
- 关于主函数代码:
- 没有缩进的代码(非函数定义和类定义),都会在载入时自动执行,这些代码,可以认为是 Python 的 main 函数。
- 为了区分主执行文件还是被调用的文件,Python 引入了一个变量
__name__
,当文件是被调用时,__name__
的值为模块名,当文件被执行时,__name__
为__main__
。 - 当我们在命令行运行模块文件时,Python 解释器把一个特殊变量
__name__
置为__main__
,而如果在其他地方导入该模块时,if 判断将失败,因此,这种 if 测试可以让一个模块通过命令行运行时执行一些额外的代码,最常见的就是运行测试。1
2if __name__ == '__main__' :
test()
__init__.py
文件:1
2
3
4
5__all__ = ['模块名'] # 定义该包下哪些模块可以被其它模块引用。
import sys # 批量导入模块
import io
import datetime一些模块内置变量:
1
2
3
4__name__ 表示命名空间
__package__ 表示包名称
__doc__ 表示模块注释,文档写在两行双引号中间
__file__ 表示模块路径不同作用域、用途的变量:
__xxx__
是特殊变量,可以被直接引用。_xxx 和 __xxx
这样的函数或变量就是非公开的(private),不应该被直接引用。外部不需要引用的函数全部定义成 private,只有外部需要引用的函数才定义为 public。
二 文件组织
- 实例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25weibo-friends-analysis/
|-- bin/ 或 Scripts/
| |-- ...
|
|-- src/
| |-- tests/
| | |-- __init__.py
| | |-- test_main.py
| |
| |-- one/
| | |-- __init__.py
| | |-- one.py
| |
| |-- __init__.py
| |-- main.py
| |-- fun.py
| |-- setting.py
|
|-- docs/
| |-- abc.rst
| |-- conf.py
|
|-- setup.py
|-- requirements.txt
|-- README
setting.py:
包含 setting 类,这个类只包含方法__init__()
,用来初始化一些东西。requirements.txt:
此文件列出项目所需的任何第三方依赖项。它让其他人知道为了处理项目需要哪些库。简单来说,它是一个 pip 安装要求列表。setup.py:
安装、部署、打包的脚本。在 setup.py 文件中写明依赖的库和版本,以便到目标机器上能够使用python setup.py install
安装。scripts/
项目用到的各种脚本。docs/
项目文档,一般来说里面还包含 config.py。etc/
用来存放配置文件的样例。tools/
用来存放与工具有关的shell脚本。bin/
用来存放将被setup.py安装的二进制脚本。data/
用来存放其他类型的文件,如媒体文件。如果是发行自己的模块,顶层目录还需要下面三个文件:
setup.cfg: 包含 setup.py 默认命令选项的 ini 文件。/ LICENSE.txt 项目许可说明文件。如果需要使用 setuptools 等工具进打包发行,那么需要一个许可文件。/ MANIFEST.in:装箱清单文件,当需要打包源码中不自动包含的附加文件时使用。
- 调用方法:
主程序与模块程序在同一目录:
main.py 中直接使用import fun
或from fun import *
。主程序使用子目录下的模块:
main.py 中直接使用import tests.test_main
或from tests.test_main import *
。子模块使用上级 / 其它同级包中模块:
test_main.py 使用 main.py 和 one.py,在 test_main.py 中直接导入使用,然后在tests/
文件夹中执行 test_main.py。/ 使用同级包中的模块可以直接import 模块名
(可以忽略 IDE 的警告)。1
2
3
4import sys
sys.path.append("..")
import src.main
import one.one
小结:
导入模块关键是能够根据 sys.path 环境变量的值,找到具体模块的路径。主函数 main.py 调用其它脚本方法:
主函数中
os.system('python ./自己的包名/XXX.py')
,如果是同级目录的话os.system('XXX.py')
,最好是先拼出绝对路径再执行this_file_path = os.path.abspath(__file__)[:-7]
os.system(this_file_path + 'modules/help.py')
;主函数中用from 自己的包名 import 模块名
包中的模块使用同级其它模块
from 自己的包名 import 模块名
使用 from 这种方式导入,直接代码中使用
模块名.其中的函数
就行了,使用更简洁。
三 单个文件结构
1 | #!/usr/bin/env python 可以让这个py文件直接在Unix/Linux/Mac上运行 |
在每个文件模块里放置了一个函数,可以放置许多函数;也可以在这些文件里定义 Python 的类,然后为这些类建一个包。
多个文件相互调用组织:
将主逻辑定义成函数写在 main.py 中并在其中运行(类似面向过程)。主函数模块用到的子模块、包在前面导入;剩下的类、函数等全部拆成模块、包,被 main.py 中的主逻辑函数调用(面向过程、面向对象)。