python如何查看模块的用法_Python中关于模块查找的使用详解

这篇文章主要给大家介绍了python中模块查找的原理与方式,文中通过示例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友们下面跟着小编来一起学习学习吧。

前言

本文主要给大家介绍了关于python模块查找的原理与方式,分享出来供大家参考学习,下面话不多说,来一起看看详细的介绍:

基础概念

module

模块, 一个 py 文件或以其他文件形式存在的可被导入的就是一个模块

package

包,包含有 __init__ 文件的文件夹

relative path

相对路径,相对于某个目录的路径

absolute path

绝对路径,全路径

路径查找

python 解释器查找被引入的包或模块

Python 解释器是如何查找包和模块的

Python 执行一个 py 文件,无论执行的方式是用绝对路径还是相对路径,interpreter 都会把文件所在的 directory 加入 sys.path 这个 list 中,Python 就是在 sys.path中查找包和模块的,sys.path 中的内容本身又是又 Python 的环境变量决定。

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 所在的文件夹都会被加入 sys.path 的首位,也就是索引为0的位置。

Python 解释器查找包的顺序是什么

解释器查找包,首先搜索 built-in module,其次搜索 sys.path ,这样的查找顺序将会导致同名包或模块被遮蔽。

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

from redis import Redis

ImportError: cannot import name Redis

由于 os 是 built-in module,即使在同目录下有同名模块,解释器依然可以找到正确的 os 模块,可以证实 built-in module 不会被遮蔽,而 redis 属于第三方模块,默认安装位置是 Python 环境变量中的 site-packages,解释器启动之后会将此目录中的内容加入 sys.path,由于当前目录会在 sys.path 的首位,当前目录的 redis 优先被找到,site-packages 中的 redis 模块被遮蔽了。

交互式执行环境的查找顺序

进入交互式执行环境,解释器会自动把当前目录加入 sys.path, 这时当前目录是以相对路径的形式出现在 sys.path中:

>>> 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__ 就是该模块的路径名–Python 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__ 每次都能准确得到模块的正确位置,最好对其再取一次绝对路径 os.path.abspath(__file__)。

交互式 shell 中的 __file__

>>> __file__

Traceback (most recent call last):

File "", line 1, in

NameError: name '__file__' is not defined

这是因为当前交互式shell的执行并不是以文件的形式加载,所以不存在__file__ 这样的属性。

sys.argv[0] 变量

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.argv[0] 是获得入口执行文件路径,__file__ 是获得任意模块文件的路径。

sys.modules 的作用

既然 Python 是在 sys.path中搜索模块的,那载入的模块存放在何处?答案就是 sys.modules。模块一经载入,Python 会把这个模块加入 sys.modules中供下次载入使用,这样可以加速模块的引入,起到缓存的作用。

>>> import sys

>>> sys.modules['tornado']

Traceback (most recent call last):

File "", line 1, in

KeyError: 'tornado'

>>> import tornado

>>> sys.modules['tornado']

前面说过 Python 解释器启动之后,会把预先载入 built-in module,可以通过 sys.modules验证。

>>> sys.modules['os']

>>>

借助sys.modules和 __file__,可以动态获取所有已加载模块目录和路径。

>>> 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 是通过查找 sys.path 来决定包的导入,并且系统包优先级>同目录>sys.path,Python 中的特有属性 __file__ 以及 sys.argv[0] ,sys.modules 都能帮助我们理解包的查找和导入概念,只要能正确理解 sys.path的作用和行为,理解包的查找就不是难题了。

总结

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值