首页 > 编程语言 >python踩坑记录之import和module

python踩坑记录之import和module

时间:2023-11-19 11:22:25浏览次数:40  
标签:submodule python handler py module Handler import

1.问题重现

最近开发时需要将一个别人的python项目作为submodule引入,调用的时候遇到了奇怪的问题,最后定位到问题是import导致的。首先对问题做一个说明。

项目结构如下:

Project/
    main.py
    submodule/
        __init__.py
        handler.py
        tools.py

导致问题的代码部分(对代码进行了简化)如下:

  • main.py
import sys
import os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/submodule")
from submodule.handler import Handler
from submodule.tools import check

if __name__ == "__main__":
    handler = Handler()
    print("check result:{}".format(check(handler)))
  • handler.py
class Handler:
    pass
  • tools.py
import sys
import os
from handler import Handler

def check(data):
    return type(data) == type(Handler())

执行main.py后,输出的结果是:check result:False,而我期望的结果是True

2.问题分析

很明显,上述结果说明传递进去的dataHandler()生成的实例类别不同,但这看起来很不合理:我明明import的是同一个类,为什么实例化之后判断类别会不同呢。将两个实例的类别打印出来发现:

type of data:<class 'submodule.handler.Handler'>
type of Handler():<class 'handler.Handler'>

可以看到两个实例的类别并不一样,并且很容易就可以发现,两个实例类比中Handler的前缀刚好就是两个文件中import时候的路径,因此大概率是这个问题导致的(实际上也确实是)。

3.原理

3.1 python的import机制及module

导致这个问题的核心原因,在于python的import机制。当我们import一个module时,导入的并不是某个类的定义或者一段代码,而是一个实例化了一个module类:

>>> import submodule.handler as handler
>>> type(handler)
<class 'module'>

而所有的module,都被维护在一个大的字典sys.modules中:

>>> import sys
>>> print(sys.modules)
{
    'sys': <module 'sys' (built-in)>,
    'builtins': <module 'builtins' (built-in)>,
    '_frozen_importlib': <module '_frozen_importlib' (frozen)>,
    ......
}

其中的key就是我们import时候的名称或者说路径。在main.py中打印sys.modules,可以看到:

'submodule.handler': <module 'submodule.handler' from '/home/aabb/import_test/submodule/handler.py'>,
'handler': <module 'handler' from '/home/aabb/import_test/submodule/handler.py'>

尽管import“指向”了同一个文件,但实际上是两个不同的module,这两个module中的Handler类也并不是同一个类(准确来说是对象。python中,类本身也是一个对象,可以参考python中类对象),因此其实例化的对象类型肯定不会相同。

3.2 解决方案

知道了上述原理,解决方案也就有了,那就是在项目内要统一import的路径。比较合理的方式是无论在项目内部还是项目外部,都从项目的根目录开始引用。我这个项目中的问题实际上是submodule中没有从根目录开始引用(不过人家这个项目本来也不是让别人拿来当submodule用的)

4. 后记

菜鸡的第一篇博客,问题也是个很简单的问题,不过我觉得是个很容易被忽略的问题(也可能是我太菜了_(:з)∠)_)。很早前就一直有想写博客的想法,但一直没有迈出第一步,这次也算开了个头。

如果有哪些地方写的有问题还请大佬们指正_(:з)∠)_

标签:submodule,python,handler,py,module,Handler,import
From: https://www.cnblogs.com/qiangliang/p/17841599.html

相关文章

  • 洛谷 B2006 地球人口承载力估计(Python3)
    这题难点在理解题意。没有任何技术含量:(题目分析:1.“可持续发展”到底什么意思?Makeendsmeet.也就是说能养活的那些人一年消耗的等于地球一年产生的。2.题中为什么要给x,a,y,b?为了求等量关系。注意,这里"x 亿人生活 a 年,或供 y 亿人生活 b年"用的是地球新生的资源和原有......
  • 使用 ChatGPT 帮助小学生编程入门系列之一:Python 编程读取和解析天气预报网页上的数据
    现在国内小学生也开设了信息技术课,课程内容也涉及到了一些简单的编程实践,比如Scratch和Python.当初这个公众号申请时专门用了我儿子的名字,算是抢注吧,毕竟微信公众号和其他社交媒体平台不一样,不允许重名。我也曾经和我儿子聊过,我今年都40多岁了,这个公众号将来迟早有一天会正......
  • python:第二十三章:程序结构之分支结构
    一,if语句(单分支结构)if条件:   #执行代码块条件是一个表达式,它的值为布尔类型,值为True或False。如果条件为True,则执行冒号后面缩进的代码块;如果条件为False,则跳过代码块不执行。例子:123age=input('请输入你的年龄:')ifint(age)>=18: ......
  • python:第二十四章:三元运算符
    一,三元运算符的语法:value_if_trueifconditionelsevalue_if_false相当于:ifcondition:   value_if_trueelse:   value_if_true它的作用:简化了代码说明:刘宏缔的架构森林—专注it技术的博客,网站:https://blog.imgtouch.com原文: https://blog.imgtouch.c......
  • python:第二十五章:range函数
    一,range函数的功能1,语法range(start,stop,step)参数 start:序列的起始值,如果不指定,默认为0。stop:序列的结束值(不包含),必须指定。step:序列的步长,如果不指定,默认为1。返回:一个整数序列,数据类型是:range应用场景:用于循环2,整数序列是从起始值到结束值(不包含结束值本身)的......
  • python:第二十一章:input接收输入
    一,input函数的用途input()函数用来从键盘接收用户的输入,它的参数是提示用户输入的信息,我们把接收到的数据保存到变量中,进行后续的操作例子:123456numPhysics=input("请输入物理成绩:")numChemical=input("请输入化学成绩:")#接收的数字转为float类......
  • python:第二十二章:程序结构之顺序结构
    一,程序的三种结构:顺序结构:按照代码顺序依次执行选择结构:根据条件判断选择执行不同的代码块循环结构:重复执行一段代码,直到满足退出条件二,顺序结构的特点:顺序执行按从上到下的顺序依次执行,每一条语句都会被执行且只执行一次:例子:123456#顺序执行,从......
  • Python、Spark SQL、MapReduce决策树、回归对车祸发生率影响因素可视化分析
    原文链接:https://tecdat.cn/?p=34286原文出处:拓端数据部落公众号分析师:ShichaoZhong项目挑战如何处理庞大的数据集,并对数据进行可视化展示;在后续分析中特征选择是重点之一,要根据事实情况和数据易处理的角度来筛选变量解决方案任务/目标根据已有的车祸数据信息,计算严重车祸......
  • python 数据可视化:直方图、核密度估计图、箱线图、累积分布函数图
    本文使用数据来源自2023年数学建模国赛C题,以附件1、附件2数据为基础,通过excel的数据透视表等功能重新汇总了一份新的数据表,从中截取了一部分数据为例用于绘制图表。绘制的图表包括一维直方图、一维核密度估计图、二维直方图、二维核密度估计图、箱线图、累计分布函数图。 目录......
  • 【Python自动化】定时自动采集,并发送微信告警通知,全流程案例讲解!
    目录一、概要二、效果演示三、代码讲解3.1爬虫采集行政处罚数据3.2存MySQL数据库3.3发送告警邮件&微信通知3.4定时机制四、总结一、概要您好!我是@马哥python说,一名10年程序猿。我原创开发了一套定时自动化爬取方案,完整开发流程如下:采集数据->筛选数据->存MySQL数据库......