前言
模块化是python中的重要知识。随着我们接触的工程项目变得越来越大时,就需要把我们的运行代码进行拆解以便我们检查和项目的推进。有些时候,几个程序都需要同一个功能,那python就提供一种方法,把需要重复利用的代码放在同一个文件夹里面,并在脚本或者python交互式解释器中使用它们。重复利用代码的文件被称为模块。模块中定义的代码可以被导入到另一个模块或主模块
模块
模块就是包含了一个python定义和声明的“.py”文件。
介绍
我们新建一个文件,将其称为“fibs.py"
在文件中定义两个函数
def fib(n):a,b=0,1while b<n:print(b,end=' ')a,b=b,a+bprint()def fib2(n):result=[]a,b=0,1while b<n:result.append(b)a,b=b,a+breturn result
我们在跟我们所定义的fibs文件的同一个目录下面建立一个新的文件,并输入下列指令
import fibs
print(fibs)
运行一下,我们就能看到下面的这一个编译结果
<module 'fibs' from 'fibs.py'>
通过结果,我们能知道这是一个叫做’fibs‘的模块,是从”fibs.py”这个文件获取的,这就说明我们成功导入了模块fibs了。
__name__变量
模块的模块名可以通过全局变量“__name__”获得。
import fibs
print(fibs.__name__)
print(__name__)
运行结果
fibs
__main__
我们发现,打印fibs中的__name__变量打出的是模块名字fibs,但是我们执行python文件打印本地的__name__变量时发现变量的值却变成了__main__。在python里面__name__是当前的模块名,当模块被直接运行时模块名就为__main__。通过python的这个特性,我们就可以在定义模块的时候通过查看当前的__name__变量值是否为__main__来判断当前文件是否被运行还是作为模块被导入。下面就是一个判断语句:
if __name__ =="__main__":print("直接运行")
else:print("被作为模板导入")
!!!python是不支持直接带点或者以数字开头的文件作为模块导入(有其他的方式可以绕过这个机制,但最好还是别用,要养成良好的编程习惯)。python中模块的文件名命名规则和变量命名规则是一样的。
dir函数
dir函数可以列出对象的模块标识符,标识符有函数,类和变量。当你为dir函数提供一个模块名的时候,它会返回模块所定义的名称列表。如果不提供参数的话,它返回当前模块中所定义的名称列表
import fibs
print(dir(fibs))
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'fib', 'fib2']
结果中可以看到一些内置变量,同时也可以看到在fibs中定义的两个函数fib和fib2,使用dir函数可以方便我们去了解对象的构造
使用模块
import...
import fibs
fibs.fib(10)
print(fibs.fib2(5))
运行结果
1 1 2 3 5 8
[1, 1, 2, 3]
这里是使用了import的语法,还有另一种语法是from...import...,这种语法方式可以让我们导入模块中一个指定的部分到当前的命名空间里面。
from... import...
from fibs import fib,fib2
fib(10)
print(fib2(5))
1 1 2 3 5 8
[1, 1, 2, 3]
这两种放方式的运行结果是一样的。不过呢,使用from...import... 之后的内容就和定义在当前文件一样方便。使用这种方式导入后呢,使用该模块时就只需要使用关键字"import"后导入的名字即可,不再需要完整的包名前缀。
包
使用
python通过模块来组织代码,模块就是一个python文件,是通过“包”来加以组织的,而“包”是一个包含__init__.py的文件夹。代码,模块和包的三者关系就是:包包含模块而且至少包含一个__init__.py,模块包含代码。
简单来说,包就是文件夹,这个文件夹下面它必须包含__init__.py文件,该文件的内容可以为空。__init__.py用于表示当前文件夹是一个包。
例子
我们在python_basic这个大的目录下建立一个名为package9的文件夹,在文件夹里面写入__init__(让package成为包的必要条件),fun1.py,fun2.py这三个文件,下面我向大家展示一下这三个文件究竟写了一些什么吧
__init__.py:
if __name__ =="__main__":print("为主程序使用")
else:print("package初始化")
fun1.py:
def print1():print("fun1")
fun2.py:
def print2():print("fun2")
我们在同一个目录下创建一个文件,注意:不在package9这个文件夹里面。
我们姑且将其称为a吧
a.py:
在a这个文件里面,我们写入以下的几行代码:
from package9.fun1 import print1
from package9.fun2 import print2print1()
print2()
我们在a里面导入了package9包里面的print1和print2这两个函数,并调用了print1和print2
运行一下a这个文件
package初始化
fun1
fun2
这里我们了解了这么去创建你的包以及怎么去调用你的包的模块中的函数。当然啦,你的包拥有无限的可能,你可以根据需要工程的需要来创建。
在多目录下使用包
我们刚刚那个例子中只有一个目录,那假如是多目录呢
当你导入一个模块或者包的时候,python解析器对模块的位置搜索顺序是
- 寻找当前的目录
- 不在就去搜索变量下的每一个目录
- 都没有的话,就去查看默认路径。
__path__
包支持一个属性:__path__,在包的文件代码执行前,它被初始化为一个包含__init__.py的目录名称的列表。这个变量是可以修改的,用于对包中包含的模块和子包进行搜索。这个功能可以用于扩展包中的模块集。
总结
接下来,我们会来谈谈模块中的标准库知识。敬请关注。