当前位置:   article > 正文

Python基础 - 本地模块的绝对导入/引用_python绝对路径导入模块

python绝对路径导入模块

目录

1. 项目入口文件

 2. 绝对导入


Python本地模块的引入是比较简单的,包括绝对引用和相对引用(相对引用的博客参考下一篇Python基础 - 本地模块的相对导入/引用),个人比较推荐使用绝对引用,会避免掉很多错误,本篇文章主要介绍绝对导入。

1. 项目入口文件

项目入口文件一般要放在项目根目录下,如下图1红框main.py所示,即为项目入口文件。如果运行main.py,系统会自动把入口文件所在的根目录,加入到sys.path里。这样在以引用方式导入包时,会逐一查找sys.path中的路径,第一个即为项目根目录,如下图2所示,其中sys.path的路径包括:[项目根目录。python的压缩包路径。python自带的一些库如os, json等。so库文件。使用pip/conda安装时的第三方库]

 2. 绝对导入

绝对导入是比较简单的,也比较推荐大家采用这种方式。首先根据上图画出当前的文件树,如下:

  1. Import_Test
  2.   |--dir1
  3.    |--d11.py
  4.    |--d12.py
  5.   |--dir2
  6.    |--d21.py
  7.    |--d22.py
  8.   |--test.py   

首先我们明确一点的是,如果运行哪个文件,该文件所在的父目录就会被加载到sys.path中,在绝对导入模块时就以这个父目录为依据来查找文件夹/文件

 示例1:引入入口文件的同级目录文件

  1. # test.py ----------------------------
  2. from dir1.d11 import d11_f
  3. def test_f():
  4. print("test")
  5. if __name__ == '__main__':
  6. test_f()
  7. d11_f()
  8. # dir1/d11.py ------------------------
  9. def d11_f():
  10. print("d11_f")
  11. # 运行结果如下:
  12. (base) @118:~/Wmq/Import_Test$ python test.py
  13. test
  14. d11_f

从层级上看,test.py在根目录下,所以在运行时,test.py的父目录/Wmq/Import_Test被加载到sys.path中,所以引用dir1下的d11模块时,直接引用dir1,因为该目录在/Wmq/Import_Test下。

示例2:test.py没变,引入的子模块dir1.d11同时引入同级模块dir1.d12

  1. # test.py ----------------------------
  2. from dir1.d11 import d11_f
  3. def test_f():
  4. print("test")
  5. if __name__ == '__main__':
  6. test_f()
  7. d11_f()
  8. # dir1/d11.py ------------------------
  9. from dir1.d12 import d12_f
  10. def d11_f():
  11. print("d11_f")
  12. d12_f()
  13. # dir1/d12.py ------------------------
  14. def d12_f():
  15. print("d12_f")
  16. # 运行结果如下:
  17. (base)@118:~/Wmq/Import_Test$ python test.py
  18. test
  19. d11_f
  20. d12_f

同级模块的引入是比较好理解的,根据示例1,test.py在运行时,其父目录/Wmq/Import_Test被加载到sys.path中,所以无论怎么调用d12_f,都要在/Wmq/Import_Test的基础上引入,而dir1就在盖目录下,所以就是dir1.d12。

示例3:test.py没变,引入的子模块dir1.d11同时引入跨文件夹模块dir2.d21

  1. # dir1/d11.py ------------------------
  2. from dir2.d21 import d21_f
  3. def d11_f():
  4. print("d11_f")
  5. d21_f()
  6. # dir2/d21.py ------------------------
  7. def d21_f():
  8. print("d21_f")
  9. # 运行结果如下:
  10. (base)@118:~/Wmq/Import_Test$ python test.py
  11. test
  12. d11_f
  13. d21_f

从示例不难发现,在dir1文件下的d11.py中,是如何跳跃文件夹引入dir2文件下的d21.py呢?是直接导入dir2文件夹。为什么这样不报错,原因也在示例1/2中有解释,test的运行加载了父目录/Import_Test,而dir2就在父目录下,所以直接引入dir2即可。

示例4:如果不运行test.py了,只运行dir1/d11.py, 其他任何引用不变,结果如下:

  1. # dir1/d11.py -------------------
  2. from dir2.d21 import d21_f
  3. def d11_f():
  4. print("d11_f")
  5. d21_f()
  6. if __name__ == '__main__':
  7. d11_f()
  8. # 运行结果报错,如下:
  9. (base) zhangyujun@118:~/Wmq/Import_Test/dir1$ python d11.py
  10. Traceback (most recent call last):
  11. File "d11.py", line 1, in <module>
  12. from dir2.d21 import d21_f
  13. ModuleNotFoundError: No module named 'dir2'

运行报错了,这其实在情理之中。因为我们前面说过,如果运行哪个文件,该文件所在的父目录就会被加载到sys.path中,在绝对导入模块时就以这个父目录为依据来查找文件夹/文件。那当我们运行d11.py时,d11.py的父目录也就是dir1被加载到sys.path中,然后顺着dir1往下找,肯定找不到dir2的,所以报错。我们验证下sys.path看一下是不是dir1被加载进去了,如下:

  1. # dir1/d11.py -------------------
  2. import sys
  3. print(sys.path)
  4. from dir2.d21 import d21_f
  5. def d11_f():
  6. print("d11_f")
  7. d21_f()
  8. if __name__ == '__main__':
  9. d11_f()
  10. # 运行结果:
  11. (base) zhangyujun@118:~/Wmq/Import_Test/dir1$ python d11.py
  12. ['/home/zhangyujun/Wmq/Import_Test/dir1',
  13. '/home/zhangyujun/anaconda3/lib/python38.zip',
  14. '/home/zhangyujun/anaconda3/lib/python3.8',
  15. '/home/zhangyujun/anaconda3/lib/python3.8/lib-dynload',
  16. '/home/zhangyujun/anaconda3/lib/python3.8/site-packages']
  17. Traceback (most recent call last):
  18. File "d11.py", line 3, in <module>
  19. from dir2.d21 import d21_f
  20. ModuleNotFoundError: No module named 'dir2'

确实,sys.path中的第一个是dir1目录,自然找不到dir2目录,那怎么解决这种问题呢?我们可以在sys.path里添加上根目录,运行结果即可正常,如下:

  1. # dir1/d11.py -------------------
  2. import sys
  3. sys.path.append("/home/zhangyujun/Wmq/Import_Test")
  4. from dir2.d21 import d21_f
  5. def d11_f():
  6. print("d11_f")
  7. d21_f()
  8. if __name__ == '__main__':
  9. d11_f()
  10. # 运行结果:
  11. (base)@118:~/Wmq/Import_Test/dir1$ python d11.py
  12. d11_f
  13. d21_f
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/405078
推荐阅读
相关标签
  

闽ICP备14008679号