如果优name_u==”uuu main_uu“:怎么办?

  • 问题:
  • 给定下面的代码,if yu name_yu==”uMain_Uu“:会做什么?在

    # Threading example
    import time, thread

    def myfunction(string, sleeptime, lock, *args):
    while True:
    lock.acquire()
    time.sleep(sleeptime)
    lock.release()
    time.sleep(sleeptime)

    if __name__ == "__main__":
    lock = thread.allocate_lock()
    thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
    thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))

  • 答案:
  • 每当Python解释器读取一个源文件时,它会做两件事:

    它设置了一些特殊的变量,如\uuname\uu,然后

    它执行文件中找到的所有代码

    让我们看看这是如何工作的,以及它与您关于Python脚本中经常看到的检查的问题的关联

    让我们使用稍微不同的代码示例来研究导入和脚本的工作方式。假设以下内容位于名为食品

    # Suppose this is foo.py.

    print("before import")
    import math

    print("before functionA")
    def functionA():
    print("Function A")

    print("before functionB")
    def functionB():
    print("Function B {}".format(math.sqrt(100)))

    print("before __name__ guard")
    if __name__ == '__main__':
    functionA()
    functionB()
    print("after __name__ guard")

    当Python interpeter读取源文件时,它首先定义几个特殊的变量。在本例中,我们关心的是变量\uuname\

    当您的模块是主程序时

    如果你正在运行你的模块(源文件)作为主程序,例如

    python foo.py

    解释器将硬编码的字符串“umain_u”分配给\uuuname_u变量,即

    # It's as if the interpreter inserts this at the top
    # of your module when run as the main program.
    __name__ = "__main__"

    当您的模块被另一个导入时

    另一方面,假设另一个模块是主程序,它导入您的模块。这意味着在主程序中,或在主程序导入的其他模块中有这样一个语句:

    # Suppose this is in some other main program.
    import foo

    翻译程序将搜索您的食品文件(同时搜索其他几个变量),在执行该模块之前,它将把import语句中的name“foo”赋值给变量

    # It's as if the interpreter inserts this at the top
    # of your module when it's imported from another module.
    __name__ = "foo"

    设置好特殊变量后,解释器执行模块中的所有代码,一次执行一条语句。您可能需要在代码示例旁边打开另一个窗口,这样您就可以按照下面的说明进行操作

    始终

    它打印字符串“before import”(不带引号)

    它加载math模块并将其分配给一个名为math的变量。这相当于将import math替换为以下内容(请注意,import_yu是Python中的一个低级函数,它接受一个字符串并触发实际的导入):

    # Find and load a module given its string name, "math",
    # then assign it to a local variable called math.
    math = __import__("math")

    它打印字符串“before function”

    它执行def块,创建一个function对象,然后将该function对象赋给一个名为function的变量

    它打印字符串“before functionB”

    它执行第二个def块,创建另一个function对象,然后将其赋给一个名为functionB的变量

    它将打印字符串“before”\\\.guard“

    仅当您的模块被另一个导入时

    始终

    摘要

    总而言之,这两种情况下的打印结果如下:

    # What gets printed if foo is the main program
    before import
    before functionA
    before functionB
    before __name__ guard
    Function A
    Function B 10.0
    after __name__ guard
    # What gets printed if foo is imported as a regular module
    before import
    before functionA
    before functionB
    before __name__ guard
    after __name__ guard

    你可能很自然地想知道为什么有人会想要这个。好吧,有时候你想写一个.py文件,它既可以被其他程序和/或模块作为模块使用,也可以作为主程序本身运行。示例:

    您的模块是一个库,但是您希望有一个脚本模式,在这种模式下它运行一些单元测试或演示

    您的模块仅用作主程序,但它有一些单元测试,测试框架通过导入.py文件(如脚本)并运行特殊的测试函数来工作。您不希望它仅仅因为它正在导入模块就尝试运行脚本

    您的模块主要用作主程序,但它也为高级用户提供了一个程序员友好的API

    除了这些例子之外,在Python中运行脚本只需设置几个魔术变量并导入脚本就可以了。”运行“脚本是导入脚本模块的副作用

    问题:我可以有多个检查块吗?回答:这样做很奇怪,但语言不会阻止你

    假设以下内容在foo2.py中。如果在命令行上说python foo2.py,会发生什么情况?为什么?在

    # Suppose this is foo2.py.
    import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

    def functionA():
    print("a1")
    from foo2 import functionB
    print("a2")
    functionB()
    print("a3")

    def functionB():
    print("b")

    print("t1")
    if __name__ == "__main__":
    print("m1")
    functionA()
    print("m2")
    print("t2")

    # Suppose this is foo3.py.
    import os, sys; sys.path.insert(0, os.path.dirname(__file__)) # needed for some interpreters

    def functionA():
    print("a1")
    from foo3 import functionB
    print("a2")
    functionB()
    print("a3")

    def functionB():
    print("b")

    print("t1")
    print("m1")
    functionA()
    print("m2")
    print("t2")
    # Suppose this is in foo4.py
    __name__ = "__main__"

    def bar():
    print("bar")

    print("before __name__ guard")
    if __name__ == "__main__":
    bar()
    print("after __name__ guard")