关于Python中的import(三)
来源:互联网 发布:网络用语ps是什么意思 编辑:程序博客网 时间:2024/06/08 12:18
上节介绍了 importlib.import_module(),和 package 的基础概念,本节深入理解导模块的机理以及简单了解 Namespace package
在 import 模块的时候,系统会首先到 sys.modules 里面去查找要导入的模块,sys.modules 是个什么东东呢,我们打印一下看看它是什么:
import sysprint(type(sys.modules)) # <class 'dict'>
sys.modules 是一个存放缓存模块的字典,打印一下会发现许多条目所有之前导入过的模块都在这个字典中。当我们导入一个模块时,会首先查看 sys.modules里面有没有缓存,如果有直接返回,搜索过程结束;如果没有,则继续查找。
例如导入模块 foo.bar.biz, 系统会首先导入中间模块 foo,然后是 foo.bar,最后是 foo.bar.biz, 然后 sys.modules 中会多出三条条目,键分别为 “foo”、“foo.bar”、“foo.bar.biz”,值为对应的模块对象,多次导入会拿到同一个模块对象,并且第一次导入模块时会执行模块内的代码。
假如在 sys.modules 中没有找到要导入的模块,那么系统就要进一步搜索模块,这里有很多具体细节,就不说了,总的来说就是如果是我们自己定义的模块,会往 sys.path 中去找
import sysprint(sys.path)
打印出的结果是一个列表,列表里面是一些路径,默认状态下第一个路径是我们启动 python 程序的工作目录,首先在这个目录下查找模块。例如导入 foo.bar.biz, 会首先在 sys.path 下寻找 foo 模块,找到后,再在 foo 的 __path__ 下查找bar, 再在 bar 的 __path__ 下查找 biz。
而 sys.path 是可以修改的,我们可以向里面 insert 搜索路径。
parent/ main.py one/ __init__.py mymodule.py two/ __init__.py three/ __init__.py
假设我们通过执行 main.py 启动 Python 程序,parent 为工作目录,这时需要在 main 模块中导入 mymodule 模块,需要 import one.mymodule, 假如在导入之前,执行 sys.path.append(‘./one’)
import syssys.path.append('./one')import mymodule
这样就会直接在 parent/one/ 路径下查找到模块,但是注意这样创建的模块和通过 import one.mymodule 方式导入的模块不是同一个对象,在 sys.modules 中会对应两个不同的键值对。
Namespace package
Namespace package 与 Regular package 表面上的不同点是 Namespace package 下没有 __init__.py 文件, 还是用实例来说明
Lib/test/namespace_pkgs project1 parent child one.py project2 parent child two.py
这里两个 parent 和 两个 child package下都没有 __init__.py 文件,
>>> import sys>>> sys.path += ['Lib/test/namespace_pkgs/project1', 'Lib/test/namespace_pkgs/project2']>>> import parent.child.one>>> parent.__path___NamespacePath(['Lib/test/namespace_pkgs/project1/parent', 'Lib/test/namespace_pkgs/project2/parent'])>>> parent.child.__path___NamespacePath(['Lib/test/namespace_pkgs/project1/parent/child', 'Lib/test/namespace_pkgs/project2/parent/child'])>>> import parent.child.two>>>
每个 namespace package 的 __path__ 属性,都有两条。说白了此时就是通过 import parent.child.xxx.py 导入模块时,有两条可搜索的路径,在 sys.path += [‘Lib/test/namespace_pkgs/project1’, ‘Lib/test/namespace_pkgs/project2’] 执行后,sys.path中就多了两条搜索路径,这两条搜索路径下有相同的 namespace package 结构,于是乎就发生了些不可描述的事情,大家自行体会。namespace package 的 __path__ 我们是不能去修改的,系统会自动动态更新。
import 的内容就简单说到这,关于 import 还有些更深入的内容,就暂时不去探究了,以后如果遇到再来补充。
参老资料:
官方文档 3.6.2
https://www.python.org/dev/peps/pep-0420/
- 关于Python中的import(三)
- 关于Python中的import(一)
- 关于Python中的import(二)
- 关于Python中的import(一)
- 关于Python的import
- 关于python 中的__future__模块(from __future__ import ***)
- python中的import详解
- python中的关键字import
- Python中的import
- python中的import机制
- python中的import介绍
- Python中的 "import" 和 "from ... import"
- python中的import 和 from .. import ..
- python中的import和from import
- 关于python import的总结
- python 中的相互import问题
- python中的import和from
- python中的python from __future__ import division
- java日志详解--logback
- beyond compare过期解决办法
- Android系统view控件使用的一些坑
- java中借助Spring获取所有带有指定注解的接口、类、对象
- Python---map和reduce函数
- 关于Python中的import(三)
- 浅析Java设计模式中的观察者模式
- mybatis 表1对多查询
- 通过方法重载给一个方法符默认参数
- Swift语音和文本的转换
- 2017科技界十大事件:AlphaGo、智能音箱、无人驾驶。AI时代正在朝我们走来!
- 数字越界
- 高内聚、低耦合的含义是什么?如何提高代码的可重用性?
- 10. Go 单元测试