不关心故事背景的朋友们可以直接跳到“解决方案”~

文章目录

  • 故事背景
  • 历史方案
  • 解决方案

故事背景

最近在用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失效解决方案相关推荐

  1. pytorch .item_从数据到模型,你可能需要1篇详实的pytorch踩坑指南

    原创 · 作者 | Giant 学校 | 浙江大学 研究方向 | 对话系统.text2sql 熟悉DL的朋友应该知道Tensorflow.Pytorch.Caffe这些成熟的框架,它们让广大AI爱好者 ...

  2. Git Commit Message校验踩坑指南

    背景 在团队多人开发中,规范的commit message可以快速定位代码提交历史,回溯问题根源,方便组内多人协作,提高团队效率. 本篇文章主要包含以下两方面内容: commitizen/cz-cli ...

  3. vue1升级vue2踩坑指南

    vue1升级vue2踩坑指南 升级原因 版本选择 老的package.json: 新的package.json: vue官方说明 语法/组件使用变化 ready钩子 $index & $key ...

  4. weex 一个传说级巨坑-- 2018最新版weex踩坑指南(weex navigator 多界面跳转)

    先说结论,本人极度非常 不推荐weex作为任何商用开发 有很多人会说了... 你瞎扯.. 你看别人阿里.. 啊飞猪... 啊那个支付宝... 人家不是用得好好的么... 当然这也是我们公司作为技术选型 ...

  5. 安装 JupyterHub 踩坑指南 —— 如何通过 JupyterHub 实现多用户管理

    安装 JupyterHub 踩坑指南 JupyterHub 简介 Jupyter Notebook and JupyterLab Jupyter Notebook 简介 JupyterLab 简介 安 ...

  6. python模块搜索路径 (sys.path)

    导入一个叫 spam 的模块时,解释器先在当前目录中搜索名为 spam.py 的文件,然后在环境变量 PYTHONPATH 表示的目录列表中搜索,然后是环境变量 PATH 中的路径列表.如果 PYTH ...

  7. Spring Cloud踩坑指南

    Spring Cloud踩坑指南 1 Spring Cloud搭建 参考 Spring Cloud 微服务技术栈:搭建高可用 Eureka Server.服务注册与发现 2 常见问题 2.1 修改ho ...

  8. 阿里云天池【Docker练习场】踩坑指南

    阿里云天池[Docker练习场]踩坑指南 题目直达 提交环境搭建(基于macOS) Docker的安装与基本功能使用 Docker安装过程遇到的小问题 提交结果注意事项 提交时的镜像配置 项目结构规范 ...

  9. android手机屏幕共享神器踩坑指南

    开源项目地址:https://github.com/Genymobile/scrcpy scrcpy,由 Genymobile 推出的可跨平台的.可自定义码率的.开源的屏幕共享工具.它提供了在 USB ...

最新文章

  1. 图解Spring解决循环依赖
  2. 红帽技术开放日:参与开源社区不只有贡献代码这一种方式
  3. python图形用户界面设计报告_19.1 Python图形用户界面开发工具包
  4. 《JavaScript凌厉开发 Ext详解与实践》3月5日开始上架销售
  5. python之.py生成.exe可执行文件
  6. java调用keras theano模型_使用Keras / Theano和LSTM进行多标签文本分类
  7. java正则匹配英文句号_「正则表达式」王国奇遇记
  8. 有没有哪种贷款不用利息,而且门槛又低?
  9. C#中const和readonly的区别
  10. linux脚本调用job,linux shell - 脚本中调用fg调取后台任务报错
  11. 监控IIS的运行状态
  12. DELPHIER,正转向PYTHON了
  13. axis2远程调用webservice例子(返回xml用dom4j解析)
  14. C语言相关问题(1)
  15. 三星SOC的显示控制器及framebuffer驱动s3c-fb.c中probe函数分析
  16. 清除Chrome的缓存、Cookie
  17. uwe5622 uwe5621ds 紫光展锐 wifi 移植的几个关键点:
  18. R语言学习:方差分析
  19. 简单几步轻松获取WiFi密码
  20. 如何理解面向对象思维?

热门文章

  1. 嵌入式课程之C语言知识点
  2. SWC_RTE02-AutoSAR架构【AutoSAR架构设计概述2】
  3. Nginx 限速模块一览
  4. FreeFileSync 同步自动备份RealTimeSync(自动同步工具)
  5. PyCharm里面的c、m、F、f、v、p分别代表什么含义?
  6. 商业软件linux下闭源,如何发布使用LGPL版Qt的商业软件
  7. Spring Security系列教程18--会话管理之防御固定会话攻击
  8. POI打印-----文件下载
  9. 热电阻的两线制、三线制与四线制接法
  10. Dirac HD Sound介绍