python import 踩坑指南 / sys.path失效解决方案
不关心故事背景的朋友们可以直接跳到“解决方案”~
文章目录
- 故事背景
- 历史方案
- 解决方案
故事背景
最近在用thrift的时候遇到一个问题,thrift生成的python文件之间的引用都是相对引用的:
thrift_folder
├── base
│ ├── constants.py
│ ├── __init__.py
│ └── ttypes.py
├── model
│ ├── __init__.py
│ ├── constants.py
│ ├── ttypes.py# model/ttypes.py
import base.ttypes
如果python起始运行文件路径不在thrift_folder内,那么引用就会有错误。
历史方案
老前辈们提供了两种解决方案
- 修改所有的import
- 修改os.path
前者的问题在于,即使用脚本在每个thrift前面写from thrift_folder import base(不能图省事先加一个__all__ = bulabula然后from thrift_folder import *,这样可能会循环引用),在thrift文件里面还是会藏着很多base.ttypes.XXX的鬼东西,需要一个个改……第一位老前辈就一个个改完了。当然可能他的thrift很少,我现在看着几十万行的thrift真的改不了= =
后者的问题在于os.path可能失效,这是为啥呢,请看下文分解——
解决方案
坑1:sys.path不能用append
在查找modules的位置时,python按照sys.path顺次查询,如果你用了append,很可能引用到了其他的模块。那么解决方案是
sys.path.insert(0,thrift_folder)
坑2:sys.modules缓存路径(insert0还是不行啊喂)
python在import module前,先会去sys.modules看看曾经有没有导入过这个模块,这是一个类似于modules path cache的地方。模块在sys.modules中不代表当前文件能调用它(可能是其他文件的代码中import了,然后把sys.modules更新了);但是调用新模块的时候会优先查找sys.modules有没有,有的话就不管sys.path了,直接从这里导入… 【想了好久也没懂这个机制可能快一丢丢之外有什么用途】
于是需要查看一下sys.modules有没有曾经导入模块留下的痕迹,如果有的话需要把它们都解决掉,这样就可以正常引用啦~ 当然,成功导入thrift之后别忘记把原来的sys.modules/sys.path还原。
# 如果在该模块导入之前有过import lv_thrift下的子模块同名模块,会导致从
# sys.modules中加载路径,所以同时对sys.modules进行修改
import_modules = [ 'base', 'model' ...]
import_modules += [s+'.ttypes' for s in import_modules]
sys_modules_backup = dict()
for mod in import_modules:if sys.modules.has_key(mod):sys_modules_backup[mod] = sys.modules[mod]del sys.modules[mod]
full_path = os.path.realpath(__file__)
thrift_path = os.path.join(os.path.dirname(full_path),"thrift_folder")
sys.path.insert(0,thrift_path)# import thrift
from base import xxx
from model import yyy
from model.ttypes import zzz
...# 恢复sys.path & sys.modules
sys.path.remove(thrift_path)
for mod,path in sys_modules_backup.items():sys.modules[mod] = path
python import 踩坑指南 / sys.path失效解决方案相关推荐
- pytorch .item_从数据到模型,你可能需要1篇详实的pytorch踩坑指南
原创 · 作者 | Giant 学校 | 浙江大学 研究方向 | 对话系统.text2sql 熟悉DL的朋友应该知道Tensorflow.Pytorch.Caffe这些成熟的框架,它们让广大AI爱好者 ...
- Git Commit Message校验踩坑指南
背景 在团队多人开发中,规范的commit message可以快速定位代码提交历史,回溯问题根源,方便组内多人协作,提高团队效率. 本篇文章主要包含以下两方面内容: commitizen/cz-cli ...
- vue1升级vue2踩坑指南
vue1升级vue2踩坑指南 升级原因 版本选择 老的package.json: 新的package.json: vue官方说明 语法/组件使用变化 ready钩子 $index & $key ...
- weex 一个传说级巨坑-- 2018最新版weex踩坑指南(weex navigator 多界面跳转)
先说结论,本人极度非常 不推荐weex作为任何商用开发 有很多人会说了... 你瞎扯.. 你看别人阿里.. 啊飞猪... 啊那个支付宝... 人家不是用得好好的么... 当然这也是我们公司作为技术选型 ...
- 安装 JupyterHub 踩坑指南 —— 如何通过 JupyterHub 实现多用户管理
安装 JupyterHub 踩坑指南 JupyterHub 简介 Jupyter Notebook and JupyterLab Jupyter Notebook 简介 JupyterLab 简介 安 ...
- python模块搜索路径 (sys.path)
导入一个叫 spam 的模块时,解释器先在当前目录中搜索名为 spam.py 的文件,然后在环境变量 PYTHONPATH 表示的目录列表中搜索,然后是环境变量 PATH 中的路径列表.如果 PYTH ...
- Spring Cloud踩坑指南
Spring Cloud踩坑指南 1 Spring Cloud搭建 参考 Spring Cloud 微服务技术栈:搭建高可用 Eureka Server.服务注册与发现 2 常见问题 2.1 修改ho ...
- 阿里云天池【Docker练习场】踩坑指南
阿里云天池[Docker练习场]踩坑指南 题目直达 提交环境搭建(基于macOS) Docker的安装与基本功能使用 Docker安装过程遇到的小问题 提交结果注意事项 提交时的镜像配置 项目结构规范 ...
- android手机屏幕共享神器踩坑指南
开源项目地址:https://github.com/Genymobile/scrcpy scrcpy,由 Genymobile 推出的可跨平台的.可自定义码率的.开源的屏幕共享工具.它提供了在 USB ...
最新文章
- 图解Spring解决循环依赖
- 红帽技术开放日:参与开源社区不只有贡献代码这一种方式
- python图形用户界面设计报告_19.1 Python图形用户界面开发工具包
- 《JavaScript凌厉开发 Ext详解与实践》3月5日开始上架销售
- python之.py生成.exe可执行文件
- java调用keras theano模型_使用Keras / Theano和LSTM进行多标签文本分类
- java正则匹配英文句号_「正则表达式」王国奇遇记
- 有没有哪种贷款不用利息,而且门槛又低?
- C#中const和readonly的区别
- linux脚本调用job,linux shell - 脚本中调用fg调取后台任务报错
- 监控IIS的运行状态
- DELPHIER,正转向PYTHON了
- axis2远程调用webservice例子(返回xml用dom4j解析)
- C语言相关问题(1)
- 三星SOC的显示控制器及framebuffer驱动s3c-fb.c中probe函数分析
- 清除Chrome的缓存、Cookie
- uwe5622 uwe5621ds 紫光展锐 wifi 移植的几个关键点:
- R语言学习:方差分析
- 简单几步轻松获取WiFi密码
- 如何理解面向对象思维?