之前已经在PyCharm中,本地调试期间,解决了相对路径导入的问题:
PyCharm中本地调试是可以导入的:
但是同样的代码:
processData/mysqlQa/MongodbToMysqlQa.py# 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
以及:
util/crifanLib/crifanHttp.pyfrom . import crifanFile
但是上传到服务器上后,去命令行中运行,就出错了:(debug_xx-wDGPvi3o) [root@xx-general-01 mysqlQa]# python MongodbToMysqlQa.py
Traceback (most recent call last):
File "MongodbToMysqlQa.py", line 16, in
from util import configs
ImportError: No module named 'util'
所以对于 相对路径的导入,看来还是理解的不够透彻
去搜:
python relative import No module named
试试回到项目根目录去试试,结果问题依旧:(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
from util import configs
ImportError: No module named 'util'
加了-m也不对:(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' (
还是好好看看:
python 相对路径导入 No module named
通过:
感觉是:
“某个包中的一个模块,而你试图以脚本模式执行,但是这种模式不支持相对导入。”
所以只能用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
都还是不行:(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
from util import configs
File "/xxx/util/__init__.py", line 1, in
from . import crifanLib
File "/xxx/util/crifanLib/__init__.py", line 1, in
from . import crifanBeautifulsoup
File "/xxx/util/crifanLib/crifanBeautifulsoup.py", line 23, in
from . import crifanList
File "/xxx/util/crifanLib/crifanList.py", line 18, in
from . import crifanString
File "/xxx/util/crifanLib/crifanString.py", line 35, in
from . import crifanHttp
File "/xxx/util/crifanLib/crifanHttp.py", line 32, in
from ..crifanLib import crifanFile
File "/xxx/util/crifanLib/crifanFile.py", line 27, in
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
from util import configs
File "/xxx/util/__init__.py", line 1, in
from . import crifanLib
File "/xxx/util/crifanLib/__init__.py", line 1, in
from . import crifanBeautifulsoup
File "/xxxx/util/crifanLib/crifanBeautifulsoup.py", line 23, in
from . import crifanList
File "/xxx/util/crifanLib/crifanList.py", line 18, in
from . import crifanString
File "/xxx/util/crifanLib/crifanString.py", line 35, in
from . import crifanHttp
File "/xxx/util/crifanLib/crifanHttp.py", line 31, in
from . import crifanFile
File "/xxx/util/crifanLib/crifanFile.py", line 31, in
from . import crifanList
ImportError: cannot import name 'crifanList'
试了半天, 还是无法导入
util/crifanLib/crifanFile.pyimport os
import sys
# currentPath = os.path.abspath(".")
# -> currentPath=/xxx/processData/mysqlQa
# -> 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
现在属于:
对于crifanLib中,所有的路径都加上了,但是crifanFile中,还是无法导入crifanLib同级目录下的另外一个库:crifanList
python 3 sys.path.append import still not work
期间:
对于此处的目录结构:(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
然后对于:
想要运行:
processData/mysqlQa/MongodbToMysqlQa.py
去作为普通的python文件去运行,去处理数据的,
其中调用到了util中的库crifanLib中的其他sub的库,比如:crifanFile, crifanLogging, crifanMysql
本来以为搞懂了,结果刚刚发现:
此处实际上,至少包含了,递归导入的问题:
而解决了递归导入的问题后,则就顺带解决了此处的问题
然后通过模块去运行的话,不论是在项目根目录:(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
还是在项目根目录的父目录:(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
都可以正常运行了。
【总结】
此处,在确保没有递归导入的前提下:
对于如下目录结构:└── 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
需求是:
processData/mysqlQa/MongodbToMysqlQa.py
去作为普通的python文件去运行,作用是去处理数据的
而其中调用到了util中的库crifanLib中的其他sub的库,比如:crifanFile, crifanLogging, crifanMysql
然后对于导入路径的,基本的思路是:
在此处调用别人的地方,比如MongodbToMysqlQa.py中,要包含对应的被导入的库的路径
所以如果MongodbToMysqlQa.py中这么写: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
也就是可以的。
注意,其中此处包含了,crifanLib的父目录=util的目录
这样后续crifanLib才能导入,否则即使直接包含了crifanLibPath:crifanLibPath = os.path.join(utilPath, 'crifanLib')
print("crifanLibPath=%s" % crifanLibPath)
也不行,也是找不到后续的util和util.crifanLib的。
而此时的:
util/__init__.py
和
util/crifanLib/__init__.py
都是空的。
而为了更加优化的处理,把相关的导入路径,分别写在自己的模块中的__init__.py中,改为:
util/__init__.pyimport os
import sys
print("--------- %s" % __file__)
currentUtilPath = os.path.split(os.path.realpath(__file__))[0]
print("currentUtilPath=%s" % currentUtilPath)
sys.path.append(currentUtilPath)
util/crifanLib/__init__.pyimport os
import sys
print("--------- %s" % __file__)
currentCrifanLibPath = os.path.split(os.path.realpath(__file__))[0]
print("currentCrifanLibPath=%s" % currentCrifanLibPath)
sys.path.append(currentCrifanLibPath)
然后之前调用此处代码的地方,就不需要包含对应路径了:
processData/mysqlQa/MongodbToMysqlQa.pyimport 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
然后也是可以正常运行MongodbToMysqlQa.py的:
在项目根目录的父目录:(xx-VJ297lRu) [root@xx-general-01 nlp]# pwd
/root/xx/nlp
python -m xx.processData.mysqlQa.MongodbToMysqlQa
在项目的根目录中:(xx-VJ297lRu) [root@xx-general-01 xx]# pwd
/root/xx/nlp/xx
python -m processData.mysqlQa.MongodbToMysqlQa
都可以正常运行的。
提示:
只不过,之前log文件生成在MongodbToMysqlQa.py所在的同级目录:
/root/xx/nlp/xx/processData/mysqlQa/
下的,现在改为当前运行时候的目录下:
/root/xx/nlp/xx
了。
总而言之,对于:别的库,要尽量包含自己的路径
比如:
(1)顶层的util
util/__init__.pyimport os
import sys
print("--------- %s" % __file__)
currentUtilPath = os.path.split(os.path.realpath(__file__))[0]
print("currentUtilPath=%s" % currentUtilPath)
sys.path.append(currentUtilPath)
以及库下面的子模块中,其导入方式,尽量以绝对路径导入:
(2)util下面的crifanLib
util/crifanLib/__init__.pyimport os
import sys
print("--------- %s" % __file__)
currentCrifanLibPath = os.path.split(os.path.realpath(__file__))[0]
print("currentCrifanLibPath=%s" % currentCrifanLibPath)
sys.path.append(currentCrifanLibPath)
(3)crifanLib下面的
util/crifanLib/crifanFile.py
中的:import crifanLib.crifanList
然后:
而别的(或许是,或许不是 模块的)python文件中,去调用该库的话,则需要包含对应的路径:
processData/mysqlQa/MongodbToMysqlQa.pyimport 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
即可正常导入和运行,不会出现import的错误,也不会出现递归导入的错误。