Python - 模块



Python 模块

Python 中 module 的概念进一步增强了模块化。您可以一起定义多个相关函数并加载所需的函数。模块是包含函数、类、变量、常量或任何其他 Python 对象的定义的文件。此文件的内容可供任何其他程序使用。Python 具有用于此目的的 import 关键字。

函数是一组有组织的、可重用的代码,用于执行单个相关操作。Functions 为您的应用程序提供更好的模块化和高度的代码重用。

Python 模块示例


import math
print ("Square root of 100:", math.sqrt(100))

它将产生以下输出 -

Square root of 100: 10.0

Python 内置模块

Python 的标准库捆绑了大量模块。它们称为内置模块。这些内置模块中的大多数都是用 C 编写的(因为 Python 的参考实现是用 C 编写的),并预编译到库中。这些模块包含有用的功能,如系统特定的操作系统管理、磁盘 IO、网络等。

以下是内置模块的选择列表 -

名称 描述

os

此模块为许多操作系统功能提供了统一的接口。

string

该模块包含许多用于字符串处理的函数

re

该模块提供了一组强大的正则表达式工具。正则表达式 (RegEx),允许对字符串中的模式进行强大的字符串搜索和匹配

math

该模块实现了浮点数的许多数学运算。这些函数通常是平台 C 库函数的精简包装器。

cmath

该模块包含许多复数的数学运算。

datetime

该模块提供了处理一天内的日期和时间的函数。它包装了 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 的单元测试框架。

random

生成伪随机数

sys

提供与解释器强交互的函数。

requests

它通过提供用户友好的界面来发送和处理响应,从而简化 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")

从命令终端运行此脚本

Hi Harish! How are you?

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))

它将产生以下输出 -

sum:30
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))

它将产生以下输出 -

sum: 30
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 -

set PYTHONPATH = c:\python20\lib;

这是来自 UNIX 系统的典型 PYTHONPATH -

set PYTHONPATH = /usr/local/lib/python

命名空间和范围

变量是映射到对象的名称(标识符)。命名空间是变量名称 (键) 及其相应对象 (值) 的字典。

  • 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__)

它将产生以下输出 -

__file__ attribute: C:\math\examples\mymodule.py
__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__)

在命令终端中运行此命令 -

__name__ attribute within a script: __main__

此属性允许将 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() 函数在定义它的同一脚本中被调用。

sum: 30

现在让我们在另一个脚本 example.py 中导入此函数。


import mymodule
print ("sum:",mymodule.sum(10,20))

它将产生以下输出 -

sum: 30
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 输出只出现一次。

sum: 30

dir( ) 函数

dir() 内置函数返回一个排序的字符串列表,其中包含模块定义的名称。

该列表包含模块中定义的所有模块、变量和函数的名称。下面是一个简单的示例 -


# Import built-in module math
import math

content = dir(math)
print (content)

执行上述代码时,它会产生以下结果 -

['__doc__', '__file__', '__name__', 'acos', 'asin', 'atan',
'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 提示符调用其函数,如 -

>>> import test
>>> 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() 函数重新加载它。

>>> import imp
>>> 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 Pots Phone
I'm 3G Phone
I'm ISDN Phone

在上面的示例中,我们以每个文件中的单个函数为例,但您可以在文件中保留多个函数。您还可以在这些文件中定义不同的 Python 类,然后可以从这些类中创建包。