鱼C论坛

 找回密码
 立即注册
查看: 8787|回复: 25

模块导入相关问题

[复制链接]
发表于 2015-5-4 14:22:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 lightninng 于 2015-5-16 23:07 编辑

问题已经解决结论和经验如下:
1、在两个模块中如果有相互导入的现象(如问题中a.py中的import b 和b.py中的import a),那么在递归导入两次后,python自动停止循环导入。虽然python有这种自带的安全机制 ,但是还是应该避免两个模块的递归调用。请看3,4,5楼
2、在导入某一个模块时,实际会将该模块的所有内容运行一次(这也是下面问题中为何只有两个print语句,但会打印四条信息,因为相互导入会导致a.py运行了两次),为了防止这种情况的发生,需要把除了函数和类定义之外的语句放在if __name__ == '__main__':这条语句后面的同一缩进的语句块中,防止递归调用的发生,这个我自己试过了,import b时,b.py中包含在if __name__ == '__main__':中的语句并未被执行,其它 的语句都执行了一次
原问题如下:
今天在看到鱼油的一个问题的时候,试着动手 解决了一下,结果出现了一个神奇的现象,其实之前我用numpy模块的时候也出现过类似的问题,所以拿出来问一下:
1、有两个代码文件a.py和b.py
第一个文件a.py的内容如下
  1. """a.py"""
  2. import sys, os
  3. sys.path.append(os.getcwd())
  4. import b
  5. value  = 1


  6. class NewClass(object):
  7.     def set(self):
  8.         global value
  9.         value = 6

  10. a_class = NewClass()
  11. a_class.set()
  12. c = b.increase()
  13. print(c)
  14. print(type(c))
复制代码
第二个文件,b.py的内容如下
  1. """b.py"""
  2. import sys, os
  3. sys.path.append(os.getcwd())


  4. def increase():
  5.     import a
  6.     a.value =a.value+1
  7.     return a.value
复制代码
运行a.py如果如下
  1. >>> ================================ RESTART ================================
  2. >>>
  3. 7
  4. <class 'int'>
  5. 8
  6. <class 'int'>
  7. >>>
复制代码

2、另外自己动手将b.py中的increase函数直接放到a.py中,即
  1. value  = 1


  2. class NewClass(object):
  3.     def set(self):
  4.         global value
  5.         value = 6

  6. def increase():
  7.     result = value+1
  8.     return result

  9. a_class = NewClass()
  10. a_class.set()
  11. c = increase()
  12. print(c)
  13. print(type(c))
复制代码

运行结果如下
  1. >>>
  2. 7
  3. <class 'int'>
  4. >>>
复制代码

请高手来解答,这个情况到底肿么回事,我用的python3.3.2,64位win 7
@~风介~ @wei_Y@戴宇轩




想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-4 15:33:17 | 显示全部楼层
我们不是高手,我们只是高手的搬运工!@Python_GoWithMe
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-4 17:50:53 | 显示全部楼层
在a脚本中import了b并且b脚本又import了a,但是a脚本又有一句import b,python禁止了这种反复import 的行为,自动禁止了,所以a被运行了两次后被python停止运行了,value被加了两次,造成这种效果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-4 18:02:43 | 显示全部楼层
  1. # a
  2. import b
  3. print('a')
复制代码
  1. # b
  2. import a
  3. print('b')
复制代码

运行a时
  1. >>>
  2. a
  3. b
  4. a
  5. >>>
复制代码


点评

我很赞同!: 5.0
我很赞同!: 5
  发表于 2015-5-4 22:59

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
lightninng + 1 + 1 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-4 18:31:15 | 显示全部楼层
说一个题外话,a中调用b,b又调用a这样的凶残的情况还是别太常用。。
而且类,函数之外的代码如果可以尽量写在
if '__name__' == '__main__':
    下面。
原因已经有啦~~,话说这样子好像递归。
下面是百度来的。。。
python在import前会查看此模块在不在模块列表里,在的话就不会在导入了,所以不会造成递归的死循环现象,用sys.modules查看已经导入了哪些模块。

评分

