zoukankan      html  css  js  c++  java
  • Module Search of Python

    Module Search

    https://docs.python.org/3/tutorial/modules.html#the-module-search-path

    当使用import语句时, 首先解析器会寻找内置的模块, 例如 os, sys

    然后在sys.path路径列表中搜索

    此列表由如下三个路径组成:

    (1)输入脚本的当所在路径

    (2)PYTHONPATH环境中指定的路径列表

    (3)第三方安装依赖路径

    When a module named spam is imported, the interpreter first searches for a built-in module with that name. If not found, it then searches for a file named spam.py in a list of directories given by the variable sys.path. sys.path is initialized from these locations:

    • The directory containing the input script (or the current directory when no file is specified).

    • PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).

    • The installation-dependent default.

    当前路径下载module会被命中, 即使在库目录中有相同的module

    After initialization, Python programs can modify sys.path. The directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path.

    This means that scripts in that directory will be loaded instead of modules of the same name in the library directory.

    This is an error unless the replacement is intended. See section Standard Modules for more information.

    sys.path例子

    ['/mnt/c/Users/xiaohua/Desktop/test_project',
     '/usr/local/bin',
     '/root/.pyenv/versions/3.6.8/lib/python36.zip',
     '/root/.pyenv/versions/3.6.8/lib/python3.6',
     '/root/.pyenv/versions/3.6.8/lib/python3.6/lib-dynload',
     '/root/.pyenv/versions/3.6.8/lib/python3.6/site-packages']

    sys.path操作

    https://blog.csdn.net/longlovefilm/article/details/99683873?utm_medium=distribute.pc_relevant_bbs_down.none-task--2~all~baidu_landing_v2~default-1.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task--2~all~baidu_landing_v2~default-1.nonecase

    修改pythonpath

    vim /etc/profile
    export PYTHONPATH=/home/www/oadata.xesv5.com
    source /etc/profile #每个打开的shell界面都要source起作用

    添加再sys.path最前面

    import sys
    sys.path.insert(0,'/home/dev/data')
    reload(sys) #加不加都起作用

    添加再sys.path最后面

    import sys
    sys.path.append('/home/dev/data2')

    '__main__' is not a package

    https://blog.csdn.net/nuaa_llf/article/details/89883293

    经过一番百度,在Stack Overflow中找到了答案——相对导入只有在父模块已经在当前运行环境中被导入过才有用
    在这里插入图片描述
    对于这一问题,官方文档intra-package-references也给出了解释:

    Note that relative imports are based on the name of the current module. Since the name of the main module is always “main”, modules intended for use as the main module of a Python application must always use absolute imports.

    这里揭示了报错的缘由,相对导入基于当前模块的名称,因为主模块总被命名为"__main__"。当我们从主模块启动时,Python就识图用"__main__"替换".",于是那句话实际便成了from __main__.Wheel import Wheel,这当然是找不到的。

    Package Relative Imports

    https://docs.python.org/3/reference/import.html#package-relative-imports

    包内部的相对寻址方法,前提是包必须先加载。

    Relative imports use leading dots. A single leading dot indicates a relative import, starting with the current package. Two or more leading dots indicate a relative import to the parent(s) of the current package, one level per dot after the first. For example, given the following package layout:

    package/
        __init__.py
        subpackage1/
            __init__.py
            moduleX.py
            moduleY.py
        subpackage2/
            __init__.py
            moduleZ.py
        moduleA.py
    

    In either subpackage1/moduleX.py or subpackage1/__init__.py, the following are valid relative imports:

    from .moduleY import spam
    from .moduleY import spam as ham
    from . import moduleY
    from ..subpackage1 import moduleY
    from ..subpackage2.moduleZ import eggs
    from ..moduleA import foo
    

    Absolute imports may use either the import <> or from <> import <> syntax, but relative imports may only use the second form; the reason for this is that:

    import XXX.YYY.ZZZ
    

    should expose XXX.YYY.ZZZ as a usable expression, but .moduleY is not a valid expression.

    ModuleNotFoundError with pytest

    https://stackoverflow.com/questions/54895002/modulenotfounderror-with-pytest

    3
     

    I want my tests folder separate to my application code. My project structure is like so

    myproject/
      myproject/
        myproject.py
        moduleone.py
      tests/
        myproject_test.py
    

    myproject.py

    from moduleone import ModuleOne
    
    class MyProject(object)
    ....
    

    myproject_test.py

    from myproject.myproject import MyProject
    import pytest
    
    ...
    

    I use myproject.myproject since I use the command

    python -m pytest
    

    from the project root directory ./myproject/

    However, then the imports within those modules fail with

    E ModuleNotFoundError: No module named 'moduleone'

    solution

    Be sure to include . dot in the $PYTHONPATH env var.

    You can use this code fragment to debug such issues:

    import pprint
    import sys
    pprint.pprint(sys.path)
    

    Your question managed to use myproject at three different levels. At least during debugging you might want to use three distinct names, to reduce possible confusion.

    good practice

    Good practice: use a Makefile or some other automation tool

    If you are lazy and do not want to type that long command all the time, one option is to create a Makefile in your project's root dir with, e.g., the following:

    .PHONY: install test
    
    default: test
    
    install:
        pip install --upgrade .
    
    test:
        PYTHONPATH=. pytest
    

    Which allows you to simply run:

    make test
    

    or (even shorter)

    make
    
  • 相关阅读:
    Delphi 的RTTI机制浅探3(超长,很不错)
    关于跨进程使用回调函数的研究:以跨进程获取Richedit中RTF流为例(在Delphi 初始化每一个TWinControl 对象时,将会在窗体 的属性(PropData)中加入一些标志,DLL的HInstance的值与HOST 进程的HInstance并不一致)
    获得QQ聊天输入框中的内容
    使用Jenkins来构建Docker容器
    各种排序算法汇总
    ASP.NET Web API和ASP.NET Web MVC中使用Ninject
    s性能优化方面的小知识
    算法时间复杂度的计算
    js模块开发
    NET Framework 4.5 五个新特性
  • 原文地址:https://www.cnblogs.com/lightsong/p/14062337.html
Copyright © 2011-2022 走看看