Python模块和包
1. 定义
-
模块:在Python可理解为对应于一个文件。在创建了一个脚本文件后,定义了某些函数和变量。在其他需要这些功能的文件中,导入该模块,就可重用这些函数和变量。其后缀名是 .py ,一个.py文件就是一个模块
-
包:将一个或多个模块放在一个文件夹中,该文件夹就可视为一个包。简而言之,包本质上是一个包含代码的文件夹。包实际上只是一个目录,但是所有包都必须包含一个
__init__
.py 文件。
层级:函数(或方法) 包含于 模块,模块 包含于 包。
2. 例子
包的定义
按如下级别创建文件夹及文件,test
为一个包,hello.py
即为test
包中的模块。
test
__init__.py
hello.py
hi.py
test01.py
在hello.py
中写入以下内容:
# File_Name:hello.py
def add(a,b):
c = a + b
return c
def reduce(a,b):
c = abs(a - b)
return c
在hi.py
中写入以下内容:
# File_Name:hi.py
def multiply(a,b):
c = a * b
return c
导入包的方法
无论导入我们自定义的包,还是导入从他处下载的第三方包,导入方法可归结为以下 3 种:
-
from 包名 import 模块名 [as 别名]
-
import 包名[.模块名 [as 别名]]
-
from 包名.模块名 import 成员名 [as 别名]
用 [] 括起来的部分,是可选部分,即可以使用,也可以直接忽略。
引用方法一:
在test01.py
中引用test
包中的hello
模块:
# File_Name:test01.py
from test import hello
j = 1
k = 2
print('hello.add(j,k):', hello.add(j,k))
print('hello.reduce(j,k):', hello.reduce(j,k))
运行test01.py
文件之后得到以下结果:
hello.add(j,k): 3
hello.reduce(j,k): 1
引用方法二:
在test01.py
中直接引用test
包:
# File_Name:test01.py
import test
j = 1
k = 2
print('hello.add(j,k):', test.hello.add(j,k))
print('hello.reduce(j,k):', test.hello.reduce(j,k))
运行test01.py
文件之后得到以下结果:
AttributeError: module 'test' has no attribute 'hello'
很奇怪,竟然发生了报错,查找资料得知:直接导入包名,并不会将包中所有模块全部导入到程序中,它的作用仅仅是导入并执行包下的 __init__.py
文件,因此,运行该程序,在执行__init__.py
文件中代码的同时,还会抛出AttributeError
异常(访问的对象不存在)。
基于该问题,在__init__.py
中写入以下内容:
# File_Name:__init__.py
print('__init__.py已导入')
然后运行test01.py
文件之后得到以下结果:
__init__.py已导入
AttributeError: module 'test' has no attribute 'hello'
而对于正确使用此方法导入包,目前并未得出确切结论,还需要进一步学习。
引用方法三:
在test01.py
中引用test
包中的hello
模块中的add
方法:
# File_Name:test01.py
from test.hello import add
j = 1
k = 2
print('hello.add(j,k):', add(j,k))
然后运行test01.py
文件之后得到以下结果:
__init__.py已导入
hello.add(j,k): 3
补充:__all__变量
__all__
变量是一个列表,可以在模块中和__init__.py
中使用。
__all__
变量结合from ... import *
语句使用,__all__
变量就是控制*所表示要引入的东西(模块,函数,类等)。
在__init__.py
中增加__all__
变量:
# File_Name:__init__.py
print('__init__.py已导入')
__all__ = ['hello', 'hi']
在test01.py
中引用test
包中的所有模块:
# File_Name:test01.py
from test import *
j = 1
k = 2
print('hello.add(j,k):', hello.add(j,k))
print('hello.reduce(j,k):', hello.reduce(j,k))
print('hi.multiply(j,k):', hi.multiply(j,k))
运行test01.py
文件之后得到以下结果:
__init__.py已导入
hello.add(j,k): 3
hello.reduce(j,k): 1
hi.multiply(j,k): 2
当从__init__.py
中删除'hi'
时:
# File_Name:__init__.py
print('__init__.py已导入')
__all__ = ['hello']
运行test01.py
文件之后得到以下结果:
NameError: name 'hi' is not defined
__init__.py已导入
hello.add(j,k): 3
hello.reduce(j,k): 1
即没有被声明的模块不能使用。
END
编辑 | sxlibe
- 往期目录: