为什么"导入模块"中的全局变量的行为不同? vs"来自模块导入*"?

时间:2015-11-13 07:45:24

标签: python python-3.x

a.py 成为:

def foo():
    global spam
    spam = 42
    return 'this'

在控制台上,如果我只是import a,那么事情对我来说很有意义:

>>> import a
>>> a.foo()
'this'
>>> a.spam
42

然而,如果我做不那么受欢迎的事情......

>>> from a import *
>>> foo()
'this'
>>> spam
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined
>>> a.spam
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined

我已经阅读过关于人们为什么不喜欢&#34; from module import *&#34;从命名空间的角度来看,但我无法找到关于这种行为的任何内容,坦率地说,我发现这是我偶然遇到的问题。

3 个答案:

答案 0 :(得分:10)

当您要求func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool { if navigationType == UIWebViewNavigationType.LinkClicked { if (request.URL!.absoluteString == generatedURL[index] { let requestObj = NSMutableURLRequest(URL: appDelegate.cachedURL[index]!); webView.loadRequest(requestObj) //return false } } return true } 时,模块a.spam中会发生命名空间搜索,并找到a。但是,当你要求spam时:

spam

>>> from a import * # imported foo, spam doesn't exist yet >>> foo() 是在命名空间中创建的(虽然您无法使用此类导入访问它),但在当前模块中却没有。并且似乎没有人承诺我们将spam新添加的全局变量添加到所有名称空间模块a已导入到a。这将需要在解释器中存储导入链接,如果一个重度导入的模块一直在做这样的技巧,可能会降低性能。

假设您在调用*之前已在主模块中定义了spam。这将是彻头彻尾的名字冲突。

就像插图一样,您可以foo()获取模块from a import *的最新更新:

a

答案 1 :(得分:2)

让我们一步一步彻底解读:

在导入时,a只有一个引用功能的符号foo

只有在执行该功能时,a才会获得附加符号spam

在第一种情况下,您执行import a并获取模块的“句柄”,这样您就可以监视稍后发生的事情。如果您在致电a.spam之前执行a.foo(),则会收到错误。

在第二种情况下,from a import *会为您提供模块中当前的内容 - 而这只是spam()。在调用之后,您也可以from a import *获取spam

答案 2 :(得分:1)

我普遍同意Vovanrock2002。

正如最近向我解释的那样,'。'是范围解析运算符。 import afrom a import *为您提供了不同的语法。 from a import *分别从a导入每个全局变量,并将它们绑定为本地范围内的变量。更实际的示例可能是import datetimefrom datetime import date之间的差异。对于前者,我必须使用datetime.date(2015, 11, 12)创建日期对象,后者我只需使用date(2015, 11, 12)

您可以在import statement

上阅读更多内容

但是,我不得不与你不同,因为我不相信垃圾邮件是生命,宇宙和一切的意义。