最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】python中的相对路径导入库失败No module named

Python crifan 12067浏览 0评论

之前已经在PyCharm中,本地调试期间,解决了相对路径导入的问题:

【已解决】Python中使用相对路径导入库函数

PyCharm中本地调试是可以导入的:

但是同样的代码:

processData/mysqlQa/MongodbToMysqlQa.py

<code># import os
# import sys
# sys.path.append(os.path.join(os.path.split(os.path.realpath(__file__))[0], '../../util'))
# sys.path.append(os.path.join(os.path.split(os.path.realpath(__file__))[0], '../'))
# sys.path.append(os.path.join(os.path.split(os.path.realpath(__file__))[0], '../..'))
# sys.path.append(os.path.join(os.path.split(os.path.realpath(__file__))[0], '../../util'))
# sys.path.append(os.path.join(os.path.split(os.path.realpath(__file__))[0], '../../util/crifanLib'))
from util import configs
from util.crifanLib import crifanFile, crifanLogging, crifanMysql
</code>

以及:

util/crifanLib/crifanHttp.py

<code>from . import crifanFile
</code>

但是上传到服务器上后,去命令行中运行,就出错了:

<code>(debug_xx-wDGPvi3o) [root@xx-general-01 mysqlQa]# python MongodbToMysqlQa.py
Traceback (most recent call last):
  File "MongodbToMysqlQa.py", line 16, in &lt;module&gt;
    from util import configs
ImportError: No module named 'util'
</code>

所以对于 相对路径的导入,看来还是理解的不够透彻

去搜:

python relative import No module named

python – Relative imports for the billionth time – Stack Overflow

relative paths for modules in python – Stack Overflow

python – “ImportError: No module named…” when importing my own module – Stack Overflow

4 PEP 328: Absolute and Relative Imports

Python 的 Import 陷阱 – PyLadies Taiwan – Medium

试试回到项目根目录去试试,结果问题依旧:

<code>(debug_nlp-wDGPvi3o) [root@xx-general-01 debug_nlp]# python processData/mysqlQa/MongodbToMysqlQa.py
Traceback (most recent call last):
  File "processData/mysqlQa/MongodbToMysqlQa.py", line 16, in &lt;module&gt;
    from util import configs
ImportError: No module named 'util'
</code>

加了-m也不对:

<code>(debug_nlp-wDGPvi3o) [root@xx-general-01 debug_nlp]# python -m processData/mysqlQa/MongodbToMysqlQa.py
/root/.local/share/virtualenvs/debug_xx-wDGPvi3o/bin/python: Error while finding spec for 'processData/mysqlQa/MongodbToMysqlQa.py' (&lt;class 'ImportError'&gt;: No module named 'processData/mysqlQa/MongodbToMysqlQa')
</code>

还是好好看看:

https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time

python 相对路径导入 No module named

Python 相对导入与绝对导入

python项目内import其他内部package的模块的正确方法 – CSDN博客

Python相对导入一处不解 – SegmentFault 思否

关于 python ImportError: No module named 的问题 – leejun2005的个人页面

通过:

Python导入模块的几种姿势| 编程派 | Coding Python

感觉是:

“某个包中的一个模块,而你试图以脚本模式执行,但是这种模式不支持相对导入。”

所以只能用sys.path.append加上path的方式去解决。

另外,感觉之前PyCharm中之所以可以正常运行,可能是因为:

在Debug调试配置中,有:

  • Add content roots to PYTHONPATH

  • Add source roots to PYTHONPATH

或许就是把相关路径加入到Python的Path中,使得可以正常运行代码的。

所以就去试试sys.path.append吧

结果试了试:

在项目根目录去-m运行

在项目根目录的父目录去-m运行

去给各级文件夹都加上__init__.py

都还是不行:

<code>(debug_nlp-wDGPvi3o) [root@xx-general-01 debug_nlp]# python -m processData.mysqlQa.MongodbToMysqlQa
currentPath=/xxx/debug_nlp/processData/mysqlQa
projectRootPath=/xxx/debug_nlp
utilLibPath=/xx/debug_nlp/util
crifanLibPath=/xx/debug_nlp/util/crifanLib
crifanBeautifulSoup: Can not found lib BeautifulSoup
crifanString: Can not found lib chardet
crifanString: Can not found lib chardet
currentPath=/xxx/debug_nlp/util/crifanLib
parentPath=/xxx/debug_nlp/util
Traceback (most recent call last):
  File "/usr/lib64/python3.4/runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib64/python3.4/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/xxx/debug_nlp/processData/mysqlQa/MongodbToMysqlQa.py", line 24, in &lt;module&gt;
    from util import configs
  File "/xxx/util/__init__.py", line 1, in &lt;module&gt;
    from . import crifanLib
  File "/xxx/util/crifanLib/__init__.py", line 1, in &lt;module&gt;
    from . import crifanBeautifulsoup
  File "/xxx/util/crifanLib/crifanBeautifulsoup.py", line 23, in &lt;module&gt;
    from . import crifanList
  File "/xxx/util/crifanLib/crifanList.py", line 18, in &lt;module&gt;
    from . import crifanString
  File "/xxx/util/crifanLib/crifanString.py", line 35, in &lt;module&gt;
    from . import crifanHttp
  File "/xxx/util/crifanLib/crifanHttp.py", line 32, in &lt;module&gt;
    from ..crifanLib import crifanFile
  File "/xxx/util/crifanLib/crifanFile.py", line 27, in &lt;module&gt;
    from . import crifanList
ImportError: cannot import name 'crifanList'

(debug_nlp-wDGPvi3o) [root@xx-general-01 nlp]# python -m debug_nlp.processData.mysqlQa.MongodbToMysqlQa
currentPath=/xxx/processData/mysqlQa
projectRootPath=/xxx/debug_nlp
utilLibPath=/xxx/util
crifanLibPath=/xxx/util/crifanLib
crifanBeautifulSoup: Can not found lib BeautifulSoup
crifanString: Can not found lib chardet
crifanString: Can not found lib chardet
currentPath=/xxx/util/crifanLib
parentPath=/xxx/util
Traceback (most recent call last):
  File "/usr/lib64/python3.4/runpy.py", line 170, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib64/python3.4/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/xxx/processData/mysqlQa/MongodbToMysqlQa.py", line 24, in &lt;module&gt;
    from util import configs
  File "/xxx/util/__init__.py", line 1, in &lt;module&gt;
    from . import crifanLib
  File "/xxx/util/crifanLib/__init__.py", line 1, in &lt;module&gt;
    from . import crifanBeautifulsoup
  File "/xxxx/util/crifanLib/crifanBeautifulsoup.py", line 23, in &lt;module&gt;
    from . import crifanList
  File "/xxx/util/crifanLib/crifanList.py", line 18, in &lt;module&gt;
    from . import crifanString
  File "/xxx/util/crifanLib/crifanString.py", line 35, in &lt;module&gt;
    from . import crifanHttp
  File "/xxx/util/crifanLib/crifanHttp.py", line 31, in &lt;module&gt;
    from . import crifanFile
  File "/xxx/util/crifanLib/crifanFile.py", line 31, in &lt;module&gt;
    from . import crifanList
ImportError: cannot import name 'crifanList'
</code>

试了半天, 还是无法导入

util/crifanLib/crifanFile.py

<code>import os
import sys
# currentPath = os.path.abspath(".")
# -&gt; currentPath=/xxx/processData/mysqlQa
# -&gt; only get the path where you run python, not current file path
currentPath = os.path.split(os.path.realpath(__file__))[0]
# currentPath=/xxx/util/crifanLib
print("currentPath=%s" % currentPath)
utilPath = os.path.abspath(os.path.join(currentPath, ".."))
# utilPath=/xxx/util
print("utilPath=%s" % utilPath)
projectRootPath = os.path.abspath(os.path.join(utilPath, ".."))
print("projectRootPath=%s" % projectRootPath)
projectParentPath = os.path.abspath(os.path.join(projectRootPath, ".."))
print("projectParentPath=%s" % projectParentPath)
sys.path.append(currentPath)
sys.path.append(utilPath)
sys.path.append(projectRootPath)
sys.path.append(projectParentPath)

# from . import crifanList
# from . crifanList import uniqueList
# from crifanLib import crifanList
# from util.crifanLib import crifanList
# from xx.util.crifanLib import crifanList

from .. crifanLib import crifanList
</code>

现在属于:

对于crifanLib中,所有的路径都加上了,但是crifanFile中,还是无法导入crifanLib同级目录下的另外一个库:crifanList

python 3 sys.path.append import still not work

Python sys.path modification not working – Stack Overflow

[Tutor] sys.path.append import python3 not working

How to add a Python module to syspath? – Ask Ubuntu

【已解决】Linux列出文件夹和文件的目录结构树

期间:

【已解决】Python中两个星号**参数去传递给函数出错:SyntaxError invalid syntax

对于此处的目录结构:

<code>(debug_nlp-wDGPvi3o) [root@xx-general-01 xx]# tree -CF
.
├── conf/
│   └── main.conf
├── __init__.py
├── xxx/
│   └── dialog/
│       ├── AccessData.py
│       ├── Analyzer.py
│       ├── config/
│       │   └── config.ini
│       ├── data/
│       │   ├── __init__.py
│       │   └── reply.txt
│       ├── DialogueManager.py
│       ├── files/
│       │   ├── control.txt
│       │   └── test.txt
│       ├── GenerateResponse.py
│       ├── __init__.py
│       ├── intent.py
│       ├── SearchData.py
│       └── tmp.py
├── Pipfile
├── Pipfile.lock
├── processData/
│   ├── __init__.py
│   ├── mysqlQa/
│   │   ├── __init__.py
│   │   ├── MongodbToMysqlQa.py
│   │   ├── README.md
│   │   └── vocabulary.txt
│   ├── mysqlThesaurus/
│   │   ├── vocabularyToMysql.py
│   │   └── \350\257\215\346\261\207\350\241\250\ 180531.xlsx
│   └── other/
│       └── to_delete/
│           ├── resource.2018.1.29.xlsx
│           ├── resource.xlsx
│           └── xlstomysql.py
├── README.md
└── util/
    ├── configs.py
    ├── crifanLib/
    │   ├── crifanBeautifulsoup.py
    │   ├── crifanCookie.py
    │   ├── crifanDatetime.py
    │   ├── crifanEmail.py
    │   ├── crifanFile.py
    │   ├── crifanGeography.py
    │   ├── crifanHtml.py
    │   ├── crifanHttp.py
    │   ├── crifanList.py
    │   ├── crifanLogging.py
    │   ├── crifanMath.py
    │   ├── crifanMysql.py
    │   ├── crifanOpenpyxl.py
    │   ├── crifanString.py
    │   ├── crifanSystem.py
    │   ├── crifanTemplate.py
    │   ├── crifanUrl.py
    │   └── __init__.py
    ├── dbcon.py
    ├── __init__.py
    └── paths.py

13 directories, 50 files
</code>

然后对于:

想要运行:

processData/mysqlQa/MongodbToMysqlQa.py

去作为普通的python文件去运行,去处理数据的,

其中调用到了util中的库crifanLib中的其他sub的库,比如:crifanFile, crifanLogging, crifanMysql

本来以为搞懂了,结果刚刚发现:

此处实际上,至少包含了,递归导入的问题:

【已解决】Python中递归import导入:ImportError: cannot import name

而解决了递归导入的问题后,则就顺带解决了此处的问题

然后通过模块去运行的话,不论是在项目根目录:

