wanglyndon 发表于 2023-3-7 20:26:11

关于__name__属性

# 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程序了吗

isdkz 发表于 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()

歌者文明清理员 发表于 2023-3-7 20:58:40

是执行了啊,但是因为没有输出所以看起来没执行
而且定义函数也需要调用的
小甲鱼说的也对啊,可以区分导入时执行的代码和直接运行程序时执行的代码

有用请设为最佳答案

wanglyndon 发表于 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模块应该是被全部导入了吧

isdkz 发表于 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 还没有被定义出来就报错了

wanglyndon 发表于 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()吗

isdkz 发表于 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__

歌者文明清理员 发表于 2023-3-7 22:04:46

isdkz 发表于 2023-3-7 20:57
在你的代码中执行 b.py 时先去 import a,然后开始执行 a.py,a.py 又 import 了 b,

所以又回到了...

你怎么比我快…

isdkz 发表于 2023-3-7 22:08:57

歌者文明清理员 发表于 2023-3-7 22:04
你怎么比我快…

我一天下来啥事不干就蹲论坛了{:10_256:}

wanglyndon 发表于 2023-3-8 00:27:19

isdkz 发表于 2023-3-7 21:36
a.py:




理解了 谢谢谢谢

已经设置最佳答案
顺便问一下 —file—用法是干嘛的

isdkz 发表于 2023-3-8 00:31:20

wanglyndon 发表于 2023-3-8 00:27
理解了 谢谢谢谢

已经设置最佳答案


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

才发现没改回来,不好意思{:10_277:}
页: [1]
查看完整版本: 关于__name__属性