参与人数 1荣誉 +1 鱼币 +1 收起 理由
lightninng + 1 + 1 感谢楼主无私奉献!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2015-5-4 22:27:38 | 显示全部楼层
本帖最后由 lightninng 于 2015-5-4 23:18 编辑
wei_Y 发表于 2015-5-4 18:31
说一个题外话,a中调用b,b又调用a这样的凶残的情况还是别太常用。。
而且类,函数之外的代码如果可以尽量 ...

哈哈,这个我深有同感,递归调用是应当避免的,这两段代码是我直接将鱼油的代码改到能运行之后所成的状态,具体的问题他并未描述,感觉这是它自己在解决某问题时想的方法~~
PS:b中的代码在鱼油的版本中是放在increase()函数之外的,在我运行a.py时会报错:'module' object has no attribute 'increase',然后我将import a放在increase函数内,a.py能正确运行~~具体原因还有待讨论,我认为可能 是在a.py中调用increase时并未将import a这条语句正确的执行导致的另外,万分感谢解答~~看来和我在numpy中遇到的情况可能不是一个东西~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-4 22:28:33 | 显示全部楼层

good!!!!我懂了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-4 22:35:38 | 显示全部楼层
本帖最后由 lightninng 于 2015-5-4 23:30 编辑
wei_Y 发表于 2015-5-4 18:31
说一个题外话,a中调用b,b又调用a这样的凶残的情况还是别太常用。。
而且类,函数之外的代码如果可以尽量 ...

有个问题想探讨一下,也就是说当在import某个模块时,这个模块中包含在if '__name__' == '__main__':这条语句后缩进的语句将不会被运行,否则将会运行,可对?


我果然变懒了,,这个问题收回,我自己试试~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-4 22:36:46 | 显示全部楼层
~风介~ 发表于 2015-5-4 15:33
我们不是高手,我们只是高手的搬运工!@Python_GoWithMe

谢谢帮助,我又学到东西了~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-4 23:00:15 | 显示全部楼层
lightninng 发表于 2015-5-4 22:35
有个问题想探讨一下,也就是说当在import某个模块时,这个模块中包含在if '__name__' == '__main__':这条 ...

不告诉你——你自己试试不就知道了?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-4 23:08:56 | 显示全部楼层
~风介~ 发表于 2015-5-4 23:00
不告诉你——你自己试试不就知道了?

有道理 ,我觉得这个贴可以结贴了~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-4 23:13:23 | 显示全部楼层
lightninng 发表于 2015-5-4 23:08
有道理 ,我觉得这个贴可以结贴了~~

不早了,早点休息吧! :)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-4 23:28:11 | 显示全部楼层
~风介~ 发表于 2015-5-4 23:13
不早了,早点休息吧! :)

睡了,晚安~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-5 10:58:29 | 显示全部楼层
lightninng 发表于 2015-5-4 22:35
有个问题想探讨一下,也就是说当在import某个模块时,这个模块中包含在if '__name__' == '__main__':这条 ...

if '__name__' == '__main__'
这个py文件不是被当成模块导入时他的__name__是__main__,当成模块导入时没试过是啥,反正不是main。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-5 12:09:59 | 显示全部楼层
wei_Y 发表于 2015-5-5 10:58
if '__name__' == '__main__'
这个py文件不是被当成模块导入时他的__name__是__main__,当成模块导入时 ...

收到,我验证了。确实如此~~
thx~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-5 17:34:07 | 显示全部楼层
wei_Y 发表于 2015-5-5 10:58
if '__name__' == '__main__'
这个py文件不是被当成模块导入时他的__name__是__main__,当成模块导入时 ...

跟模块名一样。。。如果模块是abc.py那abc.__name__是'abc'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-5 18:50:42 | 显示全部楼层
戴宇轩 发表于 2015-5-5 17:34
跟模块名一样。。。如果模块是abc.py那abc.__name__是'abc'

呦西。如果用了as是不是变成as后的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-5 19:31:56 | 显示全部楼层
wei_Y 发表于 2015-5-5 18:50
呦西。如果用了as是不是变成as后的。

不变,你自己干嘛不试试。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-5 19:47:42 | 显示全部楼层
戴宇轩 发表于 2015-5-5 19:31
不变,你自己干嘛不试试。。。

重度懒癌患者。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-5-5 20:37:27 | 显示全部楼层
戴宇轩 发表于 2015-5-5 19:31
不变,你自己干嘛不试试。。。

用嘴问总感觉会快些,虽然往往不是这么回事~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 07:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表