亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

python之import機(jī)制詳解

 更新時(shí)間:2014年07月03日 16:55:13   投稿:shichen2014  
這篇文章主要介紹了python的import機(jī)制,需要的朋友可以參考下

本文詳述了Python的import機(jī)制,對(duì)于理解Python的運(yùn)行機(jī)制很有幫助!

1.標(biāo)準(zhǔn)import:

Python中所有加載到內(nèi)存的模塊都放在 sys.modules 。當(dāng) import 一個(gè)模塊時(shí)首先會(huì)在這個(gè)列表中查找是否已經(jīng)加載了此模塊,如果加載了則只是將模塊的名字加入到正在調(diào)用 import 的模塊的 Local 名字空間中。如果沒有加載則從 sys.path 目錄中按照模塊名稱查找模塊文件,模塊可以是py、pyc、pyd,找到后將模塊載入內(nèi)存,并加到 sys.modules 中,并將名稱導(dǎo)入到當(dāng)前的 Local 名字空間。

一個(gè)模塊不會(huì)重復(fù)載入。多個(gè)不同的模塊都可以用 import 引入同一個(gè)模塊到自己的 Local 名字空間,其實(shí)背后的 PyModuleObject 對(duì)象只有一個(gè)。這里說一個(gè)容易忽略的問題:import 只能導(dǎo)入模塊,不能導(dǎo)入模塊中的對(duì)象(類、函數(shù)、變量等)。例如:模塊 A(A.py)中有個(gè)函數(shù) getName,另一個(gè)模塊不能通過 import A.getName 將 getName導(dǎo)入到本模塊,只能用 from A import getName。

2.嵌套import:

1)順序嵌套

例如:本模塊導(dǎo)入 A 模塊(import A),A 中又 import B,B 模塊又可以 import 其他模塊……
這中嵌套比較容易理解,需要注意的一點(diǎn)就是各個(gè)模塊的 Local 名字空間是獨(dú)立的。對(duì)于上面的例子,本模塊 import A 之后本模塊只能訪問模塊 A,不能訪問模塊 B 及其他模塊。雖然模塊 B 已經(jīng)加載到內(nèi)存了,如果訪問還要再明確的在本模塊中 import B。

2)循環(huán)嵌套

例如:

文件[A.py]

from B import D
class C:pass

文件[ B.py ]

from A import C
class D:pass

為什么執(zhí)行 A 的時(shí)候不能加載 D 呢?
如果將 A.py 改為:import B 就可以了。
這是怎么回事呢?

RobertChen:這跟Python內(nèi)部 import 的機(jī)制是有關(guān)的,具體到 from B import D,Python 內(nèi)部會(huì)分成幾個(gè)步驟:
(1)在 sys.modules 中查找符號(hào) “B”
(2)如果符號(hào) B 存在,則獲得符號(hào) B 對(duì)應(yīng)的 module 對(duì)象。
  從 <modult B> 的 __dict__ 中獲得符號(hào) “D” 對(duì)應(yīng)的對(duì)象,如果 “D” 不存在,則拋出異常。
(3)如果符號(hào) B 不存在,則創(chuàng)建一個(gè)新的 module 對(duì)象 <module B>,注意,此時(shí),module 對(duì)象的 __dict__ 為空。
執(zhí)行 B.py 中的表達(dá)式,填充 <module B> 的 __dict__。
從  <module B> 的 __dict__ 中獲得 “D” 對(duì)應(yīng)的對(duì)象,如果 “D” 不存在,則拋出異常。

所以這個(gè)例子的執(zhí)行順序如下:

