什么是包
- 简单理解,包就是文件夹,只不过在该文件夹下必须存在一个名为“__init__.py” 的文件。
- 注意,这是 Python 2.x 的规定,而在 Python 3.x 中,__init__.py 对包来说,并不是必须的。
- 每个包的目录下都必须建立一个 __init__.py 的模块,可以是一个空模块,可以写一些初始化代码,其作用就是告诉 Python 要将该目录当成包来处理。
- 注意, __init__.py 不同于其他模块文件,此模块的模块名不是 __init__,而是它所在的包名。例如,在 settings 包中的 init.py 文件,其模块名就是 settings。
- 包是一个包含多个模块的文件夹,它的本质依然是模块,因此包中也可以包含包。
创建包
如果我们想手动创建一个包,只需进行以下 2 步操作:
- 新建一个文件夹,文件夹的名称就是新建包的包名;
- 在该文件夹中,创建一个 __init__.py 文件(前后各有 2 个下划线‘_’),该文件中可以不编写任何代码。当然,也可以编写一些 Python 初始化代码,则当有其它程序文件导入包时,会自动执行该文件中的代码
举个例子. 现在我们创建一个非常简单的包,该包的名称为 my_package
- 创建一个文件夹,其名称设置为 my_package;
- 在该文件夹中添加一个 __init__.py 文件,此文件中可以不编写任何代码。不过,这里向该文件编写如下代码:
'''
http://c.biancheng.net/
创建第一个 Python 包
'''
print('http://c.biancheng.net/python/')
- 可以看到, __init__.py 文件中,包含了 2 部分信息,分别是此包的说明信息和一条 print 输出语句。
由此,我们就成功创建好了一个 Python 包。
创建好包之后,我们就可以向包中添加模块(也可以添加包)。这里给 my_package 包添加 2 个模块,分别是 module1.py、module2.py
#module1.py模块文件
def display(arc):
print(arc)
#module2.py 模块文件
class CLanguage:
def display(self):
print("http://c.biancheng.net/python/")
现在,我们就创建好了一个具有如下文件结构的包:
my_package
┠── __init__.py
┠── module1.py
┗━━ module2.py
导入包
通过前面的学习我们知道,包其实本质上还是模块,因此导入模块的语法同样也适用于导入包。无论导入我们自定义的包,还是导入从他处下载的第三方包,导入方法可归结为以下 3 种:
- import 包名[.模块名 [as 别名]]
- from 包名 import 模块名 [as 别名]
- from 包名.模块名 import 成员名 [as 别名]
用 [] 括起来的部分,是可选部分,即可以使用,也可以直接忽略。
- 注意,导入包的同时,会在包目录下生成一个含有 __init__.cpython-36.pyc 文件的 __pycache__ 文件夹。
- import 包名[.模块名 [as 别名]]
import my_package.module1
my_package.module1.display("http://c.biancheng.net/java/")
- 可以看到,通过此语法格式导入包中的指定模块后,在使用该模块中的成员(变量、函数、类)时,需添加“包名.模块名”为前缀。
- 当然,如果使用 as 给包名.模块名”起一个别名的话,就使用直接使用这个别名作为前缀使用该模块中的方法了
import my_package.module1 as module
module.display("http://c.biancheng.net/python/")
- 另外,当直接导入指定包时,程序会自动执行该包所对应文件夹下的 __init__.py 文件中的代码。例如:
import my_package
my_package.module1.display("http://c.biancheng.net/linux_tutorial/")
- 直接导入包名,并不会将包中所有模块全部导入到程序中,它的作用仅仅是导入并执行包下的 __init__.py 文件,因此,运行该程序,在执行 __init__.py 文件中代码的同时,还会抛出 AttributeError 异常(访问的对象不存在):
http://c.biancheng.net/python/
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\demo.py", line 2, in <module>
my_package.module1.display("http://c.biancheng.net/linux_tutorial/")
AttributeError: module 'my_package' has no attribute 'module1'
- from 包名 import 模块名 [as 别名]
from my_package import module1
module1.display("http://c.biancheng.net/golang/")
- from 包名.模块名 import 成员名 [as 别名]
from my_package.module1 import display
display("http://c.biancheng.net/shell/")
from my_package.module1 import display as dis
dis("http://c.biancheng.net/shell/")
pycache 是模块的缓存文件
- py代码在执行前,需要被解析器先转换为机器码,然后再执行
- 所以我们在使用模块(包)时,也需要将模块的代码先转换为机器码然后再交由计算机执行
- 而为了提高程序运行的性能,python会在编译过一次以后,将代码保存到一个缓存文件中
- 这样在下次加载这个模块(包)时,就可以不再重新编译而是直接加载缓存中编译好的代码即可