当前位置: 首页 > 面试题库 >

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

马浩淼
2023-03-14
问题内容

我很惊讶地发现

import foo

from foo import *

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

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

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


问题答案:

是的,您的观察是正确的。这是绑定在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达到真正全局性的最接近的东西。作为一种语言,它极大地重视名称空间。



 类似资料:
  • 问题内容: 在Python中,我不太清楚以下两行代码之间的区别: 要么 他们不是都只是从模块X导入所有内容吗?有什么不同? 问题答案: 之后,你可以参考的东西一样。之后,您可以像一样直接引用事物。因为第二种形式将名称直接导入到本地名称空间,所以如果您从许多模块中导入内容,则可能会产生冲突。因此,不鼓励使用。 您也可以执行,仅将导入到本地名称空间,而不导入中的所有内容。这样做会更好,因为如果您列出了

  • 问题内容: 说,我们在ES6中使用React。我们将React和Component导入为 为什么语法不同?我们不能按以下规定使用吗? 问题答案: 下面是文档的。 以上是默认导入。默认导入使用导出。只能有一个默认导出。 但这是成员导入(称为导入)。成员进口与出口。可以有很多成员出口。 您可以使用以下语法导入两者: 在JavaScript中,默认导入和命名导入被拆分,因此您不能像默认导入那样导入命名导

  • 问题内容: 我知道这是一个愚蠢的问题,但我才刚刚开始学习python,但我对python并不了解。我的问题是之间有什么区别 和 为什么我不能写 谁能抽出几分钟来启发我? 问题答案: 将Tkinter中的每个公开对象导入到您当前的名称空间中。 导入名称空间中的“名称空间” Tkinter并 执行相同的操作,但是在本地将其“重命名”为“ tk”以节省您的输入 假设我们有一个模块foo,其中包含类A,B

  • 问题内容: 在Java中,我们既可以导入单个类,也可以导入整个类集(一个包)。 举个例子 包括 除了代码的长度之外,以任何方式使用每种方法是否有特定的优势?内存分配?性能? 问题答案: 两者都没有性能或内存分配优势,它们都将编译为相同的字节码。 该语句是告诉编译器在哪里可以找到源代码所引用的类。 但是,仅按类导入有一个优势。如果在两个包中有一个名称完全相同的类,则在引用哪个类时就会发生冲突。 类和

  • 问题内容: 我有一个用ES6编写的node.js库(与Babel一起编译),在其中导出了以下子模块: 如果从我的主要项目中,我包括这样的图书馆 我可以看到正确的输出,并且可以按预期工作。但是,如果我尝试包含这样的库: 会的。 有人可以解释这里发生了什么吗?这两种导入方法不应该等效吗?如果没有,我想念什么? 问题答案: 正在请求一个具有所有“ lib”命名出口的对象。 被命名为exports,这就是

  • 问题内容: 我知道在Java中,我们使用*(星号)将所有内容导入包中 那么为什么不在C#中使用相同的*(星号)来导入所有内容,有没有像Java中那样的方法来导入所有内容。之间有什么区别 和 问题答案: Java 所做的.NET称为引用- 在.NET中添加对程序集的 引用 ,使您可以使用该程序集中定义的(公共)类型。 C#指令只是一种无需输入整个名称空间即可访问这些类型的方法。 您还 可以 使用指令