在Python教程的这一部分,我们使用Python模块。几个示例展示了如何创建和使用Python模块。
模块是包含Python代码的文件。Python模块具有.py
扩展名。
可以使用以下方式管理Python代码:
- 函数
- 类
- 模块
- 包
Python模块用于组织Python代码。例如,数据库相关代码放在数据库模块中,安全代码放在安全模块中等。较小的Python脚本可以有一个模块。但是较大的程序被分成几个模块。模块组合在一起形成包。
Python模块名称
模块名称是具有.py
扩展名的文件名。当我们有一个名为empty.py
的文件时,empty是模块名称。__name__
是一个变量,它保存被引用的模块的名称。当前模块,正在执行的模块(也称为主模块)有一个特殊的名称:'__main__'
。使用此名称可以从Python代码中引用它。
我们在当前工作目录中有两个文件:empty.py
和test_empty.py
。第二个模块是执行的主模块。它导入第一个模块。使用import
关键字导入模块。
""" An empty module """
这是empty.py
模块。
#!/usr/bin/python import empty import sys print(__name__) print(empty.__name__) print(sys.__name__)
在此代码示例中,我们导入了两个模块:内置模块sys
和一个自定义模块empty
。我们将模块的名称打印到控制台。
$ ./test_empty.py __main__ empty sys
正在执行的模块的名称始终是'__main__'
。其他模块以文件名命名。可以使用import关键字。
Python定位模块
导入模块时,解释器首先搜索具有该名称的内置模块。如果未找到,它将在变量sys.path
给出的目录列表中搜索。sys.path
是指定模块搜索路径的字符串列表。它由当前工作目录、在PYTHONPATH
环境变量中指定的目录名称以及一些附加的安装依赖目录组成。如果未找到该模块,则会引发ImportError
。
#!/usr/bin/python import sys import textwrap sp = sorted(sys.path) dnames = ', '.join(sp) print(textwrap.fill(dnames))
该脚本打印来自sys.path
变量的所有目录。
import textwrap
textwrap
模块用于轻松格式化段落。
sp = sorted(sys.path)
我们从sys.path
变量中检索目录列表并对它们进行排序。
dnames = ', '.join(sp)
我们从列表中创建一个字符串。
$ ./locating_modules.py /home/jano/.local/lib/python3.10/site-packages, /home/jano/tmp/py, /usr/lib/python3.10, /usr/lib/python3.10/lib-dynload, /usr/lib/python3/dist-packages, /usr/lib/python310.zip, /usr/local/lib/python3.10/dist-packages
Python导入关键字
import
关键字可以以多种方式使用。
from module import *
此构造会将所有Python定义导入另一个模块的命名空间。有一个例外。不导入以下划线_
开头的对象。它们应该只在被导入的模块内部使用。不推荐这种导入模块的方式。
#!/usr/bin/python from math import * print(cos(3)) print(pi)
此导入结构已从内置math
模块导入所有定义。我们可以直接调用数学函数,而无需引用math
模块。
$ ./everything.py -0.9899924966004454 3.141592653589793
使用此导入结构可能会导致命名空间污染。我们可能有多个同名对象,它们的定义可以被覆盖。
#!/usr/bin/python from math import * pi = 3.14 print(cos(3)) print(pi)
该示例将3.14打印到控制台。这可能不是我们想要的。命名空间污染在大型项目中可能变得很严重。
未导入的Python对象
以下示例显示了未使用此import
构造导入的定义。
#!/usr/bin/python """ names is a test module """ _version = 1.0 names = ["Paul", "Frank", "Jessica", "Thomas", "Katherine"] def show_names(): for i in names: print(i) def _show_version(): print(_version)
#!/usr/bin/python from names import * print(locals()) show_names()
_version
变量和_show_version
函数未导入到test_names
模块中。我们在命名空间中看不到它们。locals
函数为我们提供了模块中可用的所有定义。
导入特定对象
使用from
和import
关键字,可以只导入一些对象。
from module import fun, var
此导入结构仅从模块中导入特定对象。这样我们只导入我们需要的定义。
#!/usr/bin/python from math import sin, pi print(sin(3)) print(pi)
我们从math
模块导入两个对象。我们无法引用其他定义,例如cos函数。
#!/usr/bin/python from names import _version, _show_version print(_version) _show_version()
我们还可以导入以下划线开头的定义。但这是一种不好的做法。
$ ./imnames.py 1.0 1.0
Python导入模块
最后一个结构使用最广泛。
import module
它防止命名空间污染并允许访问模块中的所有定义。
#!/usr/bin/python import math pi = 3.14 print(math.cos(3)) print(math.pi) print(math.sin(3)) print(pi)
在这种情况下,我们通过模块名称引用定义。如我们所见,我们能够使用两个pi变量。我们的定义和来自math
模块的定义。
$ ./impmod.py -0.9899924966004454 3.141592653589793 0.1411200080598672 3.14
Python别名模块
我们可以使用as
关键字为模块创建别名。
#!/usr/bin/python # importas.py import math as m print(m.pi) print(m.cos(3))
我们可以更改我们可以引用模块的名称。为此,我们使用as
关键字。
$ ./importas.py 3.14159265359 -0.9899924966
导入错误
如果无法导入模块,则会引发ImportError
。
#!/usr/bin/python try: import empty2 except ImportError as e: print('Failed to import:', e)
我们还没有创建empty2
模块。因此引发异常。
$ ./importerror.py Failed to import: No module named empty2
执行Python模块
模块可以导入到其他模块中,也可以被执行。模块作者通常会创建一个测试套件来测试模块。仅当模块作为脚本执行时,__name__
属性等于'__main__'
。
我们将在斐波那契模块上对此进行演示。斐波那契数列是一个数字序列,其中每个数字都是其前两个数字的总和。
#!/usr/bin/python """ A module containing the fibonacci function. """ def fib(n): a, b = 0, 1 while b < n: print(b, end=" ") (a, b) = (b, a + b) # testing if __name__ == '__main__': fib(500)
模块可以正常导入。该模块也可以执行。
$ ./fibonacci.py 1 1 2 3 5 8 13 21 34 55 89 144 233 377
如果我们导入fibonacci模块,测试不会自动执行。
>>> import fibonacci as fib >>> fib.fib(500) 1 1 2 3 5 8 13 21 34 55 89 144 233 377
导入斐波那契模块并执行fib
函数。
Python目录函数
内置的dir
函数给出了一个排序的字符串列表,其中包含模块定义的名称。
#!/usr/bin/python """ This is dirfun module """ import math, sys version = 1.0 names = ["Paul", "Frank", "Jessica", "Thomas", "Katherine"] def show_names(): for i in names: print(i) print(dir())
在这个模块中,我们导入了两个系统模块。我们定义了一个变量、一个列表和一个函数。
print(dir())
dir
函数返回模块当前命名空间中的所有可用名称。
$ ./dirfun.py ['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'math', 'names', 'show_names', 'sys', 'version']
我们可以看到一些内置名称,如'__file__'
或'__name__'
以及我们定义和导入的所有其他名称。
Python全局函数
globals
函数返回代表当前全局命名空间的字典。它是全局名称及其值的字典。它是当前模块的字典。
#!/usr/bin/python import textwrap version = 1.0 def myfun(): pass gl = globals() gnames = ', '.join(gl) print(textwrap.fill(gnames))
我们使用globals
函数来打印当前模块的所有全局名称。
$ ./globalsfun.py textwrap, __package__, version, __builtins__, __name__, __spec__, __doc__, gl, __cached__, myfun, __loader__, __file__
这些是当前模块的全局名称。
Python__module__属性
__module__
类属性具有定义该类的模块的名称。
""" module animals """ class Cat: pass class Dog: pass
这是animals.py
文件的内容。我们有两个班级。
#!/usr/bin/python from animals import Cat class Being: pass b = Being() print(b.__module__) c = Cat() print(c.__module__)
在这段代码中,我们使用了__module__
属性。
from animals import Cat
从animals
模块中,我们导入Cat
类。
class Being: pass
在当前模块中,我们定义了一个类Being
。
b = Being() print(b.__module__)
Being
类的一个实例被创建。我们打印其模块的名称。
c = Cat() print(c.__module__)
我们从Cat
类创建一个对象。我们还在定义模块的地方打印模块。
$ ./mclass.py __main__ animals
当前模块的名称是'__main__'
。Cat的
模块名称是animals。
在本文中,我们介绍了Python模块。
列出所有Python教程。