模块有什么用呢?何不把所有的 py 代码都放在一个文件中呢?
大量代码在一个文件中,不易于维护,大量的代码会让人眼花缭乱,我们根据功能不同分为多个文件,那么维护的时候就很方便了。
从另一方面,我们会写一些比较有用的代码,我们将其封装为单独的模块,下次使用此功能的时候就不需要重写编写代码,达到复用的效果,我们的程序也不需要每次都从零开始。
封装为单独的模块,还可以解决命名冲突的问题,不同模块中的名字是可以重复的。但是同一模块中名字是不可以重复的。达到复用名字的效果。
1. 使用模块
Python 中的模块指的是一个包含的各种 Python 对象的程序文件。
1.1 模块使用
我们编写一个模块,命名为 my_module.py,在该模块中我们定义一些函数和类,如下代码所示:
# Person类 class Person(object): def __init__(self,name,age): self.name = name self.age = age def show_person(self): print("Name:%s Age:%d"%(self.name,self.age)) # 函数 def my_add(a,b): ret = a + b return ret
我们在其他 Python 文件中使用时,首先需要导入这些需要的对象,导入方法如下:
- import 模块名
- import 模块名 as 别名
- from 模块名 import 符号
- from 模块名 import 符号 as 别名
- from 模块名 import *
# 1. import 模块名 import mymodule print(mymodule.my_add(10, 20)) # 2. import 模块名 as 别名 import mymodule as mm print(mm.my_add(10, 20)) # 3. from 模块名 import 符号 from mymodule import Person person = Person('smith', 18) person.show_person() # 3. from 模块名 import 符号 as 别名 from mymodule import Person as P from mymodule import my_add as ma p = P('obama', 20) p.show_person() print(ma(10, 20)) # 4. from 模块名 import * from mymodule import * person = Person('smith', 18) person.show_person()
1.2 main
如果我们的 my_module 模块内容如下:
def my_addd(): print('a + b = %d' % (a + b)) # 测试代码,或者其他一些代码 my_add(10, 20)
当 my_module 作为模块被 import 到其他文件中时,上面的 my_add 函数调用就会被自动执行。我们可以进行如下改进来避免此问题:
def my_addd(): print('a + b = %d' % (a + b)) # 测试代码或者其他一些代码,避免被作为模块导入时被执行 if __name__ == '__main__': my_addd(10, 20)
所以,if main 的作用就是避免某个 Python 模块被导入时自动执行一些测试代码。
2. 包
为了更好管理模块,将多个模块放到一个文件夹中,这个文件夹就叫做包,但是此文件夹下必须包含__init__.py 文件,该__init__文件可以为空。__init__文件主要用于标识该目录是一个包。我们接下来构建一个名字叫叫做 package 的 Python 包,目录结构如下:
package |-- __init__.py |-- my_module1.py `-- sub_package |-- __init__.py `-- my_module2.py
2.1 使用包
# 1. import 模块名 import package.my_module1 import package.sub_package.my_module2 package.my_module1.my_function1() package.sub_package.my_module2.my_function2() # 2. import 模块名 as 别名 import package.my_module1 as p import package.sub_package.my_module2 as sp p.my_function1() sp.my_function2() # 3. from 模块名 import 符号 from package.my_module1 import my_function1 from package.sub_package.my_module2 import my_function2 my_function1() my_function2() # 4. from 模块名 import * from package.my_module1 import * from package.sub_package.my_module2 import * my_function1() my_function2()
2.2 __init__.py 文件的作用
init 文件中一般用来编写一些模块的初始化代码或者其他一些用于简化 import 的代码。这一部分我们通过案例描述。目录结构为:
. |-- main.py `-- package |-- __init__.py |-- my_module1.py `-- sub_package |-- __init__.py |-- my_module2.py
package 中 定义 my_function1 函数,sub_package/my_module2 中定义 my_function2 函数。包的目录结构会导致导入包时编写的路径较长,我们可以使用 init 文件来简化这个步骤。
sub_packgae/init.py 文件内容如下:
from package.sub_package.my_module2 import *
执行效果就是将 my_module2 中的 my_funtion2 提到了 sub_package 空间中,如下图所示:
其中 packgae/init.py 文件内容如下:
from package.my_module1 import * from package.sub_package import *
这两行代码,将 sub_package 中的 my_function2 和 my_module1 中的 my_function1 提升到了 package 空间中,如下图所示:
当我们在 main 中导包时,就可以直接通过顶层包名来导入某个具体符号,如下代码所示:
# 通过包名直接导入模块中定义的符号 from package import my_function2 from package import my_function1
讲的很基础,很清晰,踩点,孟老师