一个模块允许你在逻辑上组织你的Python代码。 将相关代码分组到模块中使代码更易于理解和使用。 一个模块是一个具有任意命名属性的Python对象,您可以将其绑定和引用。

简单地说,一个模块是一个由Python代码组成的文件。 模块可以定义函数,类和变量。 一个模块还可以包含可运行代码。

例子

名为aname的模块的Python代码通常驻留在名为aname.py的文件中。 这是一个简单模块support.py的例子 -

def print_func( par ):
    print "Hello : ", par
    return

import 语句

通过在其他Python源文件中执行import语句,可以将任何Python源文件用作模块。 导入具有以下语法 -

import module1[, module2[,... moduleN]

当解释器遇到导入语句时,如果模块出现在搜索路径中,它将导入模块。 搜索路径是解释器在导入模块之前搜索的目录列表。 例如,要导入模块hello.py,您需要将以下命令放在脚本的顶部 -

#!/usr/bin/python3
    
# Import module support
import support
    
# Now you can call defined function that module as follows
support.print_func("Zara")

当上面的代码被执行时,它会产生以下结果 -

Hello : Zara

无论导入次数如何,模块只能加载一次。 如果发生多个导入,这可以防止模块执行重复发生。

rom…import 语句

Python的from语句让你从模块中导入一个指定的部分到当前命名空间中,语法如下

from modname import name1[, name2[, ... nameN]]

例如,要从模块fib中导入函数fibonacci,请使用以下语句 -

#!/usr/bin/python3
    
# Fibonacci numbers module
    
def fib(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a + b
    return result
>>> from fib import fib
>>> fib(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

此语句不会将整个模块fib导入当前名称空间; 它只是将来自模块fib的项目fibonacci引入导入模块的全局符号表。

From…import* 语句

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

from modname import *

这提供了一种将模块中的所有项目导入当前名称空间的简单方法; 但是,应该谨慎使用这种说法。

作为脚本执行模块

在模块中,模块的名称(作为字符串)可用作全局变量__name__的值。 模块中的代码将被执行,就像导入它一样,但__name__设置为“__main__”。

将此代码添加到模块的末尾 -

#!/usr/bin/python3
    
# Fibonacci numbers module
    
def fib(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a + b
    return result
if __name__ == "__main__":
    f = fib(100)
    print(f)

当您运行上述代码时,将显示以下输出。

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

定位模块

当你导入一个模块时,Python解释器按以下顺序搜索模块 -

  • 当前目录。

  • 如果找不到该模块,则Python会搜索shell变量PYTHONPATH中的每个目录。

  • 如果一切都失败了,Python会检查默认路径。 在UNIX上,这个默认路径通常是/usr/local/lib/python3/。

模块搜索路径作为sys.path变量存储在系统模块sys中。 sys.path变量包含当前目录PYTHONPATH和依赖于安装的缺省值。

PYTHONPATH变量

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

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

set PYTHONPATH = c:\python34\lib;

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

set PYTHONPATH = /usr/local/lib/python

命名空间和作用域

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

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

  • 每个函数都有自己的本地名称空间。 类方法遵循与普通函数相同的范围规则。

  • Python对变量是本地还是全局进行了有根据的猜测。 它假定在函数中赋值的任何变量都是本地的。

  • 因此,为了给函数中的全局变量赋值,你必须首先使用全局语句。

  • 语句全局VarName告诉Python VarName是一个全局变量。 Python停止搜索变量的本地名称空间。

例如,我们在全局名称空间中定义一个变量Money。 在Money函数中,我们为Money分配一个值,因此Python将Money作为局部变量。

但是,在设置它之前,我们访问了局部变量Money的值,因此UnboundLocalError是结果。 取消全球声明可以解决问题。

#!/usr/bin/python3
    
Money = 2000
def AddMoney():
    # Uncomment the following line to fix the code:
    # global Money
    Money = Money + 1
    
print (Money)
AddMoney()
print (Money)

dir()函数

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

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

#!/usr/bin/python3

# 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']

这里,特殊字符串变量__name__是模块的名称,__file__是模块加载的文件名。

globals()和locals()函数

可以使用globals()和locals()函数根据调用位置的位置来返回全局名称空间和本地名称空间中的名称。

  • 如果locals()从函数中调用,它将返回所有可以从该函数本地访问的名称。

  • 如果从函数中调用globals(),它将返回可以从该函数全局访问的所有名称。

这两个函数的返回类型都是字典。 因此,可以使用keys()函数来提取名称。

reload函数

将模块导入脚本时,模块顶层部分的代码只执行一次。

因此,如果要重新执行模块中的顶级代码,可以使用reload()函数。 reload()函数再次导入以前导入的模块。 reload()函数的语法是这样的 -

reload(module_name)

这里,module_name是要重新加载的模块的名称,而不是包含模块名称的字符串。 例如,要重新加载hello模块,请执行以下操作 -

reload(hello)

Python中的包

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

考虑Phone目录中可用的文件Pots.py。 该文件具有以下一行源代码 -

#!/usr/bin/python3
    
def Pots():
    print ("I'm Pots Phone")

类似的,我们还有其他两个文件具有不同的功能,其名称与上面相同。 他们是 -

  • 具有函数Isdn()的Phone/Isdn.py文件

  • 具有函数G3()的Phone/G3.py文件

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

  • Phone/__init__.py

要在导入Phone使所有函数都可用,您需要在__init__.py中显式输入语句,如下所示 -

from Pots import Pots
from Isdn import Isdn
from G3 import G3

将这些行添加到__init__.py之后,当您导入Phone包时,所有这些类都可用。

#!/usr/bin/python3

# 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类,然后你可以从这些类中创建你的包。