疯狂Python讲义学习笔记(含习题)之 模块和包

一、模块化编程

import语句主要有两种用法:

● import 模块名1[as 别名1], 模块名2[as 别名2], ......:导入整个模块

● from 模块名 import 成员名1[as 别名1], 成员名2[ as 别名2], ......:导入模块中指定成员。

以上两种import语句有三点区别:

● 第一种import语句导入整个模块内的所有成员(包括变量、函数、类等);第二种import语句值导入模块内指定成员(除非使用from模块名import *,但通常不推荐使用这种语法)。

● 当使用第一种import语句导入模块中的成员时,必须添加模块名或模块别名前缀;当使用第二种import语句导入模块中的成员时,无须使用任何前缀,直接使用成员名或成员别名即可。

任何Python程序都可以作为模块导入。

为模块编写说明文档,只要在模块开始处定义一个字符串直接量即可。

如果Python程序作为模块被导入其他程序中,__name__变量的值就是模块名。

二、加载模块

为了让Python能找到我们编写(或第三方提供)的模块,可以用以下两种方式来告诉程序:

● 使用环境变量

● 将模块放在默认的模块加载路径下。

linux平台的环境变量是通过.bash_profile文件来设置的,设置完环境变量后需要重新登陆Linux平台,或者执行命令:source .bash_profile

但程序重复导入同一个模块时,Python只会导入一次。

Python默认的模块加载路径由sys.path变量代表。

导入模块的本质就是:将模块文件中的全部代码加载到内存并执行,然后将整个模块内容赋值给与模块同名的变量,该变量的类型是module,而在该模块中定义的所有程序单元都相当于该module对象的成员。

在导入模块后,可以字啊模块文件所在目录下看到一个名为“__pycache__”的文件夹,该文件夹下为每个模块生成一个*.cpython-xx.pyc文件,该文件是Python为模块编译生成的字节码,用于提升该模块的运行效率。

在默认情况下,如果使用"from 模块名 import *“这样的语句来导入模块,程序会导入该模块中所有不以下划线开头的程序单元,如果不希望将每个成员都暴露出来提供外界使用,可借助模块的__all__变量,该变量的值为可以暴露出来的程序单元列表。

如果希望程序使用模块内__all__列表之外的程序单元,有两种解决方法。

● 使用"import 模块名"来导入模块。

● 使用“from 模块名 import 程序单元"来导入指定程序单元。

三、使用包

● 从物理上看,包就是一个文件夹,在该文件夹下包含了一个__init__.py文件,该文件夹可用于包含多个模块源文件。

● 从逻辑上看,包的本质依然是模块。

定义包,主要有两步:

① 创建一个文件夹,该文件夹的名字就是该包的包名。

② 在该文件夹内添加一个__init__.py文件即可。

由于导入包就相当于导入该包下的__init__.py文件,因此完全可以在__init__.py文件中定义变量、函数、类等程序单元,但实际上往往并不会这么做。

包的主要作用是包含多个模块,因此__init__.py文件的主要作用就是导入该包内的其他模块。

例如:建立如下目录及文件结构

fk_package

   |------arithmetic_chart.py

   |------billing.py

   |------print_shape.py

   |------__init__.py

通过如下方式导入各模块:

# 导入fk_package包,实际上就是导入包下的__init__.py文件
import fk_package
# 导入fk_package包下的print_shape模块
# 实际上就是导入fk_package目录下的print_shape.py
import fk_package.print_shape
# 导入fk_package包下的billing模块
# 实际上就是导入fk_package目录下的billing.py
from fk_package import billing
# 导入fk_package包下的arithmetic_chart模块
# 实际上就是导入fk_package目录下的arithmetic_chart.py
import fk_package.arithmetic_chart
​
​
fk_package.print_shape.print_blank_triangle(5)
im = billing.Item(4.5)
print(im)
fk_package.arithmetic_chart.print_multiple_chart(5)

由于__init__.py的内容为空,因此import fk_package语句没有任何作用。

import fk_package.print_shape语句的实质是加载并执行fk_package包下的print_shape.py文件,并将其赋值给fk_package.print_shape变量。

from fk_package import billing语句的本质是导入fk_package包下的billing成员,执行这条语句后,程序可使用fk_package\billing.py文件定义的程序单元,而且只需添加billing前缀。

以上方面忽略了__init__.py文件的作用。

我们可以在__init__.py文件中构建导入:

# 从当前包中导入print_shape模块
from . import print_shape
# 从.print_shape中导入所有程序单元到fk_package中
from .print_shape import *
# 从当前包中导入billing模块
from . import billing
# 从.billing中导入所有程序单元到fk_package中
from .billing import *
# 从当前包中导入arithmetic_chart模块
from . import arithmetic_chart
# 从.arithmetic_chart中导入所有程序单元到fk_package中
from .arithmetic_chart import *
 

然后通过如下方式来导入包:

# 导入fk_package包,实际上就是导入该包下的__init__.py文件
import fk_package
​
​
# 直接使用fk_package.前缀即可调用它所包含的模块内的程序单元
fk_package.print_blank_triangle(5)
im = fk_package.Item(4.5)
print(im)
fk_package.print_multiple_chart(5)
​

四、查看模块内容

查看模块内容有两种方式:

● 使用dir()函数。

● 使用模块本身提供的__all__变量。但是并不是所有模块都会提供__all__变量。

从理论上来说,应该为每个程序单元都编写完备而详细的文档信息,这样开发者只要通过help()函数即可查看该程序单元的文档信息,完全不需要查看文档。

通过模块的__file__属性即可查看到指定模块的源文件路径。并不是所有模块都是使用Python语言编写的,有些与底层交互的模块可能是用C语言编写的,而且是C程序编译之后的效果,因此这种模块可能没有__file__属性。

你可能感兴趣的:(Python3学习)