美文网首页
Python sys.path详解

Python sys.path详解

作者: 大富帅 | 来源:发表于2018-12-17 10:37 被阅读28次

    直接运行 和 模块运行 的区别

    • python xxx.py
    • python -m xxx.py

    这是两种加载py文件的方式:
    1叫做直接运行
    2把模块当作脚本来启动(注意:但是__name__的值为'main' )

    直接启动是把xx.py文件,所在的目录放到了sys.path属性中。
    模块启动是把你输入命令的目录(也就是当前路径),放到了sys.path属性中

    下面可以看看例子:
    假设我们项目的结构是这样的:

    statistics
        ->activity
            -> stat.py
        ->base
            ->connection.py
            ->__init__.py
    
    python activity/stat.py
    

    这样执行的话,打印sys.path可以看到sys.path的第一个目录就是运行的stat.py所在的目录,也就是activity目录

    ['/home/lidongwei/vhost/nemu-server/statistics/activity',  ...]
    

    那如果我们用模块运行 python -m

    python -m activity.mumu_stat
    

    这样运行的话sys.path的第一个值就是'', 也就是当前执行python的目录

    ['',  ...]
    

    两种不同的运行,分别有什么场景?

    如果我们想在stat.py 里面import activity目录上一个文件夹的其他模块是不可以的, 比如我想导入base.connection里面的db_mongo, 这是不可以的,为什么?因为sys.path 就是在activity目录,根目录statictis 没有在sys.path里面啊

    from base.connection import db_mongo
    

    这样会报错:

    ImportError: No module named base.connection
    

    那自然我们就会想能否这样通过相对路径引入

    from ..base.connection import db_mongo
    

    然后执行 python activity/stat.py
    这样还回报错,但是是另外一个报错:

    ValueError: Attempted relative import in non-package
    

    这是因为, 如果我们直接执行py文件的话,是不可以使用相对引入的,否则就会报错 Attempted relative import in non-package

    那如果我们用模块运行会怎样 python -m

     [~/vhost/statistics]$ python -m activity.mumu_stat
    

    报了另外一个错误

    ValueError: Attempted relative import beyond toplevel package
    

    这是因为 ..base的时候已经出了顶级目录了,为什么?因为python -m 的时候,sys.path的第一个目录就是当前执行python的目录, 也就是 ~/vhost/statistics, 这个已经是顶级目录了, 还要..base的话就会超出,所以报错

    这个时候,到底是使用直接启动,还是以模块的启动?目的就是把import的那个模块的路径放到sys.path中。

    总结

    导入一个叫 mod1 的模块时,解释器先在当前目录中搜索名为 mod1.py 的文件。如果没有找到的话,接着会到 sys.path 变量中给出的目录列表中查找。 sys.path 变量的初始值来自如下:

    • 输入脚本的目录(当前目录)。
    • 环境变量 PYTHONPATH 表示的目录列表中搜索(这和 shell 变量 PATH 具有一样的语法,即一系列目录名的列表)。
    • Python 默认安装路径中搜索。
      实际上,解释器由 sys.path 变量指定的路径目录搜索模块,该变量初始化时默认包含了输入脚本(或者当前目录), PYTHONPATH 和安装目录。这样就允许 Python程序了解如何修改或替换模块搜索目录。

    PYTHONPATH 与 sys.path的关系

    (mumu-store-server-env) [~/vhost/nemu-statistics]$ echo $PYTHONPATH
    
    (mumu-store-server-env) [~/vhost/nemu-statistics]$ python 
    >>> import sys
    >>> sys.path
    ['', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/plat-x86_64-linux-gnu', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/lib-tk', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/lib-old', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/lib-dynload', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/home/lidongwei/.virtualenvs/mumu-store-server-env/local/lib/python2.7/site-packages', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/site-packages']
    

    默认情况下PYTHONPATH是空的, 然后进去看到sys.path是一个列表,包括有所有查找包的目录

    下面我们给PYTHON加个目录

    (mumu-store-server-env) [~/vhost/nemu-statistics]$ export PYTHONPATH=/home/lidongwei/Desktop 
    (mumu-store-server-env) [~/vhost/nemu-statistics]$ python 
    >>> import sys
    >>> sys.path
    ['', '/home/lidongwei/Desktop', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/plat-x86_64-linux-gnu', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/lib-tk', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/lib-old', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/lib-dynload', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-x86_64-linux-gnu', '/usr/lib/python2.7/lib-tk', '/home/lidongwei/.virtualenvs/mumu-store-server-env/local/lib/python2.7/site-packages', '/home/lidongwei/.virtualenvs/mumu-store-server-env/lib/python2.7/site-packages']
    

    可以看到'/home/lidongwei/Desktop' 这个目录已经被加到sys.path了, 说明PYTHONPATH会加到sys.path

    相关文章

      网友评论

          本文标题:Python sys.path详解

          本文链接:https://www.haomeiwen.com/subject/ihrqkqtx.html