python中模块查找的原理与方法详解
前言 本文主要给大家介绍了关于python模块查找的原理与方式,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍: 基础概念 module 模块, 一个 py 文件或以其他文件形式存在的可被导入的就是一个模块 package 包,包含有 __init__ 文件的文件夹 relative path 相对路径,相对于某个目录的路径 absolute path 绝对路径,全路径 路径查找 python 解释器查找被引入的包或模块 Python 解释器是如何查找包和模块的 Python 执行一个 py 文件,无论执行的方式是用绝对路径还是相对路径,interpreter 都会把文件所在的 directory 加入 code-1 #test.py import os import sys print sys.path[0] # execute python test.py python /Users/x/workspace/blog-code/p2016_05_28_python_path_find/test.py 执行表明相对路径和绝对路径都输出相同的结果,而且无论哪种执行方式,test.py 所在的文件夹都会被加入 Python 解释器查找包的顺序是什么 解释器查找包,首先搜索 built-in module,其次搜索 code-2 #ls ├── os.py ├── test2.py ├── redis.py #test2.py import os from redis import Redis #execute test2.py Traceback (most recent call last): File "/Users/x/workspace/blog-code/p2016_05_28_python_path_find/test2.py",line 1,in <module> from redis import Redis ImportError: cannot import name Redis 由于 os 是 built-in module,即使在同目录下有同名模块,解释器依然可以找到正确的 os 模块,可以证实 built-in module 不会被遮蔽,而 redis 属于第三方模块,默认安装位置是 Python 环境变量中的 site-packages,解释器启动之后会将此目录中的内容加入 交互式执行环境的查找顺序 进入交互式执行环境,解释器会自动把当前目录加入 >>> import os.path >>> import sys >>> os.path.abspath(sys.path[0]) '/Users/x/workspace/blog-code' >>> 除此之外,其他与执行一个文件是相同的。 模块中的 __file__ 变量 __file__ is the pathname of the file from which the module was loaded,if it was loaded from a file. 如果一个模块是从文件加载的,__file__ 就是该模块的路径名CPython Doc: 顾名思义,当模块以文件的形式出现 __file__ 指的是模块文件的路径名,以相对路径执行 __file__ 是相对路径,以绝对路径执行 __file__ 是绝对路径。 #test3.py print __file__ #相对路径执行 python test3.py test3.py #绝对路径执行 python /Users/x/workspace/blog-code/p2016_05_28_python_path_find/test3.py /Users/x/workspace/blog-code/p2016_05_28_python_path_find/test3.py 为了保证__file__ 每次都能准确得到模块的正确位置,最好对其再取一次绝对路径 交互式 shell 中的 __file__ >>> __file__ Traceback (most recent call last): File "<input>",in <module> NameError: name '__file__' is not defined 这是因为当前交互式shell的执行并不是以文件的形式加载,所以不存在__file__ 这样的属性。 sys.argv[0] 变量
#test.py import sys print __file__ print sys.argv[0] 以上 print 输出相同的结果,因为主执行文件和__file__所属的模块是同一个,当我们改变入口文件,区别就出现了。 #test.py import sys print __file__ print sys.argv[0] #test2.py import test #execute test2.py /Users/x/workspace/blog-code/p2016_05_28_python_path_find/child/test.py #__file__ test2.py #sys.argv[0] 总的来说, sys.modules 的作用 既然 Python 是在 >>> import sys >>> sys.modules['tornado'] Traceback (most recent call last): File "<input>",in <module> KeyError: 'tornado' >>> import tornado >>> sys.modules['tornado'] <module 'tornado' from '/Users/x/python_dev/lib/python2.7/site-packages/tornado/__init__.pyc'> 前面说过 Python 解释器启动之后,会把预先载入 built-in module,可以通过 >>> sys.modules['os'] <module 'os' from '/Users/x/python_dev/lib/python2.7/os.pyc'> >>> 借助 >>> import os >>> os.path.realpath(sys.modules['os'].__file__) '/Users/x/python_dev/lib/python2.7/os.pyc' >>> import tornado >>> os.path.realpath(sys.modules['tornado'].__file__) '/Users/x/python_dev/lib/python2.7/site-packages/tornado/__init__.pyc' def get_module_dir(name): path = getattr(sys.modules[name],'__file__',None) if not path raise AttributeError('module %s has not attribute __file__'%name) return os.path.dirname(os.path.abspath(path)) summary 总的来说,Python 是通过查找 文中所有代码见:github 总结 以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对编程小技巧的支持。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |