Python调用另一个py变量失败的问题

举个栗子

我有两个文件,第一个文件a.py的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/env python
# coding=utf-8

CHOOSE = input ('''
\033[1;35m choose 1 or 2:\033[0m
1)tom
2)jack
''')

a = 666
b = "bbb"
def f():
print("this is a test")
return "function"

if __name__ == '__main__':
if CHOOSE == '1':
username = 'tom'
print(username)

elif CHOOSE == '2':
username = 'jack'
print(username)

else:
print('wrong choice,script is exit...')

拎一个脚本,b.py的内容如下:

1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
# coding=utf-8

import a
from a import b,f,CHOOSE,username

a = a.a
f()
print(b,a,CHOOSE,username)

可以看出b.py的内容就是调用同目录下a.py的变量,但是执行b.py是会报错的。
akb48

可见b.py已经成功读取到了b,f,CHOOSE这些变量,但是username却引入失败,为啥呢?

因为a.py里有一个if __name__ == '__main__',他的意思是当.py文件被直接运行时,if name == ‘main‘之下的代码块将被运行;当.py文件以模块形式被导入时,if name == ‘main‘之下的代码块不被运行。

举个例子解释一下:假设你是小明.py,在朋友眼中你是小明(name == ‘小明’), 你自己眼中你是你自己(name == ‘main‘)。

你编程很好, 朋友调你去帮他写程序(import 小明, 这时你在朋友眼中: name == ‘小明’),但你晚上也会打开xx网站, 做一些自己的事情(直接运行小明.py, name == ‘main‘)—摘自知乎网友回答。

既然知道了原因,解决方法也很简单:把a.py里的if __name__ == '__main__'段落拆掉,把相应内容改成一个函数,比如a.py改成如下的样子:

1
2
3
4
5
6
7
8
9
10
11
12
13
上面内容略

def foo(CHOOSE):
if CHOOSE == '1':
username = 'tom'

elif CHOOSE == '2':
username = 'jack'

else:
username = None

return username

b.py改成如下样子(其他可读取的变量不考虑):

1
2
3
4
5
6
7
8
9
10
11
12
from a import foo
CHOOSE = input ('''
\033[1;35m choose 1 or 2:\033[0m
1)tom
2)jack
''')

username = foo(CHOOSE)
if username:
print(username)
else:
print('Wrong choice')

这样问题就解决了,记住if __name__ == '__main__'更适合放在脚本的入口点。

上面说了,if __name__ == '__main__'更适合放在脚本的入口点,到底哪个程序入口被选中,这取决于__name__的值,__name__是内置变量,可用于表示当前模块的名字。如果一个.py文件(模块)被直接运行时,则其没有包结构,其__name__值为__main__,即模块名为__main__

所以,if __name__ == '__main__'的意思是:当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。

上面的话,可以做一个小实验来理解,我们在a.pyif __name__ == '__main__'之前加入print __name__,即将__name__打印出来,那么执行a.py会看到__name__输出是__main__
akb48

但是此时a.py不动,直接执行b.py,会发现__name__变量值为b,不满足__name__=="__main__"的条件,因此,无法执行其后的代码:
akb48

参考资料

https://zhuanlan.zhihu.com/p/34112508
http://blog.konghy.cn/2017/04/24/python-entry-program/
https://stackoverflow.com/questions/419163/what-does-if-name-main-do
https://www.zhihu.com/question/49136398 (里面有很多例子)
https://blog.csdn.net/liao392781/article/details/80496060 (跨文件夹引用PY文件的方法)

感谢您请我喝咖啡~O(∩_∩)O,如果要联系请直接发我邮箱chenx1242@163.com,我会回复你的
-------------本文结束感谢您的阅读-------------