python中同包、不同包引用总结;no module、no known parent package等报错信息解决

本文主要是总结我这两天对于python中的引用以及相应报错信息的总结
从而可以指导对自己建包,以及如何使用包,处理引用问题。

py可以引用同目录下包的所有模块

  • 这是既定事实,所以当你调用一个第三方的包时,就可以将py和包放在同一目录下
  • 当然这其中可能会出现pycharm引用标红的问题,那是pycharm的问题,对于python来说不影响(详情可见 运行没有问题,pycharm却标红引用?
    • 同时,因为pycharm会因为工作区的问题,将正确的引用标红,那么反推,如果pycharm没有标红,也不代表没有引用问题存在

当py并不与第三方包在同一目录下时

  • 如果我们pip install了一些包,那么就直接import
  • 而对于我们拷贝,下载过来的,没有安装的包,就需要麻烦一点了
  • 简单却麻烦的方式
    • 在py中将 所需引用的包的 路径加入python的系统路径(仅临时生效)
    • python运行时需要import时,就会去自己的系统路径中进行搜索 (sys.path,具体就不解释,自行百度,不过提示一句,若import多个模块,则sys.path.append一定要放到第一个,不然不生效
    • eg.在这里插入图片描述
    • 这里我们要引入try路径下的ansemb包,那么就将它的父节点路径导入(忽略标红,这是正常的)
    • 其实这里的操作就是等价于我们在pycharm中,右键文件夹,make directory as source root
      在这里插入图片描述
  • 简单也不怎么方便的方式
    • 在你的 /python安装目录/site-package/下创建xxx.pth(记不太清了,自己查一下),将要引入的包的父路径放入,这样相当于永久添加路径
    • 麻烦在于,如果这个引入的第三方包是临时的,以后还得改,容易忘了改

有没有__init__.py其实影响不大

  • 不是很确定,不过好像是这样
  • 实测有没有它 都可以正常的引入
  • 看了别的博客说,python3.3之后,directory都是默认的隐式包,所以不是很需要__init__.py来标识包,它的目的还是更多的在于控制

当前py要运行 用绝对路径,当前py被引用 用相对路径

  • 特别是我们要建一个包的时候,很头疼,里面的import,from . import,很容易报错 no module,于是记住本节的标题,就可以轻松规避这些问题
  • 用下面的例子来做演示
eg

目标

  • 包外的demo引用包中的test模块
  • 包内的test引用同级目录下test2,分别采用绝对路径和相对路径的方式引用
  • 分别运行demo和test,观察 在绝对路径和相对路径下是否能够正常运行,如果报错,报的什么错

(文件的取名是我在解决问题时看到别人博客,顺手借鉴的取名,最近写代码,取模块名、变量名已经累了,不想再取名了)
在这里插入图片描述

文件结构如下面(为了方便看,我把init都去掉了)

	|--demo.py
	
	|--try
		|--ansemb
			|--dataset
				|--test.py
				|--test2.py
	# test2
	def ok():
	    print("test2")
	#demo
	#引入了ansemb的路径,可以放在任意位置运行
	import sys
	sys.path.append(r"C:\Users\pan\PycharmProjects\pythonProject\try")
	
	from ansemb import config
	from ansemb.dataset import test
	# config.ok()
	test.ok2()
  • 我们主要看test、test2、和在包外的demo.py
  • 在demo中,引入ansemb.dataset.test,调用其ok2()方法
  • test中需要引入同级目录下的test2

test使用 相对路径 引入test2
在这里插入图片描述

  • 运行demo,正常打印
    在这里插入图片描述
  • 运行test
    在这里插入图片描述
    test使用 绝对路径 引入test2
    在这里插入图片描述
  • 运行demo
    在这里插入图片描述
  • 运行test
    在这里插入图片描述

于是可以得到总结,同一包里进行引用时,如果需要运行自己,则使用绝对路径;如果是其他py引用自己,那么使用相对路径

原因猜想

其中的原因我结合看的博客,简单分析一下,不确保准确,如有大佬,可以评论区讲一下正确理解

使用相对路径
  • 当直接运行test时,python默认test为主模块,其name为"main",所以就会把相对路径中的 . . . 换成"main",变成"from main import test2",这自然就无法找到test2了;而使用demo引用test时,demo的name是"main",test还是正常的,所以可以正常使用相对路径
使用绝对路径
  • 直接运行test,就会以自己为根目录,此时就可以直接import当前目录下的test2,这没问题;而如果使用demo引入test运行,对于demo来说,需要引入test的引入test2(有点绕),那么此时以demo为准,为工作区,它的目录下没有test2,其他sys.path也都找不到,所以报错no module named test2
  • 那么设想一下,如果我们在demo路径下新建一个空的test2,是不是就能找到test2了?是的,那么此时,因为空,所以会报错test2 has no attribute ok这个信息,我们来试一下
    在这里插入图片描述

在这里插入图片描述

参考

https://blog.csdn.net/qq_34687559/article/details/122474888
https://zhuanlan.zhihu.com/p/349407590
https://blog.csdn.net/weixin_39738273/article/details/111635095

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值