鱼C论坛

 找回密码
 立即注册
查看: 2712|回复: 10

[已解决]关于__name__属性

[复制链接]
发表于 2023-3-7 20:26:11 | 显示全部楼层 |阅读模式

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

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

x
# a.py
import b

def x():
    print('x')

b.y()

# b.py
import a

def y():
    print('y')

a.x()

执行 b.py 引发下边异常:
>>> 
Traceback (most recent call last):
  File "/Users/FishC/Desktop/b.py", line 1, in <module>
    import a
  File "/Users/FishC/Desktop/a.py", line 1, in <module>
    import b
  File "/Users/FishC/Desktop/b.py", line 6, in <module>
    a.x()
AttributeError: 'module' object has no attribute 'x'

有关这个代码  这个是python课后作业的代码
在利用__name__属性的时候 执行 b.py 程序后不会报错  
小甲鱼给的解释是  就是使用 if __name__ == "__main__" 来确保 Python 不要在导入的过程中调用不该调用的函数
# a.py
import b

def x():
    print('x')

if __name__ == "__main__":
    b.y()

# b.py
import a

def y():
    print('y')

if __name__ == "__main__":
    a.x()

那么这里的__name__属性是在执行b.py的过程中 import a 之后不会执行a.py中的import b程序了吗
最佳答案
2023-3-7 20:57:55
本帖最后由 isdkz 于 2023-3-7 21:00 编辑

if name == "__main__" 的作用是让你的 Python 程序在不同的情况下有不同的行为。

当你直接运行你的 Python 文件时,它的 name 变量会被设置为 "__main__",

所以 if 语句中的代码会被执行。当你把你的 Python 文件作为一个模块导入到其他文件中时,

它的 name 变量会被设置为它的文件名,所以 if 语句中的代码不会被执行。

这样,你可以在你的 Python 文件中定义一些函数或类,让其他文件导入使用,

同时也可以在 if name == "__main__" 中写一些测试或示例代码,让你自己运行看看效果。

这是一种常用的编程习惯,可以提高你的代码的可重用性和可测试性。


在你的代码中执行 b.py 时先去 import a,然后开始执行 a.py,a.py 又 import 了 b

所以又回到了 b,因为每个模块只能被 import 一次,所以 import a 不会被执行,

然后开始往下走,一直到 a.x() 因为 a.py 还处在 import b 的阶段,所以 x 还没有被定义出来

这时候调用 a.x 是会报错的,而把 a.x() 放在 if __name__ = '__main__' 中就是使它作为模块被 import 的时候不会执行 a.x()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-7 20:57:55 | 显示全部楼层    本楼为最佳答案   
本帖最后由 isdkz 于 2023-3-7 21:00 编辑

if name == "__main__" 的作用是让你的 Python 程序在不同的情况下有不同的行为。

当你直接运行你的 Python 文件时,它的 name 变量会被设置为 "__main__",

所以 if 语句中的代码会被执行。当你把你的 Python 文件作为一个模块导入到其他文件中时,

它的 name 变量会被设置为它的文件名,所以 if 语句中的代码不会被执行。

这样,你可以在你的 Python 文件中定义一些函数或类,让其他文件导入使用,

同时也可以在 if name == "__main__" 中写一些测试或示例代码,让你自己运行看看效果。

这是一种常用的编程习惯,可以提高你的代码的可重用性和可测试性。


在你的代码中执行 b.py 时先去 import a,然后开始执行 a.py,a.py 又 import 了 b

所以又回到了 b,因为每个模块只能被 import 一次,所以 import a 不会被执行,

然后开始往下走,一直到 a.x() 因为 a.py 还处在 import b 的阶段,所以 x 还没有被定义出来

这时候调用 a.x 是会报错的,而把 a.x() 放在 if __name__ = '__main__' 中就是使它作为模块被 import 的时候不会执行 a.x()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-7 20:58:40 | 显示全部楼层
是执行了啊,但是因为没有输出所以看起来没执行
而且定义函数也需要调用的
小甲鱼说的也对啊,可以区分导入时执行的代码和直接运行程序时执行的代码

有用请设为最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-7 21:13:12 | 显示全部楼层
isdkz 发表于 2023-3-7 20:57
在你的代码中执行 b.py 时先去 import a,然后开始执行 a.py,a.py 又 import 了 b,

所以又回到了  ...

但是当我们执行b.py的时候会打印结果 x 的 也就是说a.x()是被执行了  换句话说 a模块应该是被全部导入了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-7 21:17:39 | 显示全部楼层
wanglyndon 发表于 2023-3-7 21:13
但是当我们执行b.py的时候会打印结果 x 的 也就是说a.x()是被执行了  换句话说 a模块应该是被全部导入了 ...


我说的是没有加 if __name__ == '__main__' 的时候,如果不把 a.x() 放在 if __name__ == '__main__' 中的话,

在 x 还没有被定义出来就报错了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-7 21:21:05 | 显示全部楼层
isdkz 发表于 2023-3-7 21:17
我说的是没有加 if __name__ == '__main__' 的时候,如果不把 a.x() 放在 if __name__ == '__main__'  ...

那加了 if语句 之后 路线是怎么走的

是import a  然后 import b  然后定义y  然后继续导入a  然后执行a.x()吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-7 21:36:04 | 显示全部楼层
本帖最后由 isdkz 于 2023-3-8 00:29 编辑
wanglyndon 发表于 2023-3-7 21:21
那加了 if语句 之后 路线是怎么走的

是import a  然后 import b  然后定义y  然后继续导入a  然后执行 ...


a.py:
# a.py
print('in a, __name__:', __name__)
import b
print('in a, __name__:', __name__)

b.py:
# b.py
print('in b, __name__:', __name__)
import a
print('in b, __name__:', __name__)

执行 b.py 的结果:
in b, __name__: __main__
in a, __name__: a
in b, __name__: b
in b, __name__: b
in a, __name__: a
in b, __name__: __main__


可以看到程序的执行路线为:b -> a -> b -> a -> b,

而且中间的 a 、b、a 的 __name__ 都不为 __main__,也就是此时不是作为主程序运行的,

而是在导包过程中运行的

而加了 if __name__ == '__main__' 并不会改变程序的运行路线,但是它可以限制被运行的代码,

因为在导包的时候 __name__ 不为 '__main__',

a.py:
# a.py
print('in a, __name__:', __name__)
import b
if __name__ == '__main__':
    print('in a, __name__:', __name__)

b.py:
# b.py
print('in b, __name__:', __name__)
import a
if __name__ == '__main__':
    print('in b, __name__:', __name__)

此时程序的运行结果为:
in b, __name__: __main__
in a, __name__: a
in b, __name__: b
in b, __name__: __main__

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

使用道具 举报

发表于 2023-3-7 22:04:46 | 显示全部楼层
isdkz 发表于 2023-3-7 20:57
在你的代码中执行 b.py 时先去 import a,然后开始执行 a.py,a.py 又 import 了 b,

所以又回到了  ...

你怎么比我快…
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-7 22:08:57 | 显示全部楼层

我一天下来啥事不干就蹲论坛了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-3-8 00:27:19 | 显示全部楼层

理解了 谢谢谢谢

已经设置最佳答案
顺便问一下 —file—用法是干嘛的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-8 00:31:20 | 显示全部楼层
wanglyndon 发表于 2023-3-8 00:27
理解了 谢谢谢谢

已经设置最佳答案

__file__ 是获取当前执行文件的路径的,我本来是想用 __name__ 的,用错了,

才发现没改回来,不好意思
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-1-2 00:59

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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