Python 简明教程
Python - Modules
Python Modules
Python Built-in Modules
Python 的标准库附带了大量模块。它们被称为内置模块。大多数这些内置模块是用 C 编写的(因为 Python 的参考实现是 C),并且预编译到库中。这些模块封装了有用的功能,如特定于系统操作系统的管理、磁盘 IO、网络等。
以下是内置模块的选择列表 -
Python User-defined Modules
带有 .py 扩展名的任何文本文件和包含 Python 代码的文本文件基本上都是一个模块。它可以包含一个或多个函数、变量、常量的定义以及类。来自模块的任何 Python 对象都可以通过 import 语句在解释器会话或另一个 Python 脚本中使用。模块还可以包含可运行的代码。
Creating a Python Module
创建模块只不过是用任何编辑器的帮助保存 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?
The import Statement
在 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))
它将生成以下 output −
sum:30
average:15.0
power:100
The from … import Statement
import 语句将会加载模块的所有资源到当前名称空间中。可以通过使用此语法从模块中导入特定对象。例如 −
在 mymodule 中的三个函数中,只有两个被导入到以下可执行脚本 example.py 中
from mymodule import sum, average
print ("sum:",sum(10,20))
print ("average:",average(10,20))
它将生成如下输出:
sum: 30
average: 15.0
注意,不需要通过给函数加上其模块名前缀来调用它。
The from…import * Statement
还可以通过使用以下 import 语句将模块中的所有名称导入到当前名称空间中 −
from modname import *
这提供了一种将模块中的所有项导入当前名称空间的简单方法;但是,此语句应该谨慎使用。
The import … as Statement
您可以为导入的模块指定一个别名。
from modulename as alias
调用时 alias 应该加在函数前面。
看看以下 example −
import mymodule as x
print ("sum:",x.sum(10,20))
print ("average:", x.average(10,20))
print ("power:", x.power(10, 2))
Locating Modules
当你导入模块时,Python 解释器按以下顺序搜索模块 −
-
The current directory.
-
如果找不到模块,Python 接着搜索 shell 变量 PYTHONPATH 中的每个目录。
-
如果仍失败,Python 会检查默认路径。在 UNIX 中,此默认路径通常为 /usr/local/lib/python/。
模块搜索路径存储在系统模块 sys 中,作为 sys.path 变量。sys.path 变量包含当前目录、PYTHONPATH 和与安装相关的默认值。
The PYTHONPATH Variable
PYTHONPATH 是一个环境变量,包括目录列表。PYTHONPATH 的语法与 shell 变量 PATH 相同。
这是 Windows 系统中的典型 PYTHONPATH −
set PYTHONPATH = c:\python20\lib;
这是 UNIX 系统中的典型 PYTHONPATH −
set PYTHONPATH = /usr/local/lib/python
Namespaces and Scoping
变量是映射到对象的名称(标识符)。命名空间是由变量名称(键)及其对应对象(值)组成的字典。
-
Python 语句可以在局部命名空间和全局命名空间中访问变量。如果一个局部变量和一个全局变量具有相同的名称,则局部变量会隐藏全局变量。
-
每个函数都有自己的局部命名空间。类方法遵循与普通函数相同的范围规则。
-
Python 对变量是局部变量还是全局变量做出明智的猜测。它假定在函数中赋值的任何变量都是局部变量。
-
为了在函数中为全局变量赋值,你必须首先使用 global 语句。
-
语句 global VarName 告诉 Python VarName 是一个全局变量。Python 会停止在局部命名空间中搜索该变量。
Example
例如,我们在全局命名空间中定义了一个变量 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)
Module Attributes
在 Python 中,模块是模块类的一个对象,因此它以属性为特征。
以下为模块属性 −
-
file 返回模块的物理名称。
-
package 返回模块所属的包。
-
doc 返回模块顶部的文档字符串(如果有)。
-
dict 返回模块的整个作用域
-
name 返回模块的名称
Example
假设以下代码已保存为 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__)
它将生成以下 output −
__file__ attribute: C:\math\examples\mymodule.py
__doc__ attribute: The docstring of mymodule
__name__ attribute: mymodule
The _name_Attribute
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))
它将生成以下 output −
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
The dir( ) Function
内置函数 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']
The reload() Function
有时,你可能需要重新加载模块,尤其是在使用 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 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
Packages in 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 中放入显式 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 类,然后可以从这些类中创建包。