[转]python3 跨目录模块调用,你真的懂了吗?,,小伙伴们,你们有遇到
[转]python3 跨目录模块调用,你真的懂了吗?,,小伙伴们,你们有遇到
小伙伴们,你们有遇到过调用自己写的模块(跨目录模块调用),提示你ImportError:No module named ...的情况,如果有,而且到现在还没有搞明白的,我想说,你今天看对文章了。
这篇文章主要是讲解怎么还原一个出错的场景,然后分析出错原因,一步一步的解决这个问题的思路。
项目结构
代码内容
# model1/student.pydef get_name(): return "hting"
# model1/new_student.pyfrom student import get_name #注意这里的导入包的方式,会导致后面的异常def get_student_name(): return get_name()
# model2/animal.pydef get_name(): return "dog"
# model2/new_animal.pyfrom model2.animal import get_name #注意这里的导入包的方式,和model1中new_student.py模块中的导入方式有什么不一样def get_student_name(): return get_name()
注意上面脚本导入包的方式,和model1中new_student.py模块中的导入方式有什么不一样
# testModel/test.py 这里是运行入口from model1 import studentfrom model1 import new_studentfrom model2 import animalfrom model2 import new_animalif __name__ == "__main__": print(student.get_name()) print(new_student.get_student_name()) print(animal.get_name()) print(new_animal.get_student_name())
执行代码报错
解释出错原因
查看刚才的报错信息,我们可以知道,我们在执行test.py这个文件的时候,找不到student这个对象,那么我们找到包含“from student import get_name”的这个文件“new_student.py”,执行这个文件,没有报错,所以,这样写是绝对没有问题的,那么为什么我们在外部对new_student.py这个模块调用的时候会报错?这里就要涉及到我们的python导包顺序了。
(1)第一步:查找执行文件所在目录
(2)第二步:查找执行文件所属的项目目录
(3)第三步:查找path环境配置的目录
根据我的实验,其实所谓的导包顺序都是根据path中配置顺序来的。我们做个实验,在test.py中将path变量打印出来,结果如下
[‘C:\\HOMETing\\ForPython\\testforpath\\testModel‘, # 执行文件的所在目录‘C:\\Python35\\lib\\site-packages\\django-2.0-py3.5.egg‘, ‘C:\\Python35\\lib\\site-packages\\pytz-2017.2-py3.5.egg‘, ‘C:\\HOMETing\\ForPython\\testforpath‘, # 执行文件所在项目的根目录 ‘C:\\Python35\\python35.zip‘, ‘C:\\Python35\\DLLs‘, ‘C:\\Python35\\lib‘, ‘C:\\Python35‘, ‘C:\\Python35\\lib\\site-packages‘]
结合我们这个问题,会执行这样的步骤
(1)查找执行文件的所在目录,没有student这个对象
(2)查找项目的根目录下,没有student这个对象
(3)查找path中的其他目录也是没有这个student对象的
(4)执行上面4个步骤之后都没有找到这个对象,所以报错
根据上面的分析,多少应该有了解决思路:就是将我们student所在的目录加入到path变量中。
解决这个问题
根据上面步骤的分析,我们尝试将model1这个包路径加入到path变量中,看是否解决了问题。
在代码中添加如下代码
import syssys.path.append("../model1")
test.py模块修改之后的代码
# test.pyimport syssys.path.append("../model1")# print(sys.path) # 打印出path,调试使用from model1 import studentfrom model1 import new_studentfrom model2 import animalfrom model2 import new_animalif __name__ == "__main__": print(student.get_name()) print(new_student.get_student_name()) print(animal.get_name()) print(new_animal.get_student_name())
运行结果
运行成功.png到此,问题已经解决。
我们使用print(sys.path)将path打印出来看一下
[ ‘C:\\HOMETing\\ForPython\\testforpath\\testModel‘, ‘C:\\Python35\\lib\\site-packages\\django-2.0-py3.5.egg‘, ‘C:\\Python35\\lib\\site-packages\\pytz-2017.2-py3.5.egg‘, ‘C:\\HOMETing\\ForPython\\testforpath‘, ‘C:\\Python35\\python35.zip‘, ‘C:\\Python35\\DLLs‘, ‘C:\\Python35\\lib‘, ‘C:\\Python35‘, ‘C:\\Python35\\lib\\site-packages‘, ‘../model1‘ # 新加入的path]
另外:我建议不要使用将相对变量的路径加入到path中,建议使用绝对变量。方法如下
import sysimport ossys.path.append(os.path.abspath("../model1"))# os.path.abspath(path) # 返回path规范化的绝对路径。
练习题
读完这篇文章,我相信小伙伴们肯定是有收获的,那么我们尝试着做一个简单的题来巩固一下。
为什么new_student.py中的导包方式不会引发异常呢?
作者:亭子青年
链接:https://www.jianshu.com/p/61ed747680e2
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
[转]python3 跨目录模块调用,你真的懂了吗?
相关内容
- python---await/async关键字,,推文:玩转 Pyth
- Python爬虫——城市公交、地铁站点和线路数据采集,
- Python爬虫教程:爬取付费电影,告别费钱的日子,,今天
- python基础——4、python应用(文件操作,字典,列表,输
- 如何入门Python爬虫?爬虫原理及过程详解,python爬虫
- python (requests模块使用),,requests模块
- Python零基础到就业指导,最后我泪奔了,,简历中每个字
- Python实现支付宝在线支付,,windows系统安
- python2升级python3,,一 python2升
- Python 的版本控制,Python版本控制,版本控制工具的差异
评论关闭