📜  Python 3-模块

📅  最后修改于: 2020-12-23 04:54:22             🧑  作者: Mango


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

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

名为aname的模块的Python代码通常位于名为aname.py的文件中。这是一个简单模块support.py的示例-

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

进口声明

您可以通过在其他一些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

无论模块导入多少次,模块都只会加载一次。如果发生多次导入,这可以防止模块执行重复发生。

from … import声明

Python的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 *声明

也可以通过使用以下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将在外壳程序变量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对变量是局部变量还是全局变量进行了有根据的猜测。它假定在函数分配了值的任何变量都是局部变量。

  • 因此,为了向函数内的全局变量分配值,必须首先使用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应用程序环境,该环境由模块,子程序包和子子程序包等组成。

考虑电话目录中可用的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中放入显式import语句,如下所示:

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