【问题标题】:__main__ and scoping in python__main__ 和 python 中的作用域
【发布时间】:2011-06-14 02:51:01
【问题描述】:

我对以下行为感到有些惊讶:

def main():
    print "%s" % foo

if __name__ == "__main__":
    foo = "bar"
    main()

即模块函数可以访问__main__ 中的封闭变量。对此有何解释?

【问题讨论】:

  • 没有范围__main__。有一个 if 恰好将一个恰好被称为 __name__ 的变量与恰好是字符串文字 "__main__" 的变量进行比较。
  • @delnan:__main__ 是一个模块,每个模块都有一个关联的范围。在解释器中尝试import __main__; type(__main__)(不是在 IPython 中)。
  • @Sven:我知道。 OP应该在某个时候知道。但在我看来,OP 反而将 if 语句与部分条件混淆,并认为 if 引入了一个新的范围——这将是一个更紧迫的问题。 (诚​​然,“严格来说,“没有范围__main__ 具有误导性)
  • @delnan:你是对的。回想起来,我不知道我为什么感到困惑。也许在凌晨 3 点调试代码毕竟不是一个好主意 :)
  • 我只是偶然发现了这种完全相同的行为......以为我快疯了。很高兴看到其他人已经问过这个问题!解释答案时行为很明显......

标签: python scope


【解决方案1】:

当前模块全局范围内的变量在模块中随处可见——这条规则也适用于__main__ 模块。

来自Guido's tutorial

在执行过程中的任何时候,至少有三个嵌套作用域的命名空间是可以直接访问的:

  • 最里面的范围,首先搜索,包含本地名称
  • 任何封闭函数的范围,从最近的开始搜索 封闭范围,包含非本地名称,但也包含非全局名称
  • 倒数第二个作用域包含当前模块的全局名称
  • 最外层范围(最后搜索)是包含内置名称的命名空间

【讨论】:

  • @AA:主脚本被 Python 视为一个名为 __main__ 的模块。你甚至可以import __main__(但通常这是个坏主意)。
  • __main__ 调用的函数中使用__main__ 模块中定义的变量而不显式传递它们是否被认为是一种好习惯?
  • @emilaz 不,绝对不是。尽可能避免使用全局变量。 :)
【解决方案2】:

这里的事情是:

if __name__ == "__main__":
    foo = "bar"

在该脚本中定义了一个名为 foo 的全局变量。所以该模块的任何功能都可以访问它。

上面列出的这段代码对模块来说是全局的,而不是在任何函数内部。

【讨论】:

    【解决方案3】:

    foo 是一个模块全局变量(它不在任何函数中)。模块内的所有作用域都可以访问它。

    【讨论】:

      【解决方案4】:

      在python中有全局作用域,函数有自己的作用域。因此,如果您在 name==main 下定义 foo,它就在全局范围内。此外,在函数中使用尚未声明的变量也不是错误的,如果在调用函数时将声明它。

      【讨论】:

        【解决方案5】:

        正如 sinelaw 所指出的,解决这种烦恼和无意错误的方法是使用函数。该函数可以在 'if ma​​in:' 中,如下所示:

        if __name__ == "__main__":
            def mainlet():
                foo = "bar"
            mainlet()
        

        【讨论】:

          猜你喜欢
          • 2016-05-17
          • 2013-02-09
          • 2021-12-25
          • 1970-01-01
          • 1970-01-01
          • 2015-04-04
          • 1970-01-01
          • 1970-01-01
          • 2012-07-04
          相关资源
          最近更新 更多