【问题标题】:How does python know what __name__ should be?python如何知道__name__应该是什么?
【发布时间】:2018-01-16 15:43:55
【问题描述】:

从命令行运行脚本,该脚本的__name__ 属性将为'__main__'。但是import从不同位置调用该脚本,该模块的__name__ 属性将是脚本的名称。

python如何知道__name__的值应该是多少?脚本可以告诉它正在被导入,并相应地设置__name__ 属性吗?

【问题讨论】:

  • 如果是模块,__name__ 是模块的名称。
  • @WillemVanOnsem 已编辑以确保准确性

标签: python import namespaces python-import python-internals


【解决方案1】:

From the docs

在加载器执行模块之前,导入机制会在加载期间根据模块的规范在每个模块对象上填充这些属性。

__name__
__name__ 属性必须设置为模块的完全限定名称。此名称用于唯一标识导入系统中的模块。

所以这些魔法属性是在所谓的“导入机制”期间分配的。您也可以阅读更多详情about that system in the docs

【讨论】:

    【解决方案2】:

    问:python如何知道__name__的值应该是多少?

    好吧,如果你写import foo,Python 将寻找一个名为“foo”的模块并将其名称设置为“foo”。

    问:一个模块能否告诉它正在被导入,...

    是的,可以。通常人们用if __name__ == '__main__' 来做这件事——如果测试通过,通常意味着模块正在执行,如果失败,通常意味着它正在被导入。

    当您有一个名为 __main__ 的模块(在名为 __main__.py 的文件中)时,此测试将失败的特殊情况。

    如果您想更加确定 100%,您可以检查 frames 并查看模块是否位于堆栈顶部:

    f = sys._getframe()
    if f.f_back is None:
        # We're at the top of the stack: this module is being executed.
    else:
        # There's a frame on top of us: this module has been imported.
    

    问: ...并相应地设置__name__ 属性?

    是的,您可以通过简单的设置将__name__ 更改为您想要的任何内容:

    __name__ = 'bar'
    

    虽然没有理由这样做,但会产生混乱并可能引入错误。

    【讨论】:

      猜你喜欢
      • 2012-08-01
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      • 2014-04-09
      • 1970-01-01
      • 1970-01-01
      • 2020-02-23
      • 2012-12-13
      相关资源
      最近更新 更多