Python 入门笔记(十二)包与模块
模块
基本概念
模块的定义
一般情况下,模块(module)是一个以 .py
为后缀的文件,其他可作为 module 的文件类型还有 .pyo
、.pyc
、.pyd
、.so
、.dll
,但初学者几乎用不到
在模块中能定义函数、类、变量,也能包含可执行的代码,在导入的时候会把模块完整地先执行一遍
模块的作用
隐藏代码细节,提高可维护性
模块的分类
- Python 的官方标准库(直接
import
就能开用) - 第三方模块(用
pip
下载的包里面的模块等) - 自己写的模块(下面来试一试)
初尝模块
首先,在当前目录新建一个 calc.py
,再在里面保存一些函数
1 | def add(a,b): |
现在我们在其他文件中引用它,在同一目录新建一个 .py
文件
import …
导入整个模块
1 | import calc |
使用这种方法,在调用其中的函数或类时,必须加上模块名的前缀
from … import …
导入特定的内容,使用时不用前缀
1 | from calc import add, sub # 可以导入任意个 |
from … import *
这会把模块中的所有函数、类、变量等全部导进来,虽然方便,但是不建议使用(可能与已有的内容冲突)
1 | from calc import * |
稍稍深入
取别名
在导入的时候可以给模块或者函数使用 as
取别名
1 | import calc as c # 这样在下面都可以使用 c 来代替 calc 了 |
1 | from calc import add as a # 这样在下面都可以使用 c 来代替 add 了 |
(下面的包也可以这样操作,可以把前面冗长的前缀如 包名.子包名.模块名
简化成一个词)
路径问题
现在,你已经学会如何导入模块了,但是,python 是从哪里找到这些模块的呢?
答案是去 sys.path
中查找,这个列表的第一个元素是当前路径,然后还有一些预定义的路径
使用下面的命令查看 sys.path
1 | import sys |
若要手动添加路径到 sys.path
里面,可以使用 sys.path.append()
方法
而且这个一般会结合 os.path.dirname(__file__)
和 os.path.abspath(__file__)
来使用,可以尝试下面的例子
1 | import os |
联合使用这三者可以将要导入的模块的绝对路径添加到 sys.path
里面,这样能够保证可以找到你所要导入的模块
1 | path5 = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # 先获取当前执行脚本的完整路径,再去掉最后2个路径(相当于:获取当前运行脚本的绝对路径,再去掉1个路径) |
_name_ 属性
在很多地方,你都会看见这样一句话,它与模块的导入有关
1 | if __name__=='__main__': |
__name__
属性可以理解为一个全局变量,它的值在各种地方是不同的
- 当该模块被其它模块调用时,
__name__
的值当前模块的名字 - 当该模块被当做执行脚本时(也就是程序从这个模块开始运行),
__name__
的值为__main__
1 | # Filename: using_name.py |
运行输出如下:
1 | $ python using_name.py |
1 | $ python |
包
基本概念
为避免模块名冲突,Python 引入了按目录组织模块的方法,称之为包(package)
模块与包的关系就如文件与文件夹的关系,文件夹的层次是用斜杠或者反斜杠来表示的,而包是用 .
来分隔层次的
你可以导入整个包,或仅仅只是导入包中的模块
如何导入
如果你想导入包,可以使用 import 包名
或 import 包名.子包名
等
如果想导入模块,可以使用 import 包名.模块名
(使用时必须有前缀) 或 from 包名 import 模块名
(推荐用法)
如何构建
_init_.py
在一个文件下同时有 __init__.py
文件和其他模块文件时,该文件夹即看作一个包
如果导入的对象是包,会执行那个包的 __init__ .py
文件
_all_ 属性
这东西在模块里其实也是有意义的,但一般都用在 __init__ .py
里
在模糊导入包或模块时( from pacakge_1 import *
),仅仅会导入 __all__
中指定的包和模块(如果没有指定,那么什么都不会被导入)
1 | __all__ = ["echo", "surround", "reverse"] # 指定模块 |
例子
菜鸟教程最底下的那个例子就挺好的