python 导入模块的坑。为什么整个项目能运行,单独运行某个文件模块就报错?多层目录不同文件夹怎么导入?

一些文章介绍了python不同目录怎么导入问题,但py文件运行起点却从来没有文章说过!这是相当重要的!!

这个连接是网上99%的所讲的导入 https://www.cnblogs.com/luoye00/p/5223543.html

网上99%都是讲x导入y模块,是以x为起点运行的,这和此篇角度完全不同。比如下面的从run开始运行,k怎么导入a,k怎么导入j,网上讲得都是直接运行k,如果用网上的方法来在k中写导入j和a,然后从run运行,k文件里面的导入一定会出错。

此篇以python3为例,python3和python2导入时候有一些区别,不讲python2。

python 导入模块的坑。为什么整个项目能运行,单独运行某个文件模块就报错?多层目录不同文件夹怎么导入?

整个项目如图上,整个项目从run文件运行起来。

dirx里面的__init__文件是空文件,如下图

python 导入模块的坑。为什么整个项目能运行,单独运行某个文件模块就报错?多层目录不同文件夹怎么导入?

a.py也是空文件,只是演示导入,就不写什么了。

pacx里面的

__init__.py是空文件

j.py 也是空文件

k.py的正确内容的姿势应该是这样,k模块导入了同级目录的j模块,导入了dirx包的a模块。看起来是不心里发慌了,第8行有红色波浪线,是不是代码写得有bug了?

第5行,from pacx import j,还可以使用from . import j

python 导入模块的坑。为什么整个项目能运行,单独运行某个文件模块就报错?多层目录不同文件夹怎么导入?

下图是 run.py的代码

python 导入模块的坑。为什么整个项目能运行,单独运行某个文件模块就报错?多层目录不同文件夹怎么导入?

这样做后,不管是从pycahrm右键运行run.py还是从cmd敲入指令 python run.py,都能很好的打印出 hello和over。

不正确的姿势是在k文件中直接import j,如图

python 导入模块的坑。为什么整个项目能运行,单独运行某个文件模块就报错?多层目录不同文件夹怎么导入?

这样,直接运行k文件没事,下面来运行run文件,在cmd里面使用py3运行run文件会出错(py2的导入方式和py3不同,py2不会出事),出错如下图

python 导入模块的坑。为什么整个项目能运行,单独运行某个文件模块就报错?多层目录不同文件夹怎么导入?

出错的文件是k文件的第6行,第6行直接导入j模块,报错找不到j了!!!

一定要使用从cmd运行 或者从shell运行run。 上面这些文件放到不同的位置,在pycahrm不一定报错,也不一定不报错,pycahrm自动加了一些目录到sys.path了,如果老是用pycahrm运行,可能一部署就挂了,代码最终运行起来,肯定不是从pycahrm运行run.py,一定是cmd shell这种。  不信的人可以把文件夹分别放到项目目录下面和建立一个很深的文件夹,从pycharm运行run就知道了。

k文件的代码

#coding=utf8

from pacx import j

# import j

from dirx import a

print ('hello')

上面这是正确的,但是直接运行k文件会报错。不正确的代码有:

#from pacx import j

import j

#from dirx import a

这样从run运行找不到j了。

k模块引入dirx包的a模块,怎么导入?很多人觉得是要写sys.path.apend,是这样吗?可以看到,django项目文件夹下面的同名文件夹的urls文件,引入一个app中的views,是from xxapp import views就行了。
直接
from dirx import a就可以使用了,k模块的这行与红色波浪线不要紧,因为运行起点不在k模块红色怕什么。

还有人可能,别人给了他应该项目,他试图直接运行项目中的某一个文件,他会纳闷说为什么从整体运行没事,为什么一运行某个文件就不行了?
如果从k模块开始运行,
k文件里面的 from pacx import j
这一行会报错。 那么一定要注意的就是运行起点,还有就是项目部署前至少从cmd /shell运行一次,pycahrm运行是不同的靠不住的,默认是添加了几个目录到syspath,这需要设置。

项目的运行起点很重要,可以使用os.getcwd()查看当前工作目录。

不但是导入模块的问题,还有读取文件的也和项目运行起点有关。

下图是一个django项目

python 导入模块的坑。为什么整个项目能运行,单独运行某个文件模块就报错?多层目录不同文件夹怎么导入?

test1109文件调用模型文件gdbt.pkl,

可以看到我在test1109同级目录放了一个gdbt.pkl模型文件

在manage.py也放了一个gdbt.pkl模型文件,按道理test1109模块读取的是同级目录的模型文件,但其实删了同级目录下的模型文件项目会运行无误,反而如果删除了manage.py同级目录的模型文件,会出错,会找不到文件。

因为当前工作目录设置了manage.py目录。

但是不从网络访问时候,需要用本地函数直接调试调用模型是有问题的,我在test1109文件的目录下面也放了一个gdbt.pkl模型文件。这样就在本地测试和网络访问都不会有问题,但要放两次,这是隐式地用了相对路径。直接写模型文件的磁盘路径当然也可以,不灵活。最好是在代码操作文件的地方使用__file__的绝对路径去定位其他文件,这样不管是外层启动还是是内层启动都能定位到唯一的地方。


模块导入和python编码一样重要,在py编程中这两种东西一定要单独花时间弄精通,不能模棱两可,每次出事都靠猜。

只有笨瓜猪才会说什么都不管,一切设置utf8,不碰py2只用py3就不会碰到编码问题这么弱的话。因为见过不少使用py3还仍然被编码报错或者乱码问题的困扰人。

2、直接使用cmd和shell启动python,一个快速与pycahrm运行保持一致的方法是,在运行python命令前,设置一个PYTHONPATH环境变量,路径是你的项目文件夹的顶层目录。有些人可能疑惑了,你电脑有十几个项目,设置个环境变量不会互相干扰吗?这是不会发生的,因为只是用命令设置环境变量,而没有去永久性的修改环境变量的配置文件,那么环境变量只在当前会话窗口有效。绝对不会发生干扰问题。
上一篇:室内定位系列(一)——WiFi位置指纹(译)


下一篇:css-子div设置margin-top影响父div