Python - 模块



Python 模块

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

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

Python 模块示例

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

这将产生以下输出

Square root of 100: 10.0

Python 内置模块

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

这是一个精选的内置模块列表:

序号 名称和简要说明

1

os

此模块为许多操作系统函数提供统一的接口。

2

string

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

3

re

此模块提供了一套强大的正则表达式功能。正则表达式 (RegEx) 允许对字符串中的模式进行强大的字符串搜索和匹配。

4

math

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

5

cmath

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

6

datetime

此模块提供处理日期和一天中的时间的函数。它包装了 C 运行时库。

7

gc

此模块提供与内置垃圾收集器的接口。

8

asyncio

此模块定义了异步处理所需的功能。

9

Collections

此模块提供高级容器数据类型。

10

functools

此模块具有高阶函数和对可调用对象的运算。在函数式编程中很有用。

11

operator

与标准运算符对应的函数。

12

pickle

将 Python 对象转换为字节流并返回。

13

socket

低级网络接口。

14

sqlite3

使用 SQLite 3.x 的 DB-API 2.0 实现。

15

statistics

数学统计函数

16

typing

对类型提示的支持

17

venv

创建虚拟环境。

18

json

编码和解码 JSON 格式。

19

wsgiref

WSGI 实用程序和参考实现。

20

unittest

Python 的单元测试框架。

21

random

生成伪随机数。

22

sys

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

23

requests

它通过提供一个用户友好的接口来发送和处理响应来简化 HTTP 请求。

Python 用户自定义模块

任何带有.py扩展名并包含 Python 代码的文本文件基本上都是一个模块。它可以包含一个或多个函数、变量、常量以及类的定义。可以通过 import 语句将模块中的任何 Python 对象提供给解释器会话或另一个 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']

要调用任何函数,请使用模块对象的引用。例如,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

from ... 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

请注意,不需要在函数名前添加模块名称来调用函数。

from...import * 语句

也可以使用以下import语句将模块中的所有名称导入到当前命名空间中:

from modname import *

这提供了一种简单的方法将模块中的所有项导入到当前命名空间中;但是,应谨慎使用此语句。

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中,作为sys.path变量。sys.path变量包含当前目录、PYTHONPATH和安装相关的默认值。

PYTHONPATH 变量

PYTHONPATH是一个环境变量,由目录列表组成。PYTHONPATH的语法与shell变量PATH的语法相同。

这是一个来自Windows系统的典型PYTHONPATH:

set PYTHONPATH = c:\python20\lib;

这是一个来自UNIX系统的典型PYTHONPATH:

set PYTHONPATH = /usr/local/lib/python

命名空间和作用域

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

  • Python语句可以访问局部命名空间全局命名空间中的变量。如果局部变量和全局变量具有相同的名称,则局部变量将隐藏全局变量。

  • 每个函数都有其自己的局部命名空间。类方法遵循与普通函数相同的作用域规则。

  • Python会根据情况猜测变量是局部变量还是全局变量。它假设在函数中赋值的任何变量都是局部变量。

  • 为了在函数内为全局变量赋值,必须首先使用global语句。

  • 语句global VarName告诉Python VarName是一个全局变量。Python将停止搜索局部命名空间中的变量。

示例

例如,我们在全局命名空间中定义了一个变量Money。在函数Money中,我们为Money赋值,因此Python将其视为局部变量。但是,我们在设置局部变量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类的对象,因此它具有属性。

以下是模块属性:

  • __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的属性:

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模块时。导入模块中的可执行语句也会运行。第二次输出来自调用脚本,即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模块(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 TutorialsPoint".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 TutorialsPoint

Python中的包

包是一个分层文件目录结构,它定义了一个由模块、子包和子子包等组成的单个Python应用程序环境。

考虑一下Phone目录中可用的文件Pots.py。此文件包含以下源代码行:

def Pots():
   print "I'm Pots Phone"

同样,我们还有另外两个文件,它们具有与上述相同的函数名称:

  • Phone/Isdn.py文件包含函数Isdn()

  • Phone/G3.py文件包含函数G3()

现在,在Phone目录中创建另一个文件__init__.py:

  • Phone/__init__.py

为了在导入Phone时使所有函数都可用,您需要在__init__.py中添加显式导入语句,如下所示:

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类,然后您可以根据这些类创建包。

广告