每个人的Python:数学、算法和游戏编程训练营
上QQ阅读APP看书,第一时间看更新

1.5.3 模块和包的应用

通过前面章节的学习,我们编写了很多代码,如果将这些代码全部写在一个文件中的话,现在这个文件中的内容一定非常多,对于编程来说,如果在一个文件中编写过多的代码,无论是理解逻辑还是添加功能都将变得非常困难,文件中的代码越多,要精确地找到某行代码就越困难。

在大型的软件工程中,一个完整的项目可能需要上百万甚至千万行的代码量,这么庞大的代码量如果不进行有效地组织管理,将会变成巨大的灾难。对软件工程的组织管理实际上就是将代码分解到不同文件中,将文件分门别类地放入不同文件夹中,再将文件夹分类进不同的模块包中等。通过这种层级方式的管理,使得项目的目录组织结构更加清晰,提高编码效率。

在Python中,模块就是一个Python文件,由文件夹组织而成的目录结构被称为包。还记得我们前面所使用的数学计算相关的函数吗,其中很多都是定义在math模块中的,使用import语句来将模块导入当前文件中。我们也可以定义自己的模块,在之前所编写的测试代码文件的同级目录下新建一个名为myfunc.py的文件,在其中编写如下代码:

在其他文件中,如果要调用newPrint方法,只需要将这个模块导入即可,示例代码如下:

        import myfunc
        myfunc.newPrint()

在Python中,使用import语句导入模块时不会产生重复导入的问题,也就是说,无论执行多少次import语句来导入同一个模块,这个模块也只会被导入一次。

当一个模块被导入后,可以使用模块名作为前缀来调用模块中定义的函数、变量以及类等。如果不需要模块中的所有内容,也可以单独导入模块的部分功能,示例如下:

        from myfunc import newPrint
        newPrint()

通过from-import方式导入的内容可以直接调用使用,无须再添加模块前缀,进一步方便了我们的使用。还有一种方式可以将模块中所有的内容导入当前文件中,并且不需要前缀即可直接对模块中的内容进行调用,示例如下:

        from myfunc import *
        newPrint()

在导入模块的时候,模块中的逻辑也会被执行,但只有在第一次导入模块时会被执行。这提供了一种方式让我们可以在模块加载时编写一些初始化的逻辑,例如在myfunc.py文件中编写如下代码:

在主文件中导入myfunc.py模块,通过打印信息即可看到模块加载时执行了模块内部的逻辑代码。

Python中的模块用来组织函数、类、变量等代码元素,包则用来组织模块。简单理解,包更像是一个文件夹,将一组功能关联的模块组织起来。首先在当前Python文件的同级目录下新建一个名为myPackage的文件夹,需要注意,一个文件夹要想成为Python中的包,其中需要包含一个名为__init__.py的文件,这个文件的作用除了标志当前文件夹为一个Python包外,其内也可以编写包的初始化代码,在myPackage文件夹下新建一个名为__init__.py的文件,在其中添加一句打印信息的代码用来进行测试,示例如下:

        print("myPackage包加载完成")

之后,在myPackage文件夹下新建两个Python模块文件,分别命名为mod1.py和mod2.py,在mod1.py中编写如下代码:

在mod2.py中编写如下代码:

在需要使用包中的模块时,可以使用如下方式进行导入:

        import myPackage.mod1 #myPackage包加载完成
        # 可以使用包中的所有模块
        myPackage.mod1.mod1()

有了模块和包的支持,对代码的组织变得非常容易,在实际项目的开发中,我们也会创建大量的模块和包用来对代码分门别类地进行管理。