首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么这种循环导入在Python2中失败,而在Python3中不失败?

循环导入在Python中是指在模块之间相互引用对方导致的循环依赖关系。Python解释器在导入模块时会执行以下步骤:

  1. 查找并加载模块的字节码文件或解释器已加载的模块缓存。
  2. 创建一个空的模块对象,并将其放入sys.modules缓存。
  3. 在新创建的模块对象中执行模块对应的源代码。

在Python2中,循环导入会导致导入的模块未完成初始化就被调用,从而导致一些异常情况。Python3对循环导入进行了改进,引入了"模块缓存"和"模块的部分初始化"的概念,以解决循环导入问题。

具体来说,在Python3中,当遇到循环导入时,解释器会执行以下步骤:

  1. 检查模块是否已在sys.modules缓存中。如果是,则直接返回缓存中的模块对象。
  2. 创建一个空的模块对象,并将其放入sys.modules缓存。
  3. 执行模块对应的源代码,但只执行到导入另一个循环导入的模块的语句,然后暂停初始化。
  4. 导入另一个循环导入的模块,如果该模块已在缓存中,则直接返回缓存中的模块对象。
  5. 继续完成当前模块的初始化过程。
  6. 返回当前模块对象。

通过这种方式,Python3能够在循环导入时暂停初始化过程,先导入并初始化已存在的模块,再继续当前模块的初始化,从而避免了循环导入失败的情况。

需要注意的是,尽管Python3对循环导入进行了改进,但过多的循环导入依然可能导致代码的可读性和维护性下降,因此在设计和编写代码时,应尽量避免循环导入的出现。

以下是腾讯云相关产品和产品介绍链接地址:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

Java 为什么推荐 while 循环中使用 sleep()

前言最近逛 CSDN 看到一篇文章,文章大意是说为什么循环推荐使用 sleep 操作,原因在于线程挂起和唤醒会有很大的性能消耗,并推荐使用 Timer 及 ScheduledExecutorService...// do something }}上面的代码你可能会得到下面的警告:Call to ‘Thread.sleep()’ in a loop, probably busy-waiting// 循环中调用...sleep 可能会导致忙等待 // 如 FLAG 变量状态未改变 那么线程可能一直循环,并不断进行线程挂起和唤醒原因是否正确主要原因和原文博主所说有很大的关系但不完全正确:我们都知道 Java 线程实际对应着操作系统的一个线程...方案是否合理记住一点,讨论方案永远不能脱离场景,没有一种方案可以适应所有的场景,我们永远只是探讨适合当前场景的方案。...比如微服务体系,客户端上报实例状态,或者服务端检测客户端状态都会使用定时轮询的机制。