1、執(zhí)行 A.py 中的 from B import D 由于是執(zhí)行的 python A.py,所以在 sys.modules 中并沒有 <module B> 存在, 首先為 B.py 創(chuàng)建一個(gè) module 對(duì)象 (<module B>) , 注意,這時(shí)創(chuàng)建的這個(gè) module 對(duì)象是空的,里邊啥也沒有, 在 Python 內(nèi)部創(chuàng)建了這個(gè) module 對(duì)象之后,就會(huì)解析執(zhí)行 B.py,其目的是填充 <module B> 這個(gè) __dict__。
2、執(zhí)行 B.py中的from A import C 在執(zhí)行B.py的過程中,會(huì)碰到這一句, 首先檢查sys.modules這個(gè)module緩存中是否已經(jīng)存在<module A>了, 由于這時(shí)緩存還沒有緩存<module A>, 所以類似的,Python內(nèi)部會(huì)為A.py創(chuàng)建一個(gè)module對(duì)象(<module A>), 然后,同樣地,執(zhí)行A.py中的語(yǔ)句
3、再次執(zhí)行A.py中的from B import D 這時(shí),由于在第1步時(shí),創(chuàng)建的<module B>對(duì)象已經(jīng)緩存在了sys.modules中, 所以直接就得到了<module B>, 但是,注意,從整個(gè)過程來看,我們知道,這時(shí)<module B>還是一個(gè)空的對(duì)象,里面啥也沒有, 所以從這個(gè)module中獲得符號(hào)"D"的操作就會(huì)拋出異常。 如果這里只是import B,由于"B"這個(gè)符號(hào)在sys.modules中已經(jīng)存在,所以是不會(huì)拋出異常的。

ZQ:圖解如下:

3. 包 import

只要一個(gè)文件夾下面有個(gè) __init__.py 文件,那么這個(gè)文件夾就可以看做是一個(gè)包。包導(dǎo)入的過程和模塊的基本一致,只是導(dǎo)入包的時(shí)候會(huì)執(zhí)行此包目錄下的 __init__.py 而不是模塊里面的語(yǔ)句了。另外,如果只是單純的導(dǎo)入包,而包的 __init__.py 中又沒有明確的其他初始化操作,那么此包下面的模塊是不會(huì)自動(dòng)導(dǎo)入的。
 例如:
  有下面的包結(jié)構(gòu):
  PA
  |---- __init__.py
  |---- wave.py
  |---- PB1
        |---- __init__.py
        |---- pb1_m.py
  |---- PB2
        |---- __init__.py
        |---- pb2_m.py
有如下程序:

import sys
import PA.wave              #1
import PA.PB1                #2
import PA.PB1.pb1_m as m1    #3
import PA.PB2.pb2_m          #4
PA.wave.getName()           #5
m1.getName()                #6
PA.PB.pb2_m.getName()       #7

1) 當(dāng)執(zhí)行 #1 后,sys.modules 會(huì)同時(shí)存在 PA、PA.wave 兩個(gè)模塊,此時(shí)可以調(diào)用 PA.wave 的任何類或函數(shù)了。但不能調(diào)用 PA.PB1(2) 下的任何模塊。當(dāng)前 Local 中有了 PA 名字。

2) 當(dāng)執(zhí)行 #2 后,只是將 PA.PB1 載入內(nèi)存,sys.modules 中會(huì)有 PA、 PA.wave、PA.PB1 三個(gè)模塊,但是 PA.PB1 下的任何模塊都沒有自動(dòng)載入內(nèi)存,此時(shí)如果直接執(zhí)行 PA.PB1.pb1_m.getName() 則會(huì)出錯(cuò),因?yàn)?PA.PB1 中并沒有 pb1_m 。當(dāng)前 Local 中還是只有 PA 名字,并沒有 PA.PB1 名 字。

3) 當(dāng)執(zhí)行 #3 后,會(huì)將 PA.PB1 下的 pb1_m 載入內(nèi)存,sys.modules 中會(huì)有 PA、PA.wave、PA.PB1、PA.PB1.pb1_m 四個(gè)模塊,此時(shí)可以執(zhí)行 PA.PB1.pb1_m.getName() 了。由于使用了 as,當(dāng)前 Local中除了 PA 名字,另外添加了 m1 作為 PA.PB1.pb1_m 的別名。

