确认导入*和xxx导入*之间的区别

发布于 2021-01-29 18:09:56

我很惊讶地发现

import foo

from foo import *

对全球成员产生了不同的影响。我想确认我的实验是正确的行为。

在第一个示例中,更改foo模块中的成员将反映在所有导入foo的代码中。但是,在以后的情况下更改该成员似乎仅影响导入该成员的文件。换句话说,使用后一种方法将为每个导入文件提供其自己的foo成员副本。

我想要的行为是可以从所有文件访问foo.x,可以从所有文件更改它,并在所有文件中反映该更改(如果愿意,则为真正的全局)。

关注者
0
被浏览
47
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    是的,您的观察是正确的。这是绑定在Python中起作用的方式的结果。

    当一个

    import foo
    

    然后foo成为引用该模块的全局名称foo。当一个

    foo.bar = 7
    

    然后遵循引用并foo加载该对象。然后7存储在bar属性中。

    当另一个模块导入时foo,它只是将对象拉出sys.modules['foo']并获取修改后的值。

    当一个

    from foo import bar
    

    globals()['bar']设置为参考foo.bar。以后再做

     bar = 7
    

    globals()['bar']不再引用,foo.bar而是引用的副本7。即,仅替换了导入模块全局范围内的原始绑定。

    在第一个示例中,一个方法是修改存储在其中的对象的属性,该属性sys.modules对于已导入该对象的所有模块都是通用的。在第二个示例中,一个正在修改导入模块的全局范围。

    如果要按照以下方式做某事

     from foo import fobaz
     fobaz.foobar = 7
    

    然后,该更改 传播到其他导入模块,因为不会 覆盖 全局引用而是 跟随
    全局引用来修改它指向的对象的属性。因此,从本质上讲,只要不覆盖全局绑定,就应该能够修改可变对象。

    我认为类似这样的东西是您将能够完全使用python达到真正全局性的最接近的东西。作为一种语言,它极大地重视名称空间。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看