Python 模块
Python 中 module 的概念进一步增强了模块化。您可以一起定义多个相关函数并加载所需的函数。模块是包含函数、类、变量、常量或任何其他 Python 对象的定义的文件。此文件的内容可供任何其他程序使用。Python 具有用于此目的的 import 关键字。
Python 模块示例
import math
print ("Square root of 100:", math.sqrt(100))
它将产生以下输出 -
Python 内置模块
Python 的标准库捆绑了大量模块。它们称为内置模块。这些内置模块中的大多数都是用 C 编写的(因为 Python 的参考实现是用 C 编写的),并预编译到库中。这些模块包含有用的功能,如系统特定的操作系统管理、磁盘 IO、网络等。
以下是内置模块的选择列表 -
名称 | 描述 |
---|---|
此模块为许多操作系统功能提供了统一的接口。 |
|
该模块包含许多用于字符串处理的函数 |
|
该模块提供了一组强大的正则表达式工具。正则表达式 (RegEx),允许对字符串中的模式进行强大的字符串搜索和匹配 |
|
该模块实现了浮点数的许多数学运算。这些函数通常是平台 C 库函数的精简包装器。 |
|
该模块包含许多复数的数学运算。 |
|
该模块提供了处理一天内的日期和时间的函数。它包装了 C 运行时库。 |
|
gc |
该模块为内置垃圾回收器提供了一个接口。 |
asyncio |
此模块定义异步处理所需的功能 |
Collections |
此模块提供高级 Container 数据类型。 |
Functools |
该模块对可调用对象具有 Higher-order functions 和 operations 。在函数式编程中很有用 |
operator |
与标准运算符对应的函数。 |
pickle |
将 Python 对象转换为字节流,反之亦然。 |
socket |
低级网络接口。 |
sqlite3 |
使用 SQLite 3.x 的 DB-API 2.0 实现。 |
statistics |
数理统计函数 |
typing |
支持类型提示 |
venv |
创建虚拟环境。 |
json |
对 JSON 格式进行编码和解码。 |
wsgiref |
WSGI 实用程序和参考实现。 |
unittest |
Python 的单元测试框架。 |
生成伪随机数 |
|
提供与解释器强交互的函数。 |
|
它通过提供用户友好的界面来发送和处理响应,从而简化 HTTP 请求。 |
Python 用户定义模块
任何带有 .py 扩展名并包含 Python 代码的文本文件基本上都是一个模块。它可以包含一个或多个函数、变量、常量以及类的定义。模块中的任何 Python 对象都可以通过 import 语句提供给解释器会话或其他 Python 脚本。模块还可以包含可运行的代码。
创建 Python 模块
创建模块只不过是在任何编辑器的帮助下保存 Python 代码。让我们将以下代码保存为 mymodule.py
def SayHello(name):
print ("Hi {}! How are you?".format(name))
return
您现在可以在当前的 Python 终端中导入 mymodule。
>>> import mymodule
>>> mymodule.SayHello("Harish")
Hi Harish! How are you?
您还可以在另一个 Python 脚本中导入一个模块。将以下代码另存为 example.py
import mymodule
mymodule.SayHello("Harish")
从命令终端运行此脚本
import 语句
在 Python 中,提供了 import 关键字以从一个模块加载 Python 对象。对象可以是函数、类、变量等。如果一个模块包含多个定义,则所有定义都将加载到命名空间中。
让我们将以下具有三个函数的代码保存为 mymodule.py。
def sum(x,y):
return x+y
def average(x,y):
return (x+y)/2
def power(x,y):
return x**y
import mymodule 语句将该模块中的所有函数加载到当前命名空间中。导入的模块中的每个函数都是此模块对象的一个属性。
>>> dir(mymodule)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'average', 'power', 'sum']
要调用任何函数,请使用 module 对象的引用。例如,mymodule.sum()。
import mymodule
print ("sum:",mymodule.sum(10,20))
print ("average:",mymodule.average(10,20))
print ("power:",mymodule.power(10, 2))
它将产生以下输出 -
average:15.0
power:100
从 ...import 语句
import 语句将加载当前命名空间中模块的所有资源。可以使用此语法从模块导入特定对象。例如 -
在 mymodule 的三个函数中,只有两个在以下可执行脚本中导入 example.py
from mymodule import sum, average
print ("sum:",sum(10,20))
print ("average:",average(10,20))
它将产生以下输出 -
average: 15.0
请注意,不需要通过为其模块的 name 添加前缀来调用 function。
的 from...import * 声明
还可以使用以下 import 语句将模块中的所有名称导入到当前命名空间中 -
from modname import *
这提供了一种将模块中的所有项导入到当前命名空间的简单方法;但是,应谨慎使用此语句。
进口 ...as 语句
您可以为导入的模块分配别名。
from modulename as alias
调用时,别名应作为函数的前缀。
请看下面的例子 -
import mymodule as x
print ("sum:",x.sum(10,20))
print ("average:", x.average(10,20))
print ("power:", x.power(10, 2))
查找模块
导入模块时,Python 解释器会按以下顺序搜索该模块 -
- 当前目录。
- 如果未找到该模块,则 Python 将在 shell 变量 PYTHONPATH 中搜索每个目录。
- 如果所有其他方法都失败,Python 将检查默认路径。在 UNIX 上,此默认路径通常为 /usr/local/lib/python/。
模块搜索路径作为 sys.path 变量存储在系统模块 sys 中。sys.path 变量包含当前目录、PYTHONPATH 和依赖于安装的默认值。
PYTHONPATH 变量
PYTHONPATH 是一个环境变量,由目录列表组成。PYTHONPATH 的语法与 shell 变量 PATH 的语法相同。
这是 Windows 系统中的典型 PYTHONPATH -
这是来自 UNIX 系统的典型 PYTHONPATH -
命名空间和范围
变量是映射到对象的名称(标识符)。命名空间是变量名称 (键) 及其相应对象 (值) 的字典。
- Python 语句可以访问本地命名空间和全局命名空间中的变量。如果 local 变量和 global 变量具有相同的名称,则 local 变量会隐藏全局变量。
- 每个函数都有自己的本地命名空间。类方法遵循与普通函数相同的范围规则。
- Python 对变量是局部变量还是全局变量进行有根据的猜测。它假定在函数中分配值的任何变量都是局部变量。
- 为了将值分配给函数中的全局变量,您必须首先使用 global 语句。
- 语句 global VarName 告诉 Python VarName 是一个全局变量。Python 停止在本地命名空间中搜索变量。
例如,我们在全局命名空间中定义一个变量 Money。在函数 Money 中,我们为 Money 分配一个值,因此 Python 将 Money 作为局部变量。但是,我们在设置局部变量 Money 之前访问了它的值,因此结果是 UnboundLocalError。取消 global 语句的注释可解决此问题。
Money = 2000
def AddMoney():
# Uncomment the following line to fix the code:
# global Money
Money = Money + 1
print (Money)
AddMoney()
print (Money)
模块属性
在 Python 中,模块是 module 类的对象,因此它由 attributes 来表征。
以下是模块属性 -
- __file__ 返回模块的物理名称。
- __package__ 返回模块所属的包。
- __doc__ 返回模块顶部的文档字符串(如果有)
- __dict__ 返回模块的整个范围
- __name__ 返回模块的名称
假设以下代码保存为 mymodule.py
"The docstring of mymodule"
def sum(x,y):
return x+y
def average(x,y):
return (x+y)/2
def power(x,y):
return x**y
让我们通过在以下脚本中导入 mymodule 来检查 mymodule 的属性 -
import mymodule
print ("__file__ attribute:", mymodule.__file__)
print ("__doc__ attribute:", mymodule.__doc__)
print ("__name__ attribute:", mymodule.__name__)
它将产生以下输出 -
__doc__ attribute: The docstring of mymodule
__name__ attribute: mymodule
__name__属性
Python 模块的 __name__ 属性具有重要意义。让我们更详细地探讨一下。
在交互式 shell 中,__name__ 属性 返回 '__main__'
>>> __name__
'__main__'
如果在解释器会话中导入任何模块,它将返回模块的名称作为该模块的 __name__ 属性。
>>> import math
>>> math.__name__
'math'
在 Python 脚本中,__name__ 属性返回 '__main__'
#example.py
print ("__name__ attribute within a script:", __name__)
在命令终端中运行此命令 -
此属性允许将 Python 脚本用作可执行文件或模块。与 C++、Java、C# 等不同,在 Python 中,没有 main() 函数的概念。带有 .py 扩展的 Python 程序脚本可以包含函数定义以及可执行语句。
保存 mymodule.py 并使用以下代码 -
"The docstring of mymodule"
def sum(x,y):
return x+y
print ("sum:",sum(10,20))
你可以看到 sum() 函数在定义它的同一脚本中被调用。
现在让我们在另一个脚本 example.py 中导入此函数。
import mymodule
print ("sum:",mymodule.sum(10,20))
它将产生以下输出 -
sum: 30
输出 “sum:30” 出现两次。一次是在导入 mymodule module 时。导入的 module 中的可执行语句也会运行。第二个输出来自调用脚本,即 example.py 程序。
我们希望发生的是,当一个模块被导入时,只应该导入函数,它的可执行语句不应该运行。这可以通过检查 __name__ 的值来完成。如果为 __main__,则表示它正在运行且未导入。有条件地包含可执行语句,如函数调用。
在 mymodule.py 中添加 if 语句,如下所示 -
"The docstring of mymodule"
def sum(x,y):
return x+y
if __name__ == "__main__":
print ("sum:",sum(10,20))
现在,如果您运行 example.py 程序,您会发现 sum:30 输出只出现一次。
dir( ) 函数
dir() 内置函数返回一个排序的字符串列表,其中包含模块定义的名称。
该列表包含模块中定义的所有模块、变量和函数的名称。下面是一个简单的示例 -
# Import built-in module math
import math
content = dir(math)
print (content)
执行上述代码时,它会产生以下结果 -
'atan2', 'ceil', 'cos', 'cosh', 'degrees', 'e', 'exp',
'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
'log10', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh',
'sqrt', 'tan', 'tanh']
reload() 函数
有时您可能需要重新加载模块,尤其是在使用 Python 的交互式解释器会话时。
假设我们有一个具有以下功能的测试模块 (test.py) -
def SayHello(name):
print ("Hi {}! How are you?".format(name))
return
我们可以导入模块并从 Python 提示符调用其函数,如 -
>>> test.SayHello("Deepak")
Hi Deepak! How are you?
但是,假设您需要修改 SayHello() 函数,例如 -
def SayHello(name, course):
print ("Hi {}! How are you?".format(name))
print ("Welcome to {} Tutorial by qikepu".format(course))
return
即使您编辑并保存 test.py 文件,内存中加载的函数也不会更新。你需要在 imp 模块中使用 reload() 函数重新加载它。
>>> imp.reload(test)
>>> test.SayHello("Deepak", "Python")
Hi Deepak! How are you?
Welcome to Python Tutorial by qikepu
Python 中的包
包是一个分层文件目录结构,它定义了一个 Python 应用程序环境,该环境由模块、子包和子子包等组成。
考虑 Phone 目录中 Pots.py 可用的文件。此文件包含以下源代码行 -
def Pots():
print "I'm Pots Phone"
类似地,我们还有另外两个具有不同功能的文件,它们的名称与上面相同 -
- 具有函数 Isdn() 的电话/Isdn.py 文件
- 具有函数 G3() 的 Phone/G3.py 文件
现在,在 Phone 目录中再创建一个文件__init__.py -
- 电话/__init__.py
要在导入 Phone 时使所有函数都可用,您需要在 __init__.py 中放置显式 import 语句,如下所示 -
from Pots import Pots
from Isdn import Isdn
from G3 import G3
将这些线路添加到 __init__.py 后,在导入 Phone 软件包时,所有这些类都可用。
# Now import your Phone Package.
import Phone
Phone.Pots()
Phone.Isdn()
Phone.G3()
执行上述代码时,它会产生以下结果 -
I'm 3G Phone
I'm ISDN Phone
在上面的示例中,我们以每个文件中的单个函数为例,但您可以在文件中保留多个函数。您还可以在这些文件中定义不同的 Python 类,然后可以从这些类中创建包。