一 写在前面
未经允许,不得转载,谢谢~~~
2020的第一篇博客就献给踩过的第一个坑吧 (〃´-ω・)
大家新年快乐!新的一年冲鸭~~~
二 最简单的import情况
日常情况下我们自己写程序一般就会碰到以下两种情况的代码调用:
1. 同级目录
这是最简单的一种情况。
例如同级目录下的main.py
要调用model.py
,那么直接import
即可。
Projects/
- main.py
- model.py
2. 子级目录
这也是很常见的一种情况。
例如根目录下的main.py
要调用models
子集目录下的p3d.py
。
- 首先在
models
文件夹下新建一个__init__.py
文件,空即可。 - 然后在
main.py
中即可import models.p3d
,from models.p3d import xx
Projects/
- main.py
- models/
- p3d.py
- c3d.py
- i3d.py
三 比较复杂的package调用情况
3.1 场景描述:
以上的两种情况基本都是所有的代码都是自己写的这种情况,但我们有的时候需要从github上扒一份别人的代码作整个项目里面的一个component,这种时候就没有那么方便。
通常下载的代码本身就有很多相互代码之间的相互调用关系,所以不能轻易改变其路径,不然你可能需要挨个修改每个的调用。
当然最简单的方法是将你自己的东西全部放在他的目录结构里面去,例如在这个例子中将main.py
挪到detectron
中,将detectron
作为你的项目主目录,但是这样子会破坏代码的结构性,不是很推荐。
例如detectron是原本独立的一份项目代码,我现在想将其加到我的Projects里面:
(具体目录结构如下示意)
Projects/
- main.py
- detectron/
- demo/
- demo.py
- predict.py
- detectron/
- backbones/
- xxx.py
- ...
- detection/
- xxx.py
- ...
- __init__.py
3.2 解决思路:
- 那么第一件是在
detectron
中加入__init__
,标注其为package - 这个时候理论上来说我可以
main.py
中用import detectron.demo.predict
的形式来调用predict
中的内容。 - 但以上的情况仅限于
predict.py
里面没有调用其他detectron
中的代码文件的情况,这一点对于一个集成性比较好的package是不可能的。会出错的原因在于在predict.py
中调用其他的代码文件的时候是从它自己原来的主目录开始的,例如在它里面可能会通过import detectron.backbones.xxx
的形式来调用backbones下的代码。 - 但是我们在
main.py
中去执行代码的时候,上面的方式就会出错,完整的应该是import detectron.detectron.backbones.xxx
- 所以解决方法有两个:
- 1: 将所有原来代码中的import语句前面补上一个路径,即从:
import detectron.backbones.xxx
-->import detectron.detectron.backbones.xxx
(推荐代码量小的情况使用) - 解决路径检索不到的问题:
import sys # add the path of detectron to your Projects sys.path.append('./detectron')
- 1: 将所有原来代码中的import语句前面补上一个路径,即从:
3.3 彩蛋:BUG
没想到还有吧哈哈哈哈哈!
正常情况下用sys
将路径append进来以后就没有什么关系了,但是文章开头就是为了记录坑,在这个意义上前面的内容全是铺垫。/捂脸
这个BUG昨天找了将近2个小时─━ _ ─━✧
细心的同学可能注意到detectron
有两个重名目录,一个是原本的主目录detectron/
,一个是原来主目录下的子目录detectron/detecron/
。这种情况如果将其作为独立的代码来看是完全没有问题的。但是在将原来的主目录放在Projects/
下面的时候就出现问题了==
具体的表现在于我用sys.path.append的方式将detectron/
加到路径里,正常情况下就可以不修改原来的import detectron.backbones.xxx
的调用方式找到backbones里面的文件。
但是!!由于两个目录重名,所以在搜索的时候每次搜到上面那个detectron
就停掉了,不会检索到下面的detectron
。
解决方法:
修改重名目录中的其中一个目录名。
四 写在最后
暂时就先写到这里吧
其实中间还尝试过想直接用过用subprocess.call
来调用python xxx.py
的方式来避免上面的问题,但是这样的问题是只能执行该文件,输出的结果只会打印在屏幕,么有办法直接将想要的结果return回来。
希望新的一年有时间多写一些blog(立个FLAG哈哈哈)