__name__ 变量会被python解释器当做内置值处理,python解释器是按照文件为单位处理的,当py文件会被当做模块使用时,python解释器会先运行一遍py文件中的可执行代码,这很重要。
如果py文件直接被使用(python test.py),则 __name__的值是字符串 '__main__'
#test.py
#不可执行代码
def printsomething():
print("this is string from func")
#可执行代码,引用函数printsomething
printsomething()
print(__name__)
# -------------------------
# 使用 python test.py
# 则输出内容为:
# this is string from func
# __main__
如果py文件被当做模块使用,那么在引用文件中,被引用文件中的 __name__ 的值会变成文件名
#test.py
#不可执行代码
def printsomething():
print("this is string from func")
#可执行代码,引用函数printsomething
printsomething()
print(__name__)
#run.py
import test #import动作相当于python test.py,因此会执行test.py文件中的可执行代码
print(test.__name__)
print(__name__)
# --------------------
# 使用 python run.py
# 则输出内容为:
# "this is string from func" <--对应printsomething()
# test <--对应print(__name__)
# test <--对应print(test.__name__)
# __main__ <--对应print(__name__)
为了方便记忆,可以这样理解:
所有py文件的__name__的值都是自己文件的名字,直接运行python解释器(import动作应当视为间接运行解释器)时,解释器会把被自己直接操作的py文件中__name__的值设置为__main__ ,其他通过import间接运行python解释器的py文件中的__name__变量不会变。
那么如果我们不想运行被import模块中的可执行代码该怎么做呢?
可以在模块中使用 if语句 把可执行代码包裹起来,当且仅当发现自己的 __name__和 '__main__' 相等时才运行可执行代码:
#test.py
#不可执行代码
def printsomething():
print("this is string from func")
#使用if条件语句包裹,test.py被当做import模块时不会再执行下面的代码
if __name__=='__main__':
printsomething()
print(__name__)
#run.py
import test #import动作相当于python test.py,因此会执行test.py文件中的可执行代码
print(test.__name__)
print(__name__)
# --------------------
# 使用 python run.py
# 则输出内容为:
# test <--对应print(test.__name__)
# __main__ <--对应print(__name__)
# --------------------
# 使用 python test.py
# 则输出内容为:
# this is string from func <--对应test.py中的printsomething()
# __main__ <--对应test.py中的print(__name__)