<code>(xxx-VJ297lRu) [root@xx-general-01 xx]# pwd
/root/xxx
(xx-VJ297lRu) [root@xxx-general-01 xx]# python -m processData.mysqlQa.MongodbToMysqlQa
---------- CurrentFile: processData/mysqlQa/MongodbToMysqlQa.py
currentPath=/xxx/processData/mysqlQa
projectRootPath=/root/xxx
utilPath=/xxxx/util
crifanLibPath=/xxx/util/crifanLib
crifanString: Can not found lib chardet
curFolderPath=/xxx/util
projectRootPath=/xxx/util/..
projectRootAbsPath=/xxx
mainConfFileFullPath=/xxx/conf/main.conf
</code>

还是在项目根目录的父目录:

<code>(xxx-VJ297lRu) [root@xxx-general-01 nlp]# pwd
/root/xx/nlp
(xxx-VJ297lRu) [root@xxx-general-01 nlp]# python -m xxx.processData.mysqlQa.MongodbToMysqlQa
---------- CurrentFile: processData/mysqlQa/MongodbToMysqlQa.py
currentPath=/root/xxx/processData/mysqlQa
projectRootPath=/root/xxx
utilPath=/root/xxx/util
crifanLibPath=/root/xxx/util/crifanLib
crifanString: Can not found lib chardet
curFolderPath=/root/xxx/util
projectRootPath=/root/xxx/util/..
projectRootAbsPath=/root/xxx
mainConfFileFullPath=/root/xxx/conf/main.conf
</code>

都可以正常运行了。

【总结】

此处,在确保没有递归导入的前提下:

【已解决】Python中递归import导入:ImportError: cannot import name

对于如下目录结构:

<code>└── xxxx/
    ├── conf/
    │   └── main.conf
    ├── __init__.py
    ├── Pipfile
    ├── Pipfile.lock
    ├── processData/
    │   ├── __init__.py
    │   ├── mysqlQa/
    │   │   ├── MongodbToMysqlQa.py
    │   │   ├── README.md
    │   │   └── vocabulary.txt
...
    ├── README.md
    └── util/
        ├── configs.py
        ├── crifanLib/
        │   ├── crifanBeautifulsoup.py
        │   ├── crifanCookie.py
        │   ├── crifanDatetime.py
        │   ├── crifanEmail.py
        │   ├── crifanFile.py
        │   ├── crifanGeography.py
        │   ├── crifanHtml.py
        │   ├── crifanHttp.py
        │   ├── crifanList.py
        │   ├── crifanLogging.py
        │   ├── crifanMath.py
        │   ├── crifanMysql.py
        │   ├── crifanOpenpyxl.py
        │   ├── crifanString.py
        │   ├── crifanSystem.py
        │   ├── crifanTemplate.py
        │   ├── crifanUrl.py
        │   └── __init__.py
        ├── dbcon.py
        ├── __init__.py
        └── paths.py
</code>

需求是:

processData/mysqlQa/MongodbToMysqlQa.py

去作为普通的python文件去运行,作用是去处理数据的

而其中调用到了util中的库crifanLib中的其他sub的库,比如:crifanFile, crifanLogging, crifanMysql

然后对于导入路径的,基本的思路是:

在此处调用别人的地方,比如MongodbToMysqlQa.py中,要包含对应的被导入的库的路径

所以如果MongodbToMysqlQa.py中这么写:

<code>import os
import sys
print("---------- CurrentFile: processData/mysqlQa/MongodbToMysqlQa.py")
currentPath = os.path.split(os.path.realpath(__file__))[0]
print("currentPath=%s" % currentPath)
projectRootPath = os.path.abspath(os.path.join(currentPath, '../..'))
print("projectRootPath=%s" % projectRootPath)
utilPath = os.path.join(projectRootPath, 'util')
print("utilPath=%s" % utilPath)
sys.path.append(projectRootPath)
sys.path.append(utilPath)
from util import configs, paths
from util.crifanLib import crifanFile, crifanLogging, crifanMysql
</code>

也就是可以的。

注意,其中此处包含了,crifanLib的父目录=util的目录

这样后续crifanLib才能导入,否则即使直接包含了crifanLibPath:

<code>crifanLibPath = os.path.join(utilPath, 'crifanLib')
print("crifanLibPath=%s" % crifanLibPath)
</code>

也不行,也是找不到后续的util和util.crifanLib的。

