Python 包导入
Python 包帮助我们管理模块和 Python 脚本。它们是普通的目录,其中包含一个初始化脚本——init.py。
如何创建Python包?
我们可以按照以下步骤创建软件包。
- 创建包目录——我们可以使用终端或Python IDE来完成此操作。
- 创建 init.py 文件——这是将普通目录转换为 Python 包所必需的。此文件用于初始化包并列出所有模块。最简单的情况下,此文件可以为空。
Python 包中可以包含哪些内容?
- 初始化文件
- Python 模块
- Python脚本
- 其他类型的文件
所以,一般来说,软件包就像我们计算机系统中的一个目录。唯一的区别在于,软件包必须包含__init__.py文件。
我们可以在Python中创建子包吗?
是的,我们可以在一个包内创建一个包。创建子包也需要遵循打包规则。
Python 包示例
让我们来看一些创建和使用软件包的例子。
1. 创建包
$ mkdir utilities
$ touch utilities/__init__.py
$ mkdir utilities/strings
$ mkdir utilities/strings/__init__.py
$ tree
.
└── utilities
├── __init__.py
└── strings
└── __init__.py
3 directories, 1 file
$
2. 向软件包添加模块
假设我们有两个 Python 模块——math.py和str_utils.py。它们包含一些将在我们的程序中使用的函数。
math.py:
def add(x, y):
return x + y
def multiply(x, y):
return x * ystr_utils.py:
def to_uppercase(s):
s = str(s)
return s.upper()
def reverse(s):
s = str(s)
return s[::-1]我们希望将这些模块添加到我们的软件包中。只需将这些文件复制到您希望存放这些模块的软件包目录即可。
$ ls
math.py str_utils.py utilities
$ mv math.py utilities
$ mv str_utils.py utilities/strings
$ tree
.
└── utilities
├── __init__.py
├── math.py
└── strings
├── __init__.py
└── str_utils.py
3 directories, 3 files
$
3. 从包中导入模块
在包内导入 Python 模块的语法是:
import package.sub_package1.sub_package2.module
import package.sub_package1.sub_package2.module as modulePython 使用sys.path变量来查找包和模块。当前目录是该sys.path变量的一部分。因此,我们将把 Python 脚本放在python-packages目录中。否则,我们需要将包的位置添加到该sys.path变量中。
$ cat my_script.py
import sys
print(sys.path)
$ python3.7 my_script.py
['/Users/pankaj/Desktop/python-packages', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages']
$以下是 my_script.py 中的代码,用于访问包中的模块并调用它们的函数。
import utilities.math as math
import utilities.strings.str_utils as str_utils
print(math.add(10, 20))
print(str_utils.reverse("ABC"))
我们还可以使用以下语法导入模块:
from package.sub_package1.sub_package2 import module以下是更新后的示例,用于在我们的程序中访问“math”和“str_utils”模块。
from utilities import math
from utilities.strings import str_utils
print(math.add(10, 20))
print(str_utils.reverse("ABC"))
4. 从包中导入 *
我们可以使用以下语法从包中导入每个模块。
from package.sub_package1.sub_package2 import *在这种情况下,Python 会在 sub_package2 中搜索包、模块和函数。这可能会导致导入一些你不想导入的内容,从而产生副作用。此外,这个过程非常耗时。
我们可以通过在 init.py 文件中创建__all__变量来定义要导入的模块列表。
utilities/init.py:
print('utilities package initialized')
__all__ = ['math']utilities/strings/init.py:
print('utilities.strings package initialized')
__all__ = ['str_utils']更新后的 my_script.py 代码如下:
from utilities import *
from utilities.strings import *
print(math.add(10, 20))
print(str_utils.reverse("ABC"))输出:
$ python3.7 my_script.py
utilities package initialized
utilities.strings package initialized
30
CBA
请注意,在初始化和导入包时,init.py 中的 Python 代码会首先执行。
如何将软件包添加到系统路径
始终依赖目录层级结构来导入包模块是不可行的。我们可以将自定义包添加到 sys.path 变量中,然后在任何脚本中导入它们。
import sys
sys.path.append("/Users/pankaj/Desktop/python-packages")
print(sys.path)
import utilities.math as math
print(math.add(1, 2))输出:
$ python3.7 my_script.py
['/Users/pankaj', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages', '/Users/pankaj/Desktop/python-packages']
utilities package initialized
3
$结论
Python 中的包机制允许我们将应用程序模块和脚本划分成逻辑模块。这使得我们的代码库保持整洁,易于维护。