引言
前面我们说到面向对象的程序设计使用了类的方法,但当代码过多时,在不同py文件中都有相同功能时,我们需要将这个共有的功能单独拿出来写进一个py文件中,方便使用和修改,定义重复使用的代码的文件被称为模块,模块中定义的代码可以被导入到另一模块或主模块中
模块
模块介绍
我们可以先定义一个.py文件,例如我定义了一个fibs.py文件,我们可以在同目录下引用这个模块
import fibs
print(fibs)
执行结果如下
<module "fibs" from "fibs.py">
这个例子中,我们使用了import关键字,将前面定义的文件进行了导入,打印出来的内容就是告诉我们,导入成功,并将导入的模块位置告诉了我们
__name__变量
模块的模块名可以通过全局变量__name__获得
import fibs
print(fibs.__name__)
print(__name__)
执行结果如下
fibs
__main__
我们发现fibs的__name__变量打印出来的是模块名,但是我们直接打印__name__时却是__main__,在Python中当模块直接运行时模块名是__main__有了这个属性我们可以通过观察当前的__name__属性观察值是否为__main__来判断当前文件是被运行还是作为模板被导入
dir函数
该函数可以列出对象的模块标识符,标识符有函数,类和变量。当你为dir函数提供一个模块名时,它返回模块定义的名称列表,如果不提供参数,它返回当前模块中定义的名称列表,例如
import fibs
print(dir(fibs))
执行后查看执行结果,可以看到一些内置变量,同时也可以看到在fibs中定义的函数
使用模块
知道模块有哪些标识符,我们就可以使用模块了,模块也是对象,所以调用模块中的内容和调用对象中的方法是一致的,例如
import fibs
fibs.fib(10)
当然我们可以调用模块中的某一部分,模块是"from·····import·····"例如
from fibs import fib,fib2
fib(10)
fib2(10)
包
使用包
先来说说三者的关系,包包含模块且至少包含一个__init__.py,模块包含代码,简单来说,包就是文件夹,且其下必须有__init__.py文件,该文件的内容可以为空,init.py用于表示当前文件夹是一个包,接下来我们来测试一下包的使用,首先创建
package9
|--__init__.py
|--fun1.py
|--fun2.py
然后我们在package9同级目录下创建9.3.1.py来调用package9包
# 导入package9包
from package9.fun1 import print1
from package9.fun2 import print2
print1()
print2()
包在多目录中使用
当你导入一个模块或是包时,对模块位置的搜索位置的搜索顺序为
(1)首先查找当前目录
(2)不在当前目录,就会搜索shell变量pythonpath下的每个目录
(3)都找不到就会查看默认路径
模块搜索路径存储在system模块的sys.path变量之中,变量里包含当前目录、PYTHONPATH下的目录和由安装过程决定的默认目录。
包还支持一个更特殊的属性: __path__在包的文件代码执行之前, 它被初始化为一个包含__init__py的目录 名称的列表。这个变量可以修改,用于对包中 包含的模块 和子包进行搜索。
虽然这个功能不是必需的,但它可用于扩展包中的模块集。