Python中的函数(Function)、类(Class)、模块(Module)、包库(Package),都是为了实现模块化引用,让程序的组织更清晰有条理。
- 通常,函数、变量、类存储在被称为模块(Module)的.py文件中,一组模块文件又组成了包(Package)。
- 将函数、变量、类存储在存储在独立的.py文件中,可隐藏代码实现的细节,将不同代码块重新组织,与主程序分离,简化主程序的逻辑,提高主程序的可读性。
- 有了包和模块文件,可以在其他不同程序中进行复用,还可以使用其他人开发的第三方依赖库。
- 便于协同开发,不同人员独立开发各自的包,最后形成项目。
1. Packages官方解释
1.1 包(package)与模块(module)
python 官方对package的解释如下。官方地址:https://docs.python.org/zh-cn/3/tutorial/modules.html#packages
Packages 可以理解为一组模块的包,并用Package.Module的方式来构建命名空间。文件夹中必须有__init__.py
这个文件,才能使 Python 将包含该文件的目录视为包(Package)。
例如,这是一个官方的package例子,提供了关于声音处理的sound
包:
sound/ Top-level package
__init__.py Initialize the sound package
formats/ Subpackage for file format conversions
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ Subpackage for sound effects
__init__.py
echo.py
surround.py
reverse.py
...
filters/ Subpackage for filters
__init__.py
equalizer.py
vocoder.py
karaoke.py
...
__init__.py
必须有这个文件,才能使 Python 将包含该文件的目录视为包(Package)。__init__.py
可以是一个空文件,也可以执行包的初始化代码或设置__all__
变量。__all__指定的是指此包被import * 的时候, 哪些模块会被import进来.- formats/ 、effects/ 、filters/ 是次一级的子包(Subpackage),每个子包中也有
__init__.py
文件。 - echo.py等文件是子包中的模块(Module),模块中可能包含函数、类或变量。
import sound.effects.echo
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
引用包(package)中子包(submodule)的示例:
from sound.effects import echo
echo.echofilter(input, output, delay=0.7, atten=4)
from sound.effects.echo import echofilter
echofilter(input, output, delay=0.7, atten=4)
1.2 使用__all__提供包的显示索引
当我们直接采用from sound.effects import *
时,可能会引用一些不需要的内容,或者导致加载速度过慢。 因此import 语句使用以下约定:包的__init__.py
代码可以定义了一个名为__all__
的列表,来指定用 *
时应导入的模块名称列表。假如sound/effects/__init__.py
包含以下代码:
__all__ = [
"echo",
"surround",
"reverse"
]
这意味着from sound.effects import *
将会加载这3个字模块。
需要注意的是,子模块可能会被本地定义的函数名遮挡,如果您在sound/effects/__init__.py
文件中添加了一个reverse
函数,则from sound.effects import *
将只导入两个子模块echo
和surround
,而不导入reverse
子模块,因为本地定义了reverse
函数名:
__all__ = [
"echo", # refers to the 'echo.py' file
"surround", # refers to the 'surround.py' file
"reverse", # !!! refers to the 'reverse' function now !!!
]
def reverse(msg: str): # <-- this name shadows the 'reverse.py' submodule
return msg[::-1] # in the case of a 'from sound.effects import *'
1.3 包内引用
构造成的子包(如示例中的sound
包),可以使用绝对导入来引用兄弟包的子模块。例如,如果模块sound.filter.vocoder
需要使用sound.effects
包中的echo
模块,则可以使用 from sound.effects import echo
。
您还可以使用import
语句的from module import name
形式相对导入。这些导入使用.
来指示相对导入中涉及的当前包和父包。例如,从surround
模块中,可以使用:
from . import echo
from .. import formats
from ..filters import equalizer
请注意,相对导入基于当前模块的名称。由于主模块的名称始终为__main__
,因此打算用作Python应用程序主模块的模块必须始终使用绝对导入。
2. 示例demo
package-test
|- __init__.py
|- package_1
|-- subpackage_1
|--- __init__.py
|--- module_1.py
|--- module_2.py
module_1.py
:
def func_1():
print('func_1')
module_2.py
:
def func_2():
print('func_2')
子包subpackage_1
中定义了__init__.py
,包含了module_1
及module_2
两个子模块:
from . import module_1
from . import module_2 # 注:每个模块占一行,方便版本控制时查看diff
__all__ = [
'module_1', # 注:每个模块占一行,便于版本控制时查看diff
'module_2',
]
包package_1
中定义了__init__.py
,包含了subpackage_1
子包:
from . import subpackage_1
__all__ = [
'subpackage_1',
]
from package_1 import subpackage_1
if __name__ == '__main__':
subpackage_1.module_1.func_1()
subpackage_1.module_2.func_2()
原文地址:https://blog.csdn.net/WonderThink/article/details/134721870
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_40494.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!