之前已经在PyCharm中,本地调试期间,解决了相对路径导入的问题:
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 <module> 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 <module> 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' (<class 'ImportError'>: No module named 'processData/mysqlQa/MongodbToMysqlQa') </code>
还是好好看看:
https://stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time
python 相对路径导入 No module named
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 <module> from util import configs File "/xxx/util/__init__.py", line 1, in <module> from . import crifanLib File "/xxx/util/crifanLib/__init__.py", line 1, in <module> from . import crifanBeautifulsoup File "/xxx/util/crifanLib/crifanBeautifulsoup.py", line 23, in <module> from . import crifanList File "/xxx/util/crifanLib/crifanList.py", line 18, in <module> from . import crifanString File "/xxx/util/crifanLib/crifanString.py", line 35, in <module> from . import crifanHttp File "/xxx/util/crifanLib/crifanHttp.py", line 32, in <module> from ..crifanLib import crifanFile File "/xxx/util/crifanLib/crifanFile.py", line 27, in <module> 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 <module> from util import configs File "/xxx/util/__init__.py", line 1, in <module> from . import crifanLib File "/xxx/util/crifanLib/__init__.py", line 1, in <module> from . import crifanBeautifulsoup File "/xxxx/util/crifanLib/crifanBeautifulsoup.py", line 23, in <module> from . import crifanList File "/xxx/util/crifanLib/crifanList.py", line 18, in <module> from . import crifanString File "/xxx/util/crifanLib/crifanString.py", line 35, in <module> from . import crifanHttp File "/xxx/util/crifanLib/crifanHttp.py", line 31, in <module> from . import crifanFile File "/xxx/util/crifanLib/crifanFile.py", line 31, in <module> from . import crifanList ImportError: cannot import name 'crifanList' </code>
试了半天, 还是无法导入
util/crifanLib/crifanFile.py
<code>import 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 </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
期间:
【已解决】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的错误,也不会出现递归导入的错误。