Python 模块
在本教程中,我们将解释如何构建和导入自定义的Python模块。此外,我们可以通过各种方法导入或集成Python的内置模块。
什么是模块化编程
模块化编程是将单个复杂的编码任务分割成多个简单、易于管理的子任务的实践。我们将这些子任务称为模块。因此,我们可以通过组装不同的模块来构建一个更大的程序,这些模块就像构建块一样工作。
在大型应用程序中对代码进行模块化有很多好处。
简化: 模块通常只集中在一小部分较小的问题上,而不是整个任务。如果我们只集中于一个模块,我们将有一个更容易管理的设计问题。现在程序开发更简单,也更不易出错。
灵活性: 模块经常被用来在不同的问题领域之间建立概念上的分离。如果模块的构建方式减少了相互关联,那么对一个模块的更改就不太可能影响程序的其他部分。(我们甚至可能会在不熟悉该程序的情况下编辑一个模块。)这增加了许多开发人员能够合作处理大型项目的可能性。
可重用性: 在特定模块中创建的函数可以轻松地被分配到任务的不同部分中(通过适当建立的api)。因此,不再需要重复的代码。
范围: 模块通常声明了一个独立的命名空间,以防止程序的不同部分发生标识符冲突。
在Python中,通过使用函数、模块和包来鼓励对代码进行模块化。
Python中的模块是什么
一个包含用Python编写的函数定义和各种语句的文档被称为Python模块。
在Python中,我们可以通过以下3种方式之一定义一个模块:
- Python本身允许创建模块。
- 类似于re(正则表达式)模块,模块可以主要用C编程语言编写,然后在运行时动态插入。
- 内置模块,如itertools模块,在解释器中已经默认包含。
一个模块是一个包含Python代码、函数定义、语句或类的文件。一个example_module.py文件是一个我们将创建的模块,它的名字是example_module。
我们使用模块将复杂的程序分割成更小、更易于理解的模块。模块还允许代码的重用。
我们可以将最常用的函数定义在一个单独的模块中,然后通过导入整个模块来避免将它们重复到多个应用程序中。
让我们来构建一个模块。在输入以下内容后,将文件保存为example_module.py。
示例:
# Here, we are creating a simple Python program to show how to create a module.
# defining a function in the module to reuse it
def square( number ):
# here, the above function will square the number passed as the input
result = number ** 2
return result # here, we are returning the result of the function
这里有一个名为example_module的模块,其中包含函数square()的定义。该函数返回给定数字的平方。
如何在Python中导入模块
在Python中,我们可以从一个模块中导入函数到我们的程序中,或者说导入到另一个模块中。
为了实现这一点,我们使用import Python关键字。在Python窗口中,我们在import关键字后添加要导入的模块的名称。我们将导入我们之前定义的模块example_module。
语法:
import example_module
我们在example_module中定义的函数不会立即被导入到当前程序中。这里只是导入了模块的名称,即example_module。
我们可以使用点操作符来使用模块名来使用这些函数。例如:
示例:
# here, we are calling the module square method and passing the value 4
result = example_module.square( 4 )
print("By using the module square of number is: ", result )
输出:
By using the module square of number is: 16
有几个标准模块适用于Python。完整的Python标准模块列表可供查阅。可以使用help命令查看该列表。
与我们导入用户定义模块的方式类似,我们可以使用import语句导入其他标准模块。
导入模块可以使用多种方式。以下是它们的列表。
Python导入语句
使用import Python关键字和点运算符,我们可以导入一个标准模块,并可以访问其中定义的函数。以下是一个示例。
代码
# Here, we are creating a simple Python program to show how to import a standard module
# Here, we are import the math module which is a standard module
import math
print( "The value of euler's number is", math.e )
# here, we are printing the euler's number from the math module
输出:
The value of euler's number is 2.718281828459045
导入和重命名
在导入模块时,我们也可以更改其名称。这里有一个示例来展示。
代码
# Here, we are creating a simple Python program to show how to import a module and rename it
# Here, we are import the math module and give a different name to it
import math as mt # here, we are importing the math module as mt
print( "The value of euler's number is", mt.e )
# here, we are printing the euler's number from the math module
输出:
The value of euler's number is 2.718281828459045
该程序中,math模块现在被命名为mt。在某些情况下,这可能有助于我们更快地输入模块名称较长的情况。
请注意,现在我们程序的作用域不包括math这个术语。因此,mt.pi是模块的正确实现,而math.pi是无效的。
Python的from…import语句
我们可以从一个模块中导入特定的名称,而不是将整个模块导入。下面是一个例子。
代码
# Here, we are creating a simple Python program to show how to import specific
# objects from a module
# Here, we are import euler's number from the math module using the from keyword
from math import e
# here, the e value represents the euler's number
print( "The value of euler's number is", e )
输出:
The value of euler's number is 2.718281828459045
只有来自math模块的e常数在这种情况下被导入。
我们避免在这些情况下使用点(.)运算符。如下,我们可以同时导入多个属性:
代码
# Here, we are creating a simple Python program to show how to import multiple
# objects from a module
from math import e, tau
print( "The value of tau constant is: ", tau )
print( "The value of the euler's number is: ", e )
输出:
The value of tau constant is: 6.283185307179586
The value of the euler's number is: 2.718281828459045
从import *
语句中导入所有名称
要在当前命名空间中从模块中导入所有对象,请使用*
符号和from和import关键字。
语法:
from name_of_module import *
使用符号*
有利有弊。除非我们确切地了解模块的特定要求,否则不建议使用*
;否则,请使用。
以下是同样的示例。
代码
# Here, we are importing the complete math module using *
from math import *
# Here, we are accessing functions of math module without using the dot operator
print( "Calculating square root: ", sqrt(25) )
# here, we are getting the sqrt method and finding the square root of 25
print( "Calculating tangent of an angle: ", tan(pi/6) )
# here pi is also imported from the math module
输出:
Calculating square root: 5.0
Calculating tangent of an angle: 0.5773502691896257
模块的路径定位
在Python程序中导入模块时,解释器会在许多地方进行搜索。如果内置模块不存在,将会搜索多个目录。可以使用sys.path来访问目录列表。Python解释器按照以下方式搜索模块:
首先,在当前工作目录中查找模块。如果在当前目录中找不到模块,则Python会在设置的shell参数PYTHONPATH所指定的每个目录中进行搜索。PYTHONPATH是一个环境变量,由一系列文件夹组成。如果在这些目录中仍然找不到模块,则Python会查找在下载Python时设置的与安装相关的一系列文件夹。
下面是一个打印路径的示例:
代码
# Here, we are importing the sys module
import sys
# Here, we are printing the path using sys.path
print("Path of the sys module in the system is:", sys.path)
输出:
Path of the sys module in the system is:
['/home/pyodide', '/home/pyodide/lib/Python310.zip', '/lib/Python3.10', '/lib/Python3.10/lib-dynload', '', '/lib/Python3.10/site-packages']
dir()内置函数
我们可以使用dir()方法来识别模块中声明的名称。
例如,我们在标准模块str中有以下名称。为了打印这些名称,我们将以以下方式使用dir()方法:
Code
# Here, we are creating a simple Python program to print the directory of a module
print( "List of functions:\n ", dir( str ), end=", " )
输出:
List of functions:
['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'removeprefix', 'removesuffix', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
命名空间和作用域
对象由称为变量的名称或标识符表示。命名空间是一个包含变量名称(键)和与之相关的对象(值)的字典。
Python语句可以访问局部和全局命名空间变量。当具有相同名称的变量是局部和全局变量时,局部变量起到全局变量的作用。每个函数都有一个单独的局部命名空间。类方法的作用域规则与普通函数相同。Python根据合理的预测确定参数是局部变量还是全局变量。在方法中分配了值的任何变量都被视为局部变量。
因此,在函数中为全局变量提供值之前,我们必须使用全局语句。通过global Var_Name的语句,Python被告知Var_Name是一个全局变量。Python停止在局部命名空间中查找该变量。
例如,在全局命名空间中声明变量Number。由于我们在函数中为Number提供了一个值,Python将Number视为局部变量。如果我们在声明全局变量之前或之后尝试访问局部变量的值,将导致UnboundLocalError错误。
代码
Number = 204
def AddNumber(): # here, we are defining a function with the name Add Number
# Here, we are accessing the global namespace
global Number
Number = Number + 200
print("The number is:", Number)
# here, we are printing the number after performing the addition
AddNumber() # here, we are calling the function
print("The number is:", Number)
输出:
The number is: 204
The number is: 404