2015-03-31 70 views
1

我有以下文件app.pyPython导入语句是否也自动导入相关性?

class Baz(): 
    def __init__(self, num): 
     self.a = num 
     print self.a 

def foo(num): 
    obj = Baz(num) 

第二个文件main.py

from app import foo 
foo(10) 

运行文件python main.py给出正确的输出。

现在在第二个文件中,我只是导入函数而不是类,尽管成功执行我的函数也需要类。

导入函数时,Python会自动导入运行该函数所需的所有内容,还是会自动搜索当前目录中的类?

回答

2

正如@DavidZ已经提到的那样,当我们导入整个Python文件时就会被编译。但是另一件特别的事情发生在函数体被解析时,函数知道它应该在本地作用域中查找哪些变量以及它应该在全局作用域中寻找哪些变量(以及有自由变量)。

>>> import dis 
>>> dis.dis(foo) 
    7   0 LOAD_GLOBAL    0 (Baz) 
       3 LOAD_FAST    0 (num) 
       6 CALL_FUNCTION   1 
       9 STORE_FAST    1 (obj) 
      12 LOAD_CONST    0 (None) 
      15 RETURN_VALUE 

所以,这里的Baz必须从全局范围提取。

但是当我们在另一个 文件中导入app.py时,如何识别这个全局范围?

那么,每个函数都有一个特殊的属性__globals__附加到它包含其实际的全局命名空间。因此,这就是Baz来源:

>>> foo.__globals__['Baz'] 
<class __main__.Baz at 0x10f6e1c80> 

因此,应用程序的模块字典和foo.__globals__指向同一个对象:

>>>sys.modules['app'].__dict__ is foo.__globals__ 
True 

由于此,即使你定义导入后在main.py命名Baz另一个变量foo它仍然会访问实际的Baz

data-model page

__globals__ func_globals

的引用保存功能的全球 变量字典 - 其中功能 定义的模块的全局命名空间。

+0

这是整洁。所以我不应该把不相关的代码放在一个文件中,如果我的意图是只加载一个函数,因为Python会一直编译整个文件,对吗? – 2015-03-31 11:25:22

+0

@KartikAnand Python只会将它编译成一个'.pyc'文件,稍后导入只需从同一个'.pyc'文件中获取字节码,直到您再次更新'.py'文件。 – 2015-03-31 11:27:05

+0

因此,如果我没有明确导入'Baz',我可以通过从函数附加的'__globals__'来实例化它吗? – 2015-03-31 11:30:40

1

Python不会自动执行任何这些操作。

当您从模块(在本例中为app模块)导入某些内容时,Python首先运行相应文件(app.py)中的所有代码。您已写入的文件app.py中的代码做了两两件事:

  1. 定义类Baz
  2. 定义函数foo

当函数foo运行,巨蟒在寻找Bazfoo是其中的一部分,并且仅限于此。 (好吧,它也检查函数foo中定义的局部变量,但是除了obj之外,您没有任何其他变量。)具体而言,它会查找app.Baz。如果你改变你的main.py做同样的搜索:

from app import foo 
foo(10) 
import app # same app that was already imported 
print app.Baz 

你会看到app.Baz是您在app.py定义的类。

如果您将Baz类的定义放在另一个文件中,并且您不导入该文件,Python将不会运行它。这表明Python确实不是自动导入依赖关系。具体而言,假设app.py包含

def foo(num): 
    obj = Baz(num) 

baz.py包含

class Baz(): 
    def __init__(self, num): 
     self.a = num 
     print self.a 

main.py不变。你会得到一个错误,因为Python没有运行代码来定义类Baz

+0

我知道关于定义部分。当它运行文件时,它是否以某种形式在当前文件中存储Class的定义部分? – 2015-03-31 11:19:22

+0

看我的编辑是否有助于澄清任何事 – 2015-03-31 11:25:33