python之from 和import執行過程分析

來源:互聯網
上載者:User

標籤:找不到   第一步   內建函數   sdn   使用   code   ofo   說明   attr   

原文連結:http://blog.csdn.net/lis_12/article/details/52883729

問題1

同一個目錄下,有兩個Python檔案,A.py,B.py

#A.pyfrom B import Dclass C(object):    pass#B.pyfrom A import Cclass D(object):    pass‘‘‘執行A.py結果:Traceback (most recent call last):  File "A.py", line 4, in <module>    from B import D  File "B.py", line 4, in <module>    from A import C  File "A.py", line 4, in <module>    from B import DImportError: cannot import name D‘‘‘

 

why?

from B import D的執行機制

可以利用sys.modules查看是否包含B模組,如查看os模組,輸入

>>> sys.modules[‘os’].

  1. 存在模組B

    如果sys.modules有B這個鍵,就會擷取相對應的值,也就是modules對象,然後從模組B的__dict__列表中尋找並擷取名稱為D的對象,如果不存在,拋出異常.

    模組B的__dict__列表可利用dir(B)來查看.

  2. 不存在模組B

    如果不存在B這個鍵的話,則會為B建立一個模組對象,此時模組對象的__dict__列表為空白,然後在搜尋路徑下尋找並執行B.py,以填充模組B對象的__dict__列表,然後從__dict__列表中尋找名稱為D的對象,如果找不到,則拋出異常.

    注:module ,模組的意思

 

根據上面修改代碼,查看sys.modules變化情況

#A.py#!/usr/bin/python# -*- coding: utf-8 -*-import systry:    print ‘module B: %s‘%sys.modules[‘B‘]except Exception,e:    print u‘沒有module B  %s‘%etry:    print ‘module A: %s‘%sys.modules[‘A‘]except Exception,e:    print u‘沒有module A  %s‘%efrom B import Dclass C(object):    pass#B.pyfrom A import Cclass D(object):    pass‘‘‘執行A.py結果:沒有module B  ‘B‘沒有module A  ‘A‘module B: <module ‘B‘ from ‘B.pyc‘>module A: <module ‘A‘ from ‘A.py‘>Traceback (most recent call last):  File "A.py", line 4, in <module>    from B import D  File "B.py", line 4, in <module>    from A import C  File "A.py", line 4, in <module>    from B import DImportError: cannot import name D
問題1答案
  1. 運行A.py,當執行到from B import D語句時,因為還沒有運行過B.py,所以sys.modules中沒有B這個鍵.會建立一個鍵B並賦值為模組B對象,只不過此時模組B對象是空的,裡面什麼都沒有;
  2. 然後,暫停執行A.py的其他語句,Python 在搜尋路徑下尋找B.py,找到同目錄下的B.py並運行,為了填充模組B對象中的__dict__列表.當執行到from A import C時,也會檢查sys.modules中是否有名為A的模組,但因為A.py還沒有讀取完,所以並沒有在sys.modules中緩衝對應的資訊.同樣,Python 會建立一個鍵A並賦值為空白的模組A對象.暫停執行B.py並尋找、從頭執行A.py.
  3. 這時,會再次執行到from B import D語句,由於在第一步時已經在sys.modules建立了鍵B的模組B對象,所以直接擷取到,但此時模組B對象中的__dict__列表還是空的,裡面什麼都沒有啊,所以找不到名為D的對象,拋出異常.

對照運行結果,是不是很符合- -!

(表述能力有限,多看代碼吧- -)

問題2 將上述from import 換成 import
#A1.py#!/usr/bin/python# -*- coding: utf-8 -*-import systry:    print ‘module B1: %s‘%sys.modules[‘B1‘]except Exception,e:    print u‘沒有module B1 %s‘%etry:    print ‘module A1: %s‘%sys.modules[‘A1‘]except Exception,e:    print u‘沒有module A1 %s‘%eimport B1class C(object):    passtry:    B1.D()except Exception,e:    print u‘B中沒有屬性D‘,e#B1.pyimport A1class D(object):    pass‘‘‘執行A.py結果:沒有module B1 ‘B1‘沒有module A1 ‘A1‘module B1: <module ‘B1‘ from ‘B1.pyc‘>module A1: <module ‘A1‘ from ‘A1.py‘>B中沒有屬性D ‘module‘ object has no attribute ‘D‘‘‘‘

由程式結果可知,將from…import…改成import後,程式不會出錯了,但是調用B1.D()時為什麼會拋出異常呢?

問題2答案
  1. 運行A1.py,當執行到import B1語句時,因為還沒有運行過B1.py,所以sys.modules中沒有B1這個鍵.會建立一個鍵B1並賦值為模組B1對象,只不過此時這個模組對象是空的,裡面什麼都沒有;

  2. 然後,暫停執行A1.py的其他語句,Python 在搜尋路徑下尋找B1.py,找到同目錄下的B1.py並運行,為了填充模組B1對象中的__dict__列表.當執行到import A1時,也會檢查sys.modules中是否有名為A1的模組,但因為A1.py還沒有讀取完,所以並沒有在sys.modules中緩衝對應的資訊.然後,同樣的,Python 會建立一個鍵A1並賦值為空白的模組A1對象.暫停執行B1.py並尋找、從頭執行A1.py.

  3. 這時,會再次執行到import B1語句,由於在第一步時已經在sys.modules建立了模組B1對象,模組B1對象已經存在了,不需要執行B1.py,所以繼續執行A1.py中的其他內容.

    注意:此時模組B1仍為空白的,裡面什麼都沒有.

  4. 當執行到B1.D()時,由於在模組B1對象的__dict__列表找不到名為D的對象,拋出異常.

問題3 修改問題1中的程式使的能正確運行
#A2.pyfrom B2 import Dclass C(object):    pass#B2.pyclass D(object):    passfrom A2 import C

簡單說明:

A2.py->B2.py->A2.py時,D屬性已經在B2的__dict__列表中了,所以不會報錯…雖然這樣寫不會報錯,但是強烈不推薦這麼寫….

總結

當Python程式匯入其他模組時,要避免迴圈匯入,不然總會出意向不到的問題….

注:迴圈匯入,即A檔案匯入了B,B檔案又匯入了A.

 

重新匯入模組
如果更新了一個已經用import語句匯入的模組,內建函數reload()可以重新匯入並運行更新後的模組代碼.它需要一個模組對象做為參數.例如: 
import foo
... some code ...
reload(foo)          # 重新匯入 foo

在reload()運行之後的針對模組的操作都會使用新匯入代碼,不過reload()並不會更新使用舊模組建立的對象,因此有可能出現新舊版本對象共存的情況。*注意* 使用C或C++編譯的模組不能通過 reload() 函數來重新匯入。記住一個原則,除非是在調試和開發過程中,否則不要使用reload()函數

 

python之from 和import執行過程分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.