模块
1、模块详解
1.1 以脚本方式运行模块1.2 模块搜索路径1.3 '已编译'的python文件 2、标准模块3、dir() 函数4、包
4.1 从包中导入 *4.2 子包参考4.3 多目录中的包
模块模块是包含 Python 定义和语句的文件,其文件名是模块名加后缀名 .py
1、模块详解fibo.py是一个模块
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
模块包含可执行语句、函数定义可以把其他模块导入模块。按惯例,所有 import 语句都放在模块(或脚本)开头,但这不是必须的。导入模块中的方法:from fibo import fib, fib2导入模块中自定义的所有名称:
from fibo import *
这种方式会导入所有不以下划线(_)开头的名称,大多数情况下,不要用这个功能,这种方式向解释器导入了一批未知的名称,可能会覆盖已经定义的名称。
模块名后使用 as 时,直接把 as 后的名称与导入模块绑定
1.1 以脚本方式运行模块import fibo as fib
from fibo import fib as fibonacci
$ python fibo.py 10
def fib(n): # write Fibonacci series up to n
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
def fib2(n): # return Fibonacci series up to n
result = []
a, b = 0, 1
while a < n:
result.append(a)
a, b = b, a+b
return result
if __name__ == '__main__':
import sys
fib(int(sys.argv[1]))
在模块内部添加 if __name__ == '__main__': 时,导入模块时,不会运行这行代码及后面的,通常用于调测模块里面的代码,但是在命令行运行
$ python fibo.py 10时,会执行if __name__ == '__main__':这里面的内容
ing
1.3 '已编译’的python文件为了快速加载模块,Python 把模块的编译版缓存在 __pycache__ 目录中,文件名为 module.version.pyc,
例如:conftest.cpython-38-pytest-7.0.1.pyc从 .pyc 文件读取的程序不比从 .py 读取的执行速度快,.pyc 文件只是加载速度更快
变量 sys.path 是字符串列表,用于确定解释器的模块搜索路径。该变量以环境变量 PYTHonPATH 提取的默认路径进行初始化,如未设置 PYTHONPATH,
则使用内置的默认路径。可以用标准列表操作修改该变量:
import sys
a = sys.path
for i in a:
print(i)
C:Python38python.exe C:/Users/Desktop/python/tiaoce.py
C:UsersDesktoppython
C:UsersDesktoppython
3、dir() 函数
注意,该函数列出所有类型的名称:变量、模块、函数等。dir() 不会列出内置函数和变量的名称。这些内容的定义在标准模块 builtins 里
>>> a = [1, 2, 3, 4, 5] >>> import fibo >>> fib = fibo.fib >>> dir() ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']4、包
- 导入包时,Python 搜索 sys.path 里的目录,查找包的子目录。其中sys.path返回路径列表,第一个值是python的安装路径,第二个是当下文件的全局路径python只把包含__init__.py文件的目录当成包,这样可以防止以 string 等通用名称命名的目录,无意中屏蔽出现在后方模块搜索路径中的有效模块,最简情况下,__init__.py 只是一个空文件,但该文件也可以执行包的初始化代码,或设置 all 变量,从包中导入单个模块,例如:import sound.effects.echo这段代码加载子模块 sound.effects.echo ,但引用时必须使用子模块的全名:sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)导入子模块的方法是:
from sound.effects import echo # 调用子模块 echo.echofilter(input, output, delay=0.7, atten=4)
- import 语句的另一种变体是直接导入所需的函数或变量:from sound.effects.echo import echofilter使用 from package import item 时,item 可以是包的子模块(或子包),也可以是包中定义的函数、类或变量等其他名称。import 语句首先测试包中是否定义了 item;如果未在包中定义,则假定 item 是模块,并尝试加载。如果找不到 item,则触发 importError 异常。使用 import item.subitem.subsubitem 句法时,除最后一项外,每个 item 都必须是包;最后一项可以是模块或包,但不能是上一项中定义的类、函数或变量。
使用 from sound.effects import * 时会发生什么?理想情况下,该语句在文件系统查找并导入包的所有子模块。这项操作花费的时间较长,并且导入子模块可能会产生不必要的副作用,这种副作用只有在显式导入子模块时才会发生。
唯一的解决方案是提供包的显式索引。import 语句使用如下惯例:如果包的 __init__.py 代码定义了列表 __all__,运行 from package import * 时,它就是用于导入的模块名列表。发布包的新版本时,包的作者应更新此列表。如果包的作者认为没有必要在包中执行导入 * 操作,也可以不提供此列表。例如,sound/effects/__init__.py 文件包含以下代码:
__all__ = ["echo", "surround", "reverse"]
即,from sound.effects import * 将导入 sound 包中的这三个命名子模块。
如果没有定义 __all__,from sound.effects import * 语句 不会 把包 sound.effects 中所有子模块都导入到当前命名空间;该语句只确保导入包 sound.effects (可能还会运行 init.py 中的初始化代码),然后,再导入包中定义的名称。这些名称包括 init.py 中定义的任何名称(以及显式加载的子模块),还包括之前 import 语句显式加载的包里的子模块。请看以下代码:
import sound.effects.echo import sound.effects.surround from sound.effects import *
本例中,执行 from…import 语句时,将把 echo 和 surround 模块导入至当前命名空间,因为,它们是在 sound.effects 包里定义的。(该导入操作在定义了 all 时也有效。)
虽然,可以把模块设计为用 import * 时只导出遵循指定模式的名称,但仍不提倡在生产代码中使用这种做法。
记住,使用 from package import specific_submodule 没有任何问题! 实际上,除了导入模块使用不同包的同名子模块之外,这种方式是推荐用法。
4.2 子包参考- 绝对导入:from sound.effects import echo相对导入:
from . import echo from .. import formats from ..filters import equalize
- 注意,相对导入基于当前模块名。因为主模块名是 “main” ,所以 Python 程序的主模块必须始终使用绝对导入。
包还支持特殊属性 path。该属性初始化为在包的 init.py 文件中的代码执行前所在的目录名列表。这个变量可以修改,但这样做会影响将来搜索包中模块和子包的操作。
这个功能虽然不常用,但可用于扩展包中的模块集。



