折腾:
【已解决】python中的相对路径导入库失败No module named
期间,从错误信息中可以看到:
<code>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 30, in <module> from util.crifanLib import crifanFile, crifanLogging, crifanMysql File "/xxx/util/crifanLib/crifanFile.py", line 53, 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 26, in <module> from . import crifanFile ImportError: cannot import name 'crifanFile' </code>
发现此处实际上好像变成了:递归导入import的问题
具体很明显:
crifanFile导入了:crifanList
crifanList导入了:crifanString
crifanString导入了:crifanHttp
crifanHttp导入了:crifanFile
需要想办法规避此问题
python recursive ImportError
class – Resolve circular import error in python – Stack Overflow
Circular (or cyclic) imports in Python – Stack Overflow
Circular imports in Python 2 and Python 3: when are they fatal? When do they work?
Circular import errors – Reinout van Rees
只导入需要用到的函数,貌似可以解决,但是不想去这么改
python – How to catch an ImportError non-recursively? – Stack Overflow
python avoid circular imports
python 避免 循环 递归 导入
延迟导入:
用到时,内部再导入
暂时看来,貌似也是一种办法,虽然也觉得不是很完美
另外,竟然Python官网说:
- 建议用:import X
- 不是很建议用:
- from module import *
- from module import a,b,c
How do you avoid circular imports in Python? – Stack Overflow
How to avoid circular imports in Python? – Stack Overflow
<code>/package __init__.py a.py b.py </code>
避免循环导入的写法有:
<code>import package.a # Absolute import import a # Implicit relative import (deprecated, py2 only) </code>
所以此处去改为:
都加上crifanLib.xxx
试试:
util/crifanLib/crifanFile.py
<code># from . import crifanList import crifanLib.crifanList </code>
util/crifanLib/crifanList.py
<code># from . import crifanString import crifanLib.crifanString </code>
util/crifanLib/crifanString.py
<code># from . import crifanMath # from . import crifanHttp # from . import crifanSystem import crifanLib.crifanMath import crifanLib.crifanHttp import crifanLib.crifanSystem </code>
util/crifanLib/crifanHttp.py
<code># from . import crifanFile import crifanLib.crifanFile </code>
结果:
就解决了此递归循环导入的问题。
【总结】
此处的文件结构是:
<code>(xx-VJ297lRu) [root@xxx-general-01 crifanLib]# tree -CF . ├── 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 0 directories, 18 files (xx-VJ297lRu) [root@xx-general-01 crifanLib]# pwd /root/xx/nlp/xx/util/crifanLib (xx-VJ297lRu) [root@xx-general-01 crifanLib]# </code>
其中,存在循环、递归导入的问题,如之前所列:
- crifanFile导入了:crifanList
- crifanList导入了:crifanString
- crifanString导入了:crifanHttp
- crifanHttp导入了crifanFile
而解决递归导入的办法,有几种:
方法1:用的时候再导入 -》把文件顶部的导入,移动到具体文件内部用到别人库的函数的地方,再导入
缺点:麻烦,不利于直观看到引用了哪些库
方法2:改为 from someOtherLib import someFunction
缺点:如果用到多个函数,要写多个
注:貌似据说Python官网中竟然是:
- 建议用:import X
- 不是很建议用:
- from module import *
- from module import a,b,c
-》和之前的认知,以为建议用:
from module import a,b,c
呢。
方法3:写成带模块名的绝对路径的导入
把:
<code>from . import crifanList </code>
改为:
<code>import crifanLib.crifanList </code>
即可。