在项目开发过程中,我们经常把项目中常用的功能或算法写成一个可供其它文件调用的函数或类,我们把这些函数和类放在一个文件中,这个文件就叫做模块,因为这个模块是我们自己写的,所以叫自定义模块。
模块很好的解决了软件工程中的低耦合,高内聚的要求,我们在项目开发中,把经常被使用的函数和类封装成模块是个很好的编程习惯。
我们自己写个函数放在一个后缀名为 py 的文件里,如果我们在其它文件中使用该文件,这个文件相对使用它的文件就叫自定义模块。 自定义模块的引用方式是用 import... ,或者 from...import... ,但要注意自定义的模块和引用文件要放在一个目录下。下面我们实现一个定义模块,模块文件名为 mabs.py,我们通常叫模块名为 myabs(不带后缀名),在该模块内,我们实现一个函数 myabsfunc,该函数返回数字的绝对值,我们在 hello.py 文件中引用该自定义模块。
''' myabs.py 文件(该文件为自定义模块 myabs) 。 该模块有一个函数 myabsfunc。 ''' def myabsfunc(data): try: data = int(data) except: raise TypeError("必须为数字类型") return data if data >= 0 else -data
''' hello.py 文件。 该文件引用自定义模块 myabs。 ''' import myabs # 导入自定义模块 print(myabs.myabsfunc(-250))
当然我们也可以直接导入这个模块内的函数。
''' hello.py 文件。 该文件引用自定义模块 myabs。 ''' from myabs import myabsfunc # 从自定义模块 myabs 里导入函数 print(myabsfunc(-250))
我们可以给 import... 后面的名字起个别名。
''' hello.py 文件。 该文件引用自定义模块 myabs。 ''' from myabs import myabsfunc as absfunc # 给函数起个别名 print(absfunc(-250)) ################################ 我是分割线 ################################ ''' hello.py 文件。 该文件引用自定义模块 myabs。 ''' import myabs as absmodule # 给函数起个别名 print(absmodule.myabsfunc(-250))
在开发项目中,我们可能要写很多模块,为了方便与组织,我们可以把这些模块放入一个目录中,Python 对按目录来组织模块的方法,称为包(Package),包是模块的集合,比模块又高一级的封装。 没有比包更高级别的封装,但是包可以嵌套包,就像文件目录一样。导入包的方式和导入模块一样,但要注意,包里面必须要有一个 __init__.py 文件,否则会报错。比如在项目 python_one 中,我们创建一个 mytools 包,把 myabs 模块放入该包中,在 hello.py 中使用该包中的 myabsfunc 函数。
如果我们的包中有多个(比如几十个)模块,对每个模块都需要使用 from...import... 的方式导入,那就很 low 了。Python 支持用 from...import * 的方式可以导入 __init__.py 的文件里的 __all__ 变量里面限定的模块。假如我们的 mytools 包里面有两个模块 myabs 和 myhaha,我们可以在 __init__.py 里面限定要导入的模块。
''' __init__.py 文件。 变量 __all__ 的值是对使用 from...import * 语法导入模块的限定。 ''' __all__ = ["myhaha"] # 如果使用 from...import * 语法,则只导入了 myhaha 模块。
''' myabs.py 文件(该文件为自定义模块 myabs) 。 该模块有一个函数 myabsfunc。 ''' def myabsfunc(data): try: data = int(data) except: raise TypeError("必须为数字类型") return data if data >= 0 else -data
''' myhaha.py 文件(该文件为自定义模块 myhaha) 。 该模块有一个函数 myhahafunc。 ''' def myhahafunc(): return "haha"
''' hello.py 文件。 该文件使用 mytools 包。 ''' from mytools import * # 只导入了 __init__.py 文件里的 __all__ 变量里面的模块。 print(myhaha.myhahafunc()) # 正确 print(myabs.myabsfunc(-250)) # 错误
当然如果不使用 from...import * 的方式导入模块,则不受 __init__.py 文件里的 __all__ 变量的限制。
比如我们在 __init__.py 文件里写入 __all__ = ["myhaha"]
,我们可以直接导入 myabs 模块。
''' hello.py 文件。 该文件使用 mytools 包。 ''' from mytools import myabs print(myabs.myabsfunc(-250)) # 正确,不受 __all__ 变量的限制
无论是导入包还是模块还是模块里的函数,变量,或类等等,import 后面的内容必须是一级单位。
''' hello.py 文件。 该文件使用 mytools 包。 ''' import mytools # 正确,导入 mytools 包 from mytools import myabs # 正确,导入 mytools 包里的 myabs 模块 from mytools.myabs import myabsfunc # 正确,导入 mytools 包里的 myabs 模块里的 myabsfunc 函数 import mytools.myabs # 错误,import 后面必须是一级单位 from mytools import myabs.myabsfunc # 错误,import 后面必须是一级单位
会写模块并导入模块。
会写包并导入包。
写两个模块,放入包中,一个模块里面写一个 Woman 类,一个模块里面写一个 myprint 函数,供其它文件调用,把 Woman 类的对象传给 myprint 函数,打印出该对象的名字。
受教了