实际工程的组织架构一般是这样的:

bin包下的bin.py是实际的执行文件,my_mould包下的是业务逻辑的实现模板

bin.py需要import my_mould下的py文件,而bin和my_mould是平级的

所以在bin.py中直接import会报错:

from my_mould import main

if __name__=='__main__':
main.run()
结果:

Traceback (most recent call last):
File "E:/PyCode/模块/bin/bin.py", line 17, in <module>
from my_mould import main
ImportError: No module named 'my_mould'

找不到my_mould这个包,因为sys.path中的第一个当前路径是bin,而不是上一级“模板”,当前路径是“模板”才能import my_mould

如何解决这个问题:

版本一:把“模板”那一层加到sys.path

import sys
sys.path.append(r'E:\PyCode\模块')
from my_mould import main
if __name__=='__main__':
main.run()
结果:5

没问题,但是这样写死sys.path,代码移植到别人的电脑上就跑不起来了

版本二

利用os模板,从后面往前推,

找到当前文件:bin.py

再找到文件的绝对路径:E:\PyCode\模块\bin\bin.py

再找到上一级路径:E:/PyCode/模块/bin

最后找到上上级路径:E:/PyCode/模块

然后把这个路径定义为BASE_DIR,添加到sys.path

这里要用到方法:

print(__file__)                                       #__file__表示文件本身,结果应该是bin.py,这里之所以是bin.py的绝对路径,是因为pycharm擅自加的,如果在cmd执行就是文件本身
print(os.path.abspath(__file__)) #abspath(__file__)才是python解释器给的正真的文件绝对路径
print(os.path.dirname(__file__)) #dirname(__file__)返回文件或文件夹的所处于的路径,也就是上一层路径
print(os.path.dirname(os.path.dirname(__file__))) #两层dirname(__file__),就是上上层

结果:

E:/PyCode/模块/bin/bin.py                                #python解释器给出的结果应该是bin.py
E:\PyCode\模块\bin\bin.py
E:/PyCode/模块/bin
E:/PyCode/模块

最终版本

import sys,os
# BASE_DIR = os.path.dirname(os.path.dirname(__file__))
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) #拿到 E:/PyCode/模板 这个路径
sys.path.append(BASE_DIR)
# sys.path.append(r'E:\PyCode\模块')
from my_mould import main if __name__=='__main__':
# print(__file__)
# print(os.path.abspath(__file__))
# print(os.path.dirname(__file__))
# print(os.path.dirname(os.path.dirname(__file__)))
# BASE_DIR = os.path.dirname(os.path.dirname(__file__))
main.run()

所以,在日常开发中,结合os.path.abspath(__file__)使用os.path.dirname(__file__)是引用模板的常见方式。

最新文章

  1. 【原创】js中input type=file的一些问题
  2. CreateFile函数详解
  3. velocity模板引擎学习(3)-异常处理
  4. 使用xp光盘修复系统的方法步骤
  5. 已知树的前序、中序,求后序的c++实现&amp;已知树的后序、中序,求前序的c++实现
  6. Android 自定义View实现单击和双击事件
  7. TOMCAT启动完成但是ECLIPSE仍然显示starting....
  8. 常用iptables规则整理
  9. jquery与ajax的应用
  10. Ecshop去掉模版中随机出现Ecshop版权的方法
  11. Bootstrap列表组
  12. vs code调试console程序报错--preLaunchTask“build”
  13. 用burpsuite暴力破解后台
  14. 字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8
  15. GMA Round 1 二项式展开
  16. ubuntu18.04中python虚拟环境的安装
  17. Qt5——从零开始的学生管理系统
  18. 使用 ps、strace、lsof 进行 Linux 进程 trouble-shooting
  19. [转帖]unity3D OnTriggerEnter和OnCollisionEnter的一点个人心得(主要讲区别)
  20. boke练习: category类的编辑修改,总是提示:该分类名称已经存在

热门文章

  1. C#9.0新特性详解系列之六:增强的模式匹配
  2. Docker部署Mysql8.0.20并配置主从复制
  3. centos下配置Apache的https强制跳转
  4. abp.zero 9.0框架的前端Angular使用说明
  5. Spark 源码浅读-SparkSubmit
  6. [日常摸鱼]bzoj1444 [JSOI2009]有趣的游戏——AC自动机+矩阵
  7. MySQL高可用(二)主备延时如何解决?
  8. http详解笔记
  9. matlab多项式拟合以及指定函数拟合
  10. Python制作折线图