鱼C论坛

 找回密码
 立即注册
查看: 1466|回复: 3

[已解决]第50讲课后习题第五题

[复制链接]
发表于 2020-9-13 19:54:08 | 显示全部楼层 |阅读模式

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

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

x
# a.py
import b

def x():
    print('x')

# b.py
import a

def y():
    print('y')

a.x()


为啥我照小甲鱼抄的代码会报错啊?
报错代码:
Traceback (most recent call last):
  File "C:/Users/Administrator/Desktop/b.py", line 1, in <module>
    import a
  File "C:\Users\Administrator\Desktop\a.py", line 1, in <module>
    import b
  File "C:\Users\Administrator\Desktop\b.py", line 4, in <module>
    a.x()
AttributeError: module 'a' has no attribute 'x'
最佳答案
2020-9-13 20:17:36
应该这样就好了,你在a.py引用b.py时,也读取了a.x(),但这时不识别,加了if __name__ == '__main__'这句话,表示只有本身运行时才执行,被import时不执行,就可以避免了
# b.py
import a

def y():
    print('y')

if __name__ == '__main__':
    a.x()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-9-13 20:12:24 | 显示全部楼层
但是我删掉a.x()在运行b.py之后再运行a.x()就好使。这是为什么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-13 20:17:36 | 显示全部楼层    本楼为最佳答案   
应该这样就好了,你在a.py引用b.py时,也读取了a.x(),但这时不识别,加了if __name__ == '__main__'这句话,表示只有本身运行时才执行,被import时不执行,就可以避免了
# b.py
import a

def y():
    print('y')

if __name__ == '__main__':
    a.x()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-13 20:44:29 | 显示全部楼层
估计你没有认真看小甲鱼的视频。小甲鱼写这个程序说了这是个会出问题的程序,因为模块导入不完全。
小甲鱼是在讲__main__的时候写的这个程序,就是为了讲 __main__ 的用法。
具体为什么报错小甲鱼也讲了,但是可能不太清楚。我细化了一下,你可以看看


执行过程是这样子的,小甲鱼讲的并不是特别清楚
若没有 if __name__=='__main__': 这一句的话,执行过程如下,红色部分小甲鱼没有说,导致很多人不理解:
执行b.py -> import a -> 查找 a 模块 -> 未发现 a 模块对象 -> 导入 a.py -> import b -> 查找 b 模块 -> 发现 b 模块对象 -> 接着上次执行的位置往下执行字节码(import a 已执行过,Python 有机制确保不重复导入,因而不会再执行) -> 导入def y() -> 执行 a.x() -> 在 a 模块中找不到 x(),因为 a 还没有被完全导入。

若有if __name__=='__main__': 这一句的话,执行过程如下:
执行b.py -> import a -> 查找 a 模块 -> 未发现 a 模块对象 -> 导入 a.py -> import b -> 查找 b 模块 -> 发现 b 模块对象 -> 接着上次执行的位置往下执行字节码(import a 已执行过,Python 有机制确保不重复导入,因而不会再执行) -> 导入def y() -> 判断if __name__=='__main__' 发现__name__ == 'b',不执行下一句a.x(),b模块导入完成  -> 继续导入a模块,接着上次执行的位置往下执行字节码(import b 已执行过)-> 导入def x() -> 判断if __name__=='__main__' 发现__name__ == 'a',不执行下一句b.y(),a模块导入完成  -> 继续执行b模块,这时接上了第一个箭头后面的import a,然后定义 def y() (这里实际上是又定义了一遍该函数)-> 判断if __name__=='__main__' 发现__name__ == '__main__',执行下一句a.x()。

我修改了一下这两文件,添加了一些print,可以很直观的看到执行过程
# a.py
import b
print('In a,__name__ is',__name__ )
def x():
    print('x')
print('aa')
if __name__ == "__main__":
    b.y()

# b.py
import a
print('In b,__name__ is',__name__ )
def y():
    print('y')
print('bb')
if __name__ == "__main__":
    a.x()
运行结果如下
In b,__name__ is b
bb
a a
aa
In b,__name__ is __main__
bb
x
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 1

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-18 17:12

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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