而此时的:

util/__init__.py

util/crifanLib/__init__.py

都是空的。

而为了更加优化的处理,把相关的导入路径,分别写在自己的模块中的__init__.py中,改为:

util/__init__.py

<code>import os
import sys
print("--------- %s" % __file__)
currentUtilPath = os.path.split(os.path.realpath(__file__))[0]
print("currentUtilPath=%s" % currentUtilPath)
sys.path.append(currentUtilPath)
</code>

util/crifanLib/__init__.py

<code>import os
import sys
print("--------- %s" % __file__)
currentCrifanLibPath = os.path.split(os.path.realpath(__file__))[0]
print("currentCrifanLibPath=%s" % currentCrifanLibPath)
sys.path.append(currentCrifanLibPath)
</code>

然后之前调用此处代码的地方,就不需要包含对应路径了:

processData/mysqlQa/MongodbToMysqlQa.py

<code>import os
import sys
print("---------- CurrentFile: processData/mysqlQa/MongodbToMysqlQa.py")
currentPath = os.path.split(os.path.realpath(__file__))[0]
print("currentPath=%s" % currentPath)
projectRootPath = os.path.abspath(os.path.join(currentPath, '../..'))
print("projectRootPath=%s" % projectRootPath)
sys.path.append(projectRootPath)

from util import configs, paths
from util.crifanLib import crifanFile, crifanLogging, crifanMysql
</code>

然后也是可以正常运行MongodbToMysqlQa.py的:

在项目根目录的父目录:

<code>(xx-VJ297lRu) [root@xx-general-01 nlp]# pwd
/root/xx/nlp
python -m xx.processData.mysqlQa.MongodbToMysqlQa
</code>

 在项目的根目录中:

<code>(xx-VJ297lRu) [root@xx-general-01 xx]# pwd
/root/xx/nlp/xx
python -m processData.mysqlQa.MongodbToMysqlQa
</code>

都可以正常运行的。

提示:

只不过,之前log文件生成在MongodbToMysqlQa.py所在的同级目录:

/root/xx/nlp/xx/processData/mysqlQa/

下的,现在改为当前运行时候的目录下:

/root/xx/nlp/xx

了。

总而言之,对于:

  • 别的库,要尽量包含自己的路径

比如:

(1)顶层的util

util/__init__.py

<code>import os
import sys
print("--------- %s" % __file__)
currentUtilPath = os.path.split(os.path.realpath(__file__))[0]
print("currentUtilPath=%s" % currentUtilPath)
sys.path.append(currentUtilPath)
</code>
  • 以及库下面的子模块中,其导入方式,尽量以绝对路径导入:

(2)util下面的crifanLib

util/crifanLib/__init__.py

<code>import os
import sys
print("--------- %s" % __file__)
currentCrifanLibPath = os.path.split(os.path.realpath(__file__))[0]
print("currentCrifanLibPath=%s" % currentCrifanLibPath)
sys.path.append(currentCrifanLibPath)
</code>

(3)crifanLib下面的

util/crifanLib/crifanFile.py

中的:

<code>import crifanLib.crifanList
</code>

然后:

而别的(或许是,或许不是 模块的)python文件中,去调用该库的话,则需要包含对应的路径:

processData/mysqlQa/MongodbToMysqlQa.py

<code>import os
import sys
print("---------- CurrentFile: processData/mysqlQa/MongodbToMysqlQa.py")
currentPath = os.path.split(os.path.realpath(__file__))[0]
print("currentPath=%s" % currentPath)
projectRootPath = os.path.abspath(os.path.join(currentPath, '../..'))
print("projectRootPath=%s" % projectRootPath)
sys.path.append(projectRootPath)

from util import configs, paths
from util.crifanLib import crifanFile, crifanLogging, crifanMysql
</code>

即可正常导入和运行,不会出现import的错误,也不会出现递归导入的错误。

转载请注明:在路上 » 【已解决】python中的相对路径导入库失败No module named

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
82 queries in 0.177 seconds, using 22.16MB memory