• if __name__ == "__main__"是什么?
  • 在什么时候需要使用 if __name__ == "__main__"?
  • 以及是否每个档案都需要使用它?

if __name__ == "__main__"是什么?

常被称为:

  • 主程序入口判断
  • 主模组判断
  • 程式执行入口
  • 模组测试代码
  • if __name__ == "__main__"是一个条件判断语句
  • 用于当你希望某些程式码仅在档案被直接执行时才运行,而在该档案被汇入import为模组时不执行。

__name__ 是什么?

  • 是 Python 的一个特殊内建变数,用于表示当前模组的名称:
  • 当档案被直接执行时,name 的值为 "main"。
  • 当档案被汇入为模组时,name 的值为该模组的名称(字串)。比喻说明:
  • 当你“直接”读这本书时,书会在封面上写着:「我的名字是 main」。
  • 当你把这本书的故事拿去给别人用时,书的封面会写上它的书名,例如:「我的名字是 my_story」。

因此if __name__ == "__main__"这句话就像是在问:

「如果这本书的名字是 __main__,也就是说,你正在直接读我,那么请读下面的内容。」

这样,只有在你"直接"读这本书的时候,才会读到这部分的内容;如果你只是把这本书的故事拿去用,这些内容就不会被读到。

这意味着 只有在直接执行这个档案时,位于该条件下的程式码才会被执行;如果是被汇入,则不会执行。

例子:我的故事书 my_story.py:

def tell_story():
print("从前从前,有一个小朋友爱听故事。")

if __name__ == "__main__":
print("开始讲故事:")
tell_story()

情况一:直接读这本书当你执行这本书时(直接运行 my_story.py),书会说:

开始讲故事:
从前从前,有一个小朋友爱听故事。

情况二:把故事拿给别人用当别人在他们的程式中写:

import my_story

my_story.tell_story()

他们执行程式时,只会看到:

从前从前,有一个小朋友爱听故事。

注意: 他们不会看到「开始讲故事:」,因为 if name == "main": 下的内容不会被执行。

为什么要这样做?

这样做可以让你的程式有双重功能:

  • 作为主程式:当你想要直接执行这个档案时,它可以运行一些测试或展示的程式码。
  • 作为模组:当别人想要使用你的函式或变数时,他们可以汇入你的档案,而不会受到你主程式部分的影响。优点:
  • 使用该结构,可以清楚地分离模组的介面(函式、类别定义等)和执行逻辑,有助于他人理解你的程式码。
  • 防止副作用:避免在模组被汇入时执行不需要的程式码,这可能导致预期外的行为。
  • 提高模组的可重用性:使模组既可被汇入使用,又可在直接执行时进行测试或提供范例。
  • 改善程式的结构:清楚地分离模组的介面(供汇入的部分)和执行逻辑。

在什么时候需要使用 if __name__ == "__main__"?

  • 当档案既可被汇入又可直接执行如果你的 Python 档案可以被其他程式汇入,也可以直接执行,那么使用 if name == "main": 来控制直接执行时的行为是很重要的。
  • # calculator.py

    def add(a, b):
    return a + b

    def subtract(a, b):
    return a - b

    if __name__ == "__main__":
    # 只有在直接执行时才会运行的程式码
    num1 = float(input("请输入第一个数字:"))
    num2 = float(input("请输入第二个数字:"))
    print(f"加法结果:{add(num1, num2)}")
    print(f"减法结果:{subtract(num1, num2)}")

    • 直接执行 calculator.py:会要求使用者输入数字,然后输出计算结果。
    • 在其他档案中汇入 calculator.py:add 和 subtract 函式可被使用,但不会执行输入和输出部分。
  • 当你想要在直接执行时进行测试或示范如果你希望在模组中包含一些测试或范例,让其他开发者在直接执行时可以看到功能的用法。
  • # string_utils.py

    def to_uppercase(s):
    return s.upper()

    if __name__ == "__main__":
    # 测试或范例程式码
    sample = "hello world"
    print(f"原始字串:{sample}")
    print(f"大写字串:{to_uppercase(sample)}")

    直接执行 string_utils.py 时:会显示范例输出。汇入 string_utils.py模组:只提供 to_uppercase 函式,不会执行范例程式码。

    不需要使用的情况:

    • 纯模组: 只定义了函式、类别、变数,不包含需要直接执行的程式码。范例:设定档 config.py

    # config.py

    DATABASE_URI = "sqlite:///:memory:"
    API_KEY = "your_api_key_here"

    用途: 提供变数或设定,供其他程式汇入。不需要 if name == "main",因为没有需要执行的程式码。

    • 一次性脚本: 仅作为脚本执行,没有被汇入的需求。

    总结

    • if name == "main" 是一个条件判断语句,用于当你希望某些程式码 仅在档案被直接执行时 才运行,而在该档案被汇入为模组时不执行。

    • 使用时机:

    • 需要使用:
      • 当档案既可被汇入又可直接执行。
      • 希望在直接执行时进行测试或示范。
    • 不需要使用:
      • 纯模组:只定义函式、类别或变数,无需直接执行。
      • 一次性脚本:专为直接执行设计,不会被汇入。
    • 作用:
      • 防止副作用: 避免在汇入时执行不必要的程式码。
      • 提高模组的可重用性: 使模组既可被汇入,又可在直接执行时进行测试。
      • 改善程式的结构: 清晰地分离模组的介面和执行逻辑。

    下一篇python : PyPI & pip