发布时间:2022-04-02 09:59:19 人气:229 作者:多测师
在上几篇文章中已经用了如 os,shutils,json 等多个模块 ,这些模块都是 python 的内置模块。相比之下,我们刚才使用的 calc 模块就是自定义模块。
假设我们使用 import calc 导入 calc 模块, python 在启动时按照什么样的顺序来查找这个模块呢?
先查找内置(built-in)模块中有没有,如果没有转到 2
查找 sys.path 变量指定的路径下有没有, 有的话就使用,没有就报错
sys.path 变量中存储了那些路径呢?
当前运行的 python 脚本所在的目录
环境变量 PYTHONPATH 中的路径,它和 shell 环境变量 PATH 差不多
这个变量可以使用 python 脚本在运行时修改它
默认的 python 安装包的路径
想要看下你的电脑当前 sys.path 有哪些路径吗?运行下面代码就可以
import sys
print(sys.path)
查找模块的顺序是从前向后,只要查到就使用,因此这个变量存储路径的顺序很重要。
模块中包含执行语句的情况
如果引入的模块中包含一些执行语句,那么在导入模块时这些语句就会执行。但是即使同样的模块被导入了两次,这些语句也只能执行一次。
来看下面的例子, 定义 calc 模块
print('I am clac module')
def plus(a, b):
return a + b
def subtract(a, b):
return a - b
并且在 main.py 中定义导入两次 calc 模块的函数
from calc import plus
from calc import subtract
print(plus(1, 2))
print(subtract(1, 2))
结果是 'I am clac module' 只会被打印一次。
用 dir() 函数来窥探模块
dir() 函数是 python 的内置函数,可用来获取模块的属性,方法等信息,当我们刚接触一个模块,不清楚它由哪些有用的属性和方法时,就可以用 dir() 来一探究竟。
以常用的 json模块 为例,我们来展示下它的属性和方法
import json
print(dir(json))
# ['JSONDecodeError', 'JSONDecoder', 'JSONEncoder', '__all__', '__author__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_default_decoder', '_default_encoder', 'codecs', 'decoder', 'detect_encoding', 'dump', 'dumps', 'encoder', 'load', 'loads', 'scanner']
其中以双下划线开头的变量,如 __name__ 并非是模块自己定义的,而是与模块相关的默认属性。
如果我想查看当前模块内的所有属性和方法呢?去掉 dir() 函数的参数就可以。拿上节的代码为例来看下。
from calc import plus
from calc import subtract
print(plus(1, 2))
print(subtract(1, 2))
print(dir())
# ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'plus', 'subtract']
我们会看到 calc 模块的 plus 和 substract 方法也展示了出来,那么 dir 函数究竟是从哪里获取的数据,背后的机理是什么呢?
其实每个模块内部都有一个子集的私有符号表,它就是模块内所有函数和方法共享的全局符号表。当模块 B 导入模块 A 时,就会把要导入的模块 A 或者特定的方法,属性放置到模块 B 的全局符号表中,dir() 函数也就是从模块中的全局符号表中获取出的值。
以上内容为大家介绍了Python模块的查找顺序,希望对大家有所帮助,如果想要了解更多Python相关知识,请关注多测师。https://www.e70w.com/xwzx/