4) 當(dāng)執(zhí)行 #4 后,會(huì)將 PA.PB2、PA.PB2.pb2_m 載入內(nèi)存,sys.modules 中會(huì)有 PA、PA.wave、PA.PB1、PA.PB1.pb1_m、PA.PB2、PA.PB2.pb2_m 六個(gè)模塊。當(dāng)前 Local 中還是只有 PA、m1。
下面的 #5,#6,#7 都是可以正確運(yùn)行的。

注意的是:如果 PA.PB2.pb2_m 想導(dǎo)入 PA.PB1.pb1_m、PA.wave 是可以直接成功的。最好是采用明確的導(dǎo)入路徑,對(duì)于 ./.. 相對(duì)導(dǎo)入路徑還是不推薦用。

相關(guān)文章

  • python 實(shí)現(xiàn)在shell窗口中編寫print不向屏幕輸出

    python 實(shí)現(xiàn)在shell窗口中編寫print不向屏幕輸出

    這篇文章主要介紹了python 實(shí)現(xiàn)在shell窗口中編寫print不向屏幕輸出的代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • 10款最好的Python開發(fā)編輯器

    10款最好的Python開發(fā)編輯器

    這篇文章主要介紹了10款最好的Python開發(fā)編輯器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • 完美處理python與anaconda環(huán)境變量的沖突問題

    完美處理python與anaconda環(huán)境變量的沖突問題

    這篇文章主要介紹了完美處理Python與anaconda環(huán)境變量的沖突問題,對(duì)anaconda感興趣的同學(xué),可以參考下
    2021-04-04
  • Django實(shí)現(xiàn)微信小程序支付的示例代碼

    Django實(shí)現(xiàn)微信小程序支付的示例代碼

    這篇文章主要介紹了Django實(shí)現(xiàn)微信小程序支付的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • pycharm遠(yuǎn)程linux開發(fā)和調(diào)試代碼的方法

    pycharm遠(yuǎn)程linux開發(fā)和調(diào)試代碼的方法

    這篇文章主要介紹了pycharm遠(yuǎn)程linux開發(fā)和調(diào)試代碼的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-07-07
  • Python單個(gè)項(xiàng)目列表轉(zhuǎn)換為整數(shù)的實(shí)現(xiàn)

    Python單個(gè)項(xiàng)目列表轉(zhuǎn)換為整數(shù)的實(shí)現(xiàn)

    本文主要介紹了Python單個(gè)項(xiàng)目列表轉(zhuǎn)換為整數(shù)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 解決pyinstaller打包發(fā)布后的exe文件打開控制臺(tái)閃退的問題

    解決pyinstaller打包發(fā)布后的exe文件打開控制臺(tái)閃退的問題

    今天小編就為大家分享一篇解決pyinstaller打包發(fā)布后的exe文件打開控制臺(tái)閃退的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2019-06-06
  • Python爬蟲實(shí)現(xiàn)網(wǎng)頁(yè)信息抓取功能示例【URL與正則模塊】

    Python爬蟲實(shí)現(xiàn)網(wǎng)頁(yè)信息抓取功能示例【URL與正則模塊】

    這篇文章主要介紹了Python爬蟲實(shí)現(xiàn)網(wǎng)頁(yè)信息抓取功能,涉及Python使用URL與正則模塊針對(duì)網(wǎng)頁(yè)信息的讀取與匹配相關(guān)操作技巧,需要的朋友可以參考下
    2017-05-05
  • TENSORFLOW變量作用域(VARIABLE SCOPE)

    TENSORFLOW變量作用域(VARIABLE SCOPE)

    這篇文章主要介紹了TENSORFLOW變量作用域(VARIABLE SCOPE),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • Windows環(huán)境下Python3.6.8 importError: DLLload failed:找不到指定的模塊

    Windows環(huán)境下Python3.6.8 importError: DLLload failed:找不到指定的模塊

    這篇文章主要介紹了Windows環(huán)境下Python3.6.8 importError: DLLload failed:找不到指定的模塊,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評(píng)論