1.3K30
  • 编写兼容 Python 2.x 和 3.

    很酷,这个Python2Python3都可以运行,而且运行的效果是一样的,再来看看下面这段: >>> print(10, 20) # Python 2 (10, 20) 此时,你并没有像前面那样幸运得到一样的结果...,Python2打印的是元组(tuple),而在Python3传递多个参数到print()里面时打印的是两个值: >>> print(10, 20) # Python 3 10 20 如果你思考得比较多的话...True,尽管这并没有错,但是为了达到Python3的效果,但你仍然会因为其他原因导致失败。...为什么我们不用sys.stdout.write()呢,因为我们需要添加一个NEWLINE字符字符串的结尾来兼容这种行为(python2.xwrite方法不会换行): # Python 2.x & 3...n') Import your way to a solution 一般情况情况下,import时没什么烦恼,只要正确的导入就行,但在下面代码,我们想导入urlopen()函数,Python2,他同时存在与

    87030

    python3python2的区别

    Python2相对路径的import会导致标准库导入变得困难(想象一下,同一目录下有file.py,如 何同时导入这个文件和标准库file)。...Python3这一点将被修改,如果还需要导入同一目录的文件必 须使用绝对路径,否则只能使用相关导入的方式来进行导入。 3. Python2存在老式类和新式类的区别 Python3统一采用新式类。...Python3使用更加严格的缩进。 Python2的缩进机制,1个tab 和8个space 是等价的,所以缩进可以同时允许tab和space 代码中共存。...这种等价机制会导致部分IDE使用存在问题。...raise IOError("file error") #抛出异常 2. except NameError as err: #捕捉异常 3. for循环中变量值区别 Python2,for循环会修改外部相同名称变量的值

    1.6K10

    Python基础学习笔记

    :") 请输入你的名字:laowang python2会报错,python3则不会 请输入你的名字:1+2 print(a) python2打印结果为3 python3打印结果为'1+2' 而python2.../或者类名也行] 定义的作用:放上将来你想要用的功能/类名,如果没放进去 调用import仍不能用 把模块有关联的放在一个文件夹 python2调用文件夹名会直接失败 python3调用会成功...setup.py install python2range(10)返回值是一个列表[0,...,9] 而在python3返回值是range(0,10) range(0,10)python2返回是一个列表...[0,...,9] 而在python3返回值是range(0,10) range有风险 如果将来你需要一个很大的值 因为需要占用很大的空间 所以不给你 如果python3想要返回值是一个列表 使用...a = [i for i in range(1,18)] 这样可以返回一个列表 python2这种写法也适合 (参数1,参数2,参数3,.....) for 参数1 in range(第1个数)

    1.3K50

    Python的故事_one

    编程断断续续总是学不好,对于自己的失败归于两点,用不到、坚持不住。...Python是一门有特色的语言,编程思想其实多数一样,语法用法各有特色,Python我的认识(初浅的自学过shell、java、C),整个代码规范程度确实很严格,对于缩进不合格会运行失败。...解释: 那么Python3输入第一行代码就会报错,要带上括号才可的 小试牛刀学习最好的方式写小游戏来连贯基础,下面找了一些适合初学者的小游戏,分享你的思维逻辑与代码吧,我先来!...Python2用的rawinput来实现的输入,思路也很简单,循环输入的次数,3就循环3次,10就循环10次,循环的数重1开始即可,只要注意防止死循环即可 2、如下图所示 ?...) --Python3的用法 randomes = random.choise --Python2的用法 引入这个模块意思是生成随机数,其实Python没有生成随机数这一说法,random是一种伪随机数

    49420

    day09-python基础

    Python软件:             ==> Python解释器(内存管理)       下载:         Python3    继续更新         Python2    继续更新...        Window:点点           python2           python3            # 环境变量             配环境变量-参考https://...www.jb51.net/os/windows/459551.html         Linux :           python2           python3   b.Python...(可以是.txt等 建议这么做)         - 导入模块时,如果不是.py文件(可以执行建议这样做)          ==> 以后文件后缀名是 .py(建议)       2.两种执行方式...        Python3 无需关注         Python2 每个文件只要出现中文,头部必须加       5.

    40810

    坚持的力量:Facebook向Python3迁移的过程回顾

    弗里德也曾表示(在内部社区Python3永远不会出现在Facebook。只有一个人向他提出质疑,并建议他做些事情来改变这种情况,虽然当时他忽略了这个建议,但这个想法却留在了他的脑海里。...他们lint工具有提示的地方导入这些包,这样可以更容易将模块转为Python3。 用于序列化和远程过程调用的Apache Thrift框架在Facebook“无处不在”。...当他最终修复了错误允许服务被构建时,又会在运行时失败——Facebook系统设置服务入口点的代码报错。 为了让代码能够正常运行,他必须修复所有问题。...如果开发人员开始觉得迁移到Python3是件困难的事,他们就会回到“让我们永远留在Python2”的心态。他让开发人员可以轻松地Python 3环境运行代码。...那一年他花了很多的时间告诉人们Python3有多好,为什么他们应该尽可能地使用Python3。一年来,很多和他共同推行Python3的同事公司中都出了名。

    55000

    那些年在win下填过的Django坑

    如果你是用python2的话,models.py开头就应该加上coding:utf8' 强制使用utf8方式编码,如果是python3的就不需要,因为python2是默认gbk,python3默认utf8...但是这种方式只对当前有效,也就是说退出重开后就会打回原形,并不能根本上解决问题。 到这里MySQL编码就告一段落了! 花絮1:Anaconda不是能同时用python2和3吗,为什么还纠结?...当时我遇到坑1的时候就想到既然anaconda能装两个版本的python,为什么不用python2操作数据库,用python3写models呢?...这种事我填坑1也做过,两个版本的Anaconda都能成功安装,但是后来安装的版本cmd使用python是无效的,换句话说,默认的python版本只能有一个并且是最先安装的那个,我尝试过修改环境变量PATH...除了这点外,还有启动虚拟环境env后安装库的位置也有不同,env内使用pip install 的库会直接安装到虚拟环境env内,这样env的python端Import导入这个库就能成功,相反,用conda

    1.7K70

    Python 2和Python 3的区别?

    并没有严格统计)兼容的地方,所以就没所谓学哪一个好,学了一个,另一个花很少时间就能掌握。 今天给大家介绍 Python2Python3 的一些主要区别 ?...py2 ,print语句后面接的是一个元组对象,而在 py3 ,print 函数可以接收多个位置参数。...如果希望 Python2 把 print 当函数使用,那么可以导入 future 模块 的 print_function # py2 >>> print("hello", "world") ('... Python2 ,字符串有两个类型,一个是 unicode,一个是 str,前者表示文本字符串,后者表示字节序列,不过两者并没有明显的界限,开发者也感觉很混乱,不明白编码错误的原因,不过 Python3...Python2的迭代器必须实现 next 方法,而 Python3 改成了 next nonlocal 我们都知道Python2可以函数里面可以用关键字 global 声明某个变量为全局变量,但是嵌套函数

    72620

    【Python专题(二)】Python二三事

    python3兼容方案,代码开头导入: from __future__ import unicode_literals 这样就会把python2所有的字符串改成Unicode,而不会默认用ASCII...4.引用问题 python2python3的引用的默认方式也有所不同。python2默认相对路径导入package,而python3默认绝对路径导入package。...python2定义迭代器的方法是类的 next()方法,但是python3定义迭代器的方法则是类的 __next__()方法。...因此我必须要在项目中解决兼容问题——把python3的代码改到python2然后用python2运行项目。你可能会问,为什么不把python2的包改成支持python3呢?...这种需求应该是非常常见的一种了,随着python2彻底成为历史,如果你手上还有兼容python3python2代码,确实应该考虑把它迁移到python3了。

    59510

    ​愉快地迁移到Python3

    但是,Python 生态系统 Python2Python3 中共存,而Python2 仍在数据科学家中使用。到2019年底,也将停止支持 Python2。...还有下面的运算 x = u'со' x += 'co' # ok x += 'со' # fail Python2 失败了,Python3 正常工作(因为我字符串中使用了俄文字母)。...'k': 1}) 虽然可以 Python2 中正确地处理这些结果,但是 Python3 中看起来结果更加友好。...python这很难实现,但是注释会帮助你 ? 这是一个带有变量注释的 PyCharm 提示示例。即使使用的函数没有注释的情况下(例如,由于向后兼容性),也可以使用这种方法。...与pytorch和cupy的技巧相比。 除此之外,还可以做以下事情: 使用它来延迟加载子模块。例如,导入tensorflow时会导入所有子模块(和依赖项)。需要大约150兆内存。

    1.1K40

    细说python的round()方法

    且听我分析~~    python2,round()方法确实是 “四舍” ,却不是 “五入”。如果两端一样远,也就是碰到 “5” 时,则保留距离0远的一边。大于 “5” 的数,才 “入”。 ...而在python3,round()方法也是 “四舍”,如果两端一样远,会保留到偶数一边。大于 “5” 的数才“入”。这也就是为什么上面的例子是1.2和1.6了。...无论Python2还是Python3,得到的结果都应该是 “2.68”,可这里的结果为什么是 “2.67”?  莫慌~~ 机器浮点数不一定能精确表达,机器做出了截断处理。...看下图: Decimal类型可以非常精确地计算机存储,我们导入该模块,查看“2.675”  存储时,确实小那么一点点,所以保留两位小数时,要“四舍”,成了“2.67”。 ...总结  看来,round()方法并不只是简单的四舍五入,不仅要分Python2Python3讨论,还要看数字计算机的存储!!确实值得好好研究。

    61930

    Python程序员最常犯的10个错误,你中招了吗?

    为什么C.x 也变了? Python,类变量是以字典形式进行内部处理,遵循方法解析顺序(Method Resolution Order ,MRO)。...这似乎有点出人意料,因为我们在这里进行循环导入,应该会报错呀! 答案是,Python如果仅存在一个循环导入,程序不会报错。如果一个模块已经被导入,Python会自动识别而不会再次导入。...常见错误9:不熟悉Python2Python3之间的差异 先来看看foo.py文件的代码: import sys def bar(i): if i == 1: raise KeyError...原来,Python 3except代码块作用域外无法访问异常对象。(原因是,Python 3会将内存堆栈循环引用进行保留,直到垃圾回收器运行后在内存对其进行清理。)...下面是处理后的代码,Python2Python3的运行结果一致: import sys def bar(i): if i == 1: raise KeyError(1)

    1K10

    python解释器安装教程的方法步骤

    推荐是,直接在C盘上创建的Python36下安装,这样以后找就能很容易直观找到,若安装失败,把问题贴到搜索引擎上找答案。 ?...现在,刚才如果不关闭黑框,python3可以出来,pip3也可以出来,但是关上后就出不来了,只可以出来python2搜索栏里搜索“系统环境变量”,,出现以下界面, ?...回到问题的刚开始,我们需要解决的是,找不到python3??? 找到安装路径C:\Python36 查看中,勾选“文件扩展名”,可以查看文件的扩展名。...解决方案:复制python的exe,重新命名为python3 A:错误更正:为什么直接修改成python3,这样操作的结果是pip3 -V会报错。...B:如果想输入python2 就出2,python3,就出3,怎么弄?

    67131
    领券