Python 3 - 模块

  • 简述

    模块允许您逻辑地组织您的 Python 代码。将相关代码分组到一个模块中可以使代码更易于理解和使用。模块是一个 Python 对象,具有您可以绑定和引用的任意命名的属性。
    简单地说,一个模块就是一个由 Python 代码组成的文件。模块可以定义函数、类和变量。模块还可以包括可运行代码。

    例子

    名为 aname 的模块的 Python 代码通常位于名为 daname.py 的文件中。这是一个简单模块的示例,support.py -
    def print_func( par ):
       print "Hello : ", par
       return
    
  • import 声明

    通过在其他 Python 源文件中执行 import 语句,您可以将任何 Python 源文件用作模块。这import具有以下语法 -
    
    import module1[, module2[,... moduleN]
    
    当解释器遇到 import 语句时,如果模块存在于搜索路径中,它就会导入该模块。搜索路径是解释器在导入模块之前搜索的目录列表。例如,要导入模块 hello.py,您需要将以下命令放在脚本的顶部 -
    
    #!/usr/bin/python3
    # Import module support
    import support
    # Now you can call defined function that module as follows
    support.print_func("Alex")
    
    执行上述代码时,会产生以下结果 -
    
    Hello : Alex
    
    一个模块只加载一次,不管它被导入多少次。如果发生多次导入,这可以防止模块重复执行。
  • from...import 语句

    蟒蛇的from语句允许您将特定属性从模块导入当前命名空间。这from...import具有以下语法 -
    
    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 * 语句

    也可以使用以下导入语句将模块中的所有名称导入当前命名空间 -
    
    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中作为sys.path多变的。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 对变量是局部变量还是全局变量进行有根据的猜测。它假定在​​函数中赋值的任何变量都是局部的。
    • 因此,为了给函数内的全局变量赋值,必须首先使用global语句。
    • 语句global 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 -
    • 电话/__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 类,然后您可以从这些类中创建包。