176 lines
9.5 KiB
Markdown
176 lines
9.5 KiB
Markdown
|
|
# Python 模块:捆绑代码并从其他文件导入它
|
|||
|
|
|
|||
|
|
> 原文:[https://python.land/project-structure/python-modules](https://python.land/project-structure/python-modules)
|
|||
|
|
|
|||
|
|
Python *import* 语句允许我们导入一个 Python 模块。反过来,Python 模块帮助我们组织和重用代码。在本文中,您将了解:
|
|||
|
|
|
|||
|
|
* 如何创建模块和组织代码
|
|||
|
|
* Python import 语句允许我们导入(部分)模块
|
|||
|
|
* 模块方面的一些最佳实践
|
|||
|
|
* 如何创建可运行模块
|
|||
|
|
|
|||
|
|
在后续文章中,您将学习如何在 [Python 包](https://python.land/project-structure/python-packages)中捆绑模块。
|
|||
|
|
|
|||
|
|
目录
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
* [什么是模块?](#What_is_a_module "What is a module?")
|
|||
|
|
* [Python 导入](#Python_import "Python import")
|
|||
|
|
* [有效的 Python 模块名称](#Valid_Python_module_names "Valid Python module names")
|
|||
|
|
* [如何创建可运行的 Python 模块](#How_to_create_runnable_Python_modules "How to create runnable Python modules")
|
|||
|
|
* [类对模块](#Classes_versus_modules "Classes versus modules")
|
|||
|
|
* [更多资源](#Further_resources "Further resources")
|
|||
|
|
* [结论](#Conclusion "Conclusion")
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
## 什么是模块?
|
|||
|
|
|
|||
|
|
如果你创建一个单独的 Python 文件来执行一些任务,那就叫做脚本。如果你创建一个 Python 文件来存储[函数](https://python.land/introduction-to-python/functions)、[类](https://python.land/objects-and-classes)和其他定义,那就叫做模块。我们通过使用 Python `import`语句从模块中导入来使用模块。
|
|||
|
|
|
|||
|
|
所以模块是一个包含 Python 代码的文件,以`.py`扩展名结尾。换句话说:任何 Python 文件也是一个模块。模块的名称与文件名相同,不包括扩展名。例如,如果您创建了一个名为`mymodule.py`的文件,那么您的模块的名称就是`mymodule`。
|
|||
|
|
|
|||
|
|
### 为什么需要 Python 模块?
|
|||
|
|
|
|||
|
|
模块有很多优点:
|
|||
|
|
|
|||
|
|
* 它们允许我们组织代码。例如,您可以将所有的[函数](https://python.land/introduction-to-python/functions)和与数学相关的数据存储在一个名为`math.py`的模块中。这正是 Python 在数学模块中所做的!
|
|||
|
|
* 我们可以更容易地重用代码。我们现在可以使用模块,而不是将相同的函数从一个项目复制到下一个项目。如果我们适当地打包模块,我们甚至可以在 Python 包索引上与他人共享它。
|
|||
|
|
|
|||
|
|
## Python 导入
|
|||
|
|
|
|||
|
|
您可以使用 Python 的 import 关键字导入 Python 模块。我们通常将模块导入放在脚本的顶部,但我们不一定要这样做。例如,有时您希望动态地决定是否需要导入一个模块,尤其是当该模块占用大量内存或其他资源时。
|
|||
|
|
|
|||
|
|
### 创建模块
|
|||
|
|
|
|||
|
|
让我们创建一个名为`mymodule.py`的简单模块。它包含的所有功能如下:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
def my_function():
|
|||
|
|
print('Hello world!')
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
我们可以在另一个脚本中导入这个模块,但是您必须确保这两个文件在同一个目录中。要导入该模块,请使用以下命令:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
import mymodule
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这将导入整个模块,并以名称`mymodule`提供给程序的其他部分。使用`import`导入模块后,我们可以使用以下命令来使用该功能:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
mymodule.my_function()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
要了解这一点,您可以运行并使用下面的代码片段:
|
|||
|
|
|
|||
|
|
[https://crumb.sh/embed/EaNTcACpjwg](https://crumb.sh/embed/EaNTcACpjwg)
|
|||
|
|
|
|||
|
|
Python 导入并使用模块
|
|||
|
|
|
|||
|
|
### 导入 Python 模块的特定部分
|
|||
|
|
|
|||
|
|
我们还可以导入模块的特定部分,比如函数、[变量](https://python.land/introduction-to-python/variable)或[类](https://python.land/objects-and-classes)。为此,请使用以下语法:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
from mymodule import my_function
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
现在,`my_funcion`函数在名称为`my_function`下对程序的其余部分可用,就好像它是在文件本身内部定义的一样。所以我们可以这样使用它:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
my_function()
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
类似地,我们可以从一个 Python 模块中导入多个元素。为此,请使用以下语法:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
from mymodule import my_function, my_variable
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
什么时候做什么由你决定。有时候,你经常需要一个函数,以至于每次引用整个模块看起来都很混乱。其他时候,最好导入模块名,因为您需要来自同一个模块的许多不同的函数。另一个需要考虑的问题是,当你使用完整的模块名来引用一个特定的函数、变量或类时,你的代码读者会更清楚。
|
|||
|
|
|
|||
|
|
Thank you for reading my tutorials. I write these in my free time, and it requires a lot of time and effort. I use ads to keep writing these *free* articles, I hope you understand! **Support me by disabling your adblocker on my website** or, alternatively, **[buy me some coffee](https://www.buymeacoffee.com/pythonland)**. It's much appreciated and allows me to keep working on this site!
|
|||
|
|
|
|||
|
|
### 通配符导入(不好的做法)
|
|||
|
|
|
|||
|
|
当一个模块有很多您想要导入的函数和其他元素时,用一个特殊的`from module import *`语法一次性导入它们是很有诱惑力的。要从模块中导入所有内容,我们可以使用以下语法:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
from mymodule import *
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
在大多数情况下,您应该避免使用`*`语法,因为它会导致意想不到的结果,尤其是在使用您无法控制的第三方模块时。毕竟,你不知道第三方模块里面有什么,也不知道将来会有什么。通过导入所有内容,您用不必要的变量、类和函数“污染”了您的名称空间。您甚至可能会在没有注意到的情况下覆盖一些现有的定义。我的建议是:只导入特定的元素,以保持对名称空间的控制。
|
|||
|
|
|
|||
|
|
### 导入别名
|
|||
|
|
|
|||
|
|
有时 Python 模块名并不像你所希望的那样。也许你需要经常输入名字,比如在笔记本上。在这种情况下,您可以使用别名来缩短模块名称。例如,如果您有一个名为`mymodule.py`的模块,您可以将其作为`m`导入:
|
|||
|
|
|
|||
|
|
```py
|
|||
|
|
import mymodule as m
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
您将遇到的一些常见别名,尤其是在数据科学等领域,包括:
|
|||
|
|
|
|||
|
|
* `import numpy as np`
|
|||
|
|
* `import pandas as pd`
|
|||
|
|
* `import matplotlib.pyplot as plt`
|
|||
|
|
* `import seaborn as sns`
|
|||
|
|
|
|||
|
|
## 有效的 Python 模块名称
|
|||
|
|
|
|||
|
|
Python 模块的名称有一些限制,因为我们必须能够从 Python 代码中导入它们,并通过常规变量使用/引用它们。因此,有效的 Python 模块名与常规变量名有很多共同之处。
|
|||
|
|
|
|||
|
|
模块名称:
|
|||
|
|
|
|||
|
|
* 是一串字母、数字
|
|||
|
|
* 如果有助于可读性,可以包含下划线
|
|||
|
|
* 它不能以数字开头
|
|||
|
|
* 它不包含空格或其他空白字符
|
|||
|
|
* 不能包含以下任何附加字符:\ / : *?"< >|–
|
|||
|
|
|
|||
|
|
除了这些规则之外,在命名模块时还有一些最佳实践可以遵循。值得注意的是:
|
|||
|
|
|
|||
|
|
* 使用小写字母作为模块名。
|
|||
|
|
* 确保名称简短且具有描述性。
|
|||
|
|
|
|||
|
|
### 常见错误
|
|||
|
|
|
|||
|
|
一个常见的错误是为您的模块使用保留字或现有的模块名称。我自己也是这样做的,比如创建一个名为`http`的模块,而 Python 已经有了一个同名的模块。
|
|||
|
|
|
|||
|
|
难以调试错误的另一个常见原因是将模块命名为与目录相同的名称。
|
|||
|
|
|
|||
|
|
## 如何创建可运行的 Python 模块
|
|||
|
|
|
|||
|
|
在模块内部,您可以检测它是用作模块还是脚本。这是很有用的,因为它允许你既可以独立运行一个模块,也可以同时从其他代码中导入它。
|
|||
|
|
|
|||
|
|
### `If __name__ == '__main__'`检查
|
|||
|
|
|
|||
|
|
你可能以前见过它,你可能想知道它是做什么的。为什么 Python 程序员如此频繁地在他们的脚本中包含这种检查?它与模块以及将模块用作脚本有着千丝万缕的联系。
|
|||
|
|
|
|||
|
|
当我们导入一个模块时,它的名字(存储在变量`__name__`中)等于模块名。当一个脚本被执行时,它的名字总是被设置为字符串`__main__`。因此,如果我们检查这个名字,我们会发现我们是作为一个脚本运行,还是作为一个模块包含在某个地方。
|
|||
|
|
|
|||
|
|
我在下面的代码片段中创建了一个简单的模块来进行这种检查。因为我没有导入这个文件,而是直接运行它,所以脚本调用了欢迎函数,我们看到一些东西打印到了屏幕上。但是,当我们导入这个模块时,脚本不会调用 greeter 函数:
|
|||
|
|
|
|||
|
|
[https://crumb.sh/embed/4WGobwBXoWc](https://crumb.sh/embed/4WGobwBXoWc)
|
|||
|
|
|
|||
|
|
一个可运行的模块,检查它是被用作模块还是脚本
|
|||
|
|
|
|||
|
|
通过仅在“脚本模式”下运行时执行代码,我们有效地创建了既可以作为脚本又可以作为我们可以导入的模块的文件。
|
|||
|
|
|
|||
|
|
## 类对模块
|
|||
|
|
|
|||
|
|
你可能想知道模块和类相比怎么样。毕竟,它们都是功能性的集合。尽管有很大的不同,Python 有很好的理由同时拥有模块和类。
|
|||
|
|
|
|||
|
|
模块将相似的功能或相关的功能组合到一个地方。例如,一个模块可能包含类、函数和常量,我们用它们来连接特定类型的数据库。
|
|||
|
|
|
|||
|
|
一个类**为你的问题域**建模。它为一个或多个对象提供了蓝图。例如,student 类保存学生数据和处理该数据的相关函数。可以有许多学生,因此可以同时有许多学生对象。关于这方面的更多内容,请阅读关于[类和对象](https://python.land/objects-and-classes)的章节。
|
|||
|
|
|
|||
|
|
## 更多资源
|
|||
|
|
|
|||
|
|
python.org 页面列出了 [Python 标准库](https://docs.python.org/3/library/),很好地概述了内置模块。
|
|||
|
|
|
|||
|
|
## 结论
|
|||
|
|
|
|||
|
|
您已经学习了如何将代码捆绑到一个模块中,帮助您构建项目。在这个过程中,您的项目将变得更易于维护。模块只是拼图的一部分。在下一篇关于 [Python 包](https://python.land/project-structure/python-packages)的文章中,您将了解模块和包如何一起工作来进一步构建您的项目。
|