最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python中import學(xué)習(xí)備忘筆記

 更新時(shí)間:2017年01月24日 10:13:29   作者:littlewhite  
python中的import語(yǔ)句是用來(lái)導(dǎo)入模塊的,在python模塊庫(kù)中有著大量的模塊可供使用,要想使用這些文件需要用import語(yǔ)句把指定模塊導(dǎo)入到當(dāng)前程序中。下面這篇文章主要給大家介紹了python中import學(xué)習(xí)的相關(guān)資料,需要的朋友可以參考借鑒。

前言

在python的模塊有兩種組織方式,一種是單純的python文件,文件名就是模塊名,一種是包,包是一個(gè)包含了若干python文件的目錄,目錄下必須有一個(gè)文件__init__.py,這樣目錄名字就是模塊名,包里的python文件也可以通過(guò)包名.文件名的方式import

import語(yǔ)法

import語(yǔ)法有兩種

1、直接import模塊

 import Module
 import Module as xx

2、從模塊import對(duì)象(下級(jí)模塊,類(lèi),函數(shù),變量等)

 from Module import Name
 from Module immport Name as yy

as語(yǔ)法是用來(lái)設(shè)置對(duì)象(這里用對(duì)象泛指模塊,類(lèi),函數(shù)等等)別名,import將對(duì)象名字引入了當(dāng)前文件的名字空間

假設(shè)有如下目錄結(jié)構(gòu)

├── A.py
└── pkg
 ├── B.py
 └── __init__.py

在當(dāng)前目錄下,以下語(yǔ)句都是有效的

import A 
import pkg
import pkg.B
from pkg import B

為了簡(jiǎn)化討論,下面將不會(huì)對(duì)as語(yǔ)法進(jìn)行舉例

import步驟

python所有加載的模塊信息都存放在sys.modules結(jié)構(gòu)中,當(dāng)import一個(gè)模塊時(shí),會(huì)按如下步驟來(lái)進(jìn)行

  1. 如果是import A,檢查sys.modules中是否已經(jīng)有A,如果有則不加載,如果沒(méi)有則為A創(chuàng)建module對(duì)象,并加載A
  2. 如果是from A import B,先為A創(chuàng)建module對(duì)象,再解析A,從中尋找B并填充到A的__dict__

嵌套import

在import模塊時(shí)我們可能會(huì)擔(dān)心一個(gè)模塊會(huì)不會(huì)被import多次,假設(shè)有A,B,C三個(gè)模塊,A需要import B和C,B又要import C,這樣A會(huì)執(zhí)行到兩次import C,一次是自己本身import,一次是在import B時(shí)執(zhí)行的import,但根據(jù)上面講到的import步驟,在第二次import時(shí)發(fā)現(xiàn)模塊已經(jīng)被加載,所以不會(huì)重復(fù)import

但如下情況卻會(huì)報(bào)錯(cuò)

#filename: A.py
from B import BB
class AA:pass

#filename: B.py
from A import AA
class BB:pass

這時(shí)不管是執(zhí)行A.py還是B.py都會(huì)拋出ImportError的異常,假設(shè)我們執(zhí)行的是A.py,究其原因如下

  1. 文件A.py執(zhí)行from B import BB,會(huì)先掃描B.py,同時(shí)在A的名字空間中為B創(chuàng)建module對(duì)象,試圖從B中查找BB
  2. 掃描B.py第一行執(zhí)行from A import AA,此時(shí)又會(huì)去掃描A.py
  3. 掃描A.py第一行執(zhí)行from B import BB,由于步驟1已經(jīng)為B創(chuàng)建module對(duì)象,所以會(huì)直接從B的module對(duì)象的__dict__中獲取BB,此時(shí)顯然BB是獲取不到的,于是拋出異常

解決這種情況有兩種辦法,

  1. 將from B import BB改為import B,或?qū)rom A import AA改為import A
  2. 將A.py或B.py中的兩行代碼交換位置

總之,import需要注意的是,盡量在需要用到時(shí)再import

包的import

當(dāng)一個(gè)目錄下有__init__.py文件時(shí),該目錄就是一個(gè)python的包

import包和import單個(gè)文件是一樣的,我們可以這樣類(lèi)比:

  • import單個(gè)文件時(shí),文件里的類(lèi),函數(shù),變量都可以作為import的對(duì)象
  • import包時(shí),包里的子包,文件,以及__init__.py里的類(lèi),函數(shù),變量都可以作為import的對(duì)象

假設(shè)有如下目錄結(jié)構(gòu)

pkg
├── __init__.py
└── file.py

其中__init__.py內(nèi)容如下

argument = 0
class A:pass

在和pkg同級(jí)目錄下執(zhí)行如下語(yǔ)句都是OK的

>>> import pkg
>>> import pkg.file
>>> from pkg import file
>>> from pkg import A
>>> from pkg import argument

但如下語(yǔ)句是錯(cuò)誤的

>>> import pkg.A
>>> import pkg.argument

報(bào)錯(cuò)ImportError: No module named xxx,因?yàn)楫?dāng)我們執(zhí)行import A.B,A和B都必須是模塊(文件或包)

相對(duì)導(dǎo)入和絕對(duì)導(dǎo)入

絕對(duì)導(dǎo)入的格式為import A.Bfrom A import B,相對(duì)導(dǎo)入格式為from . import Bfrom ..A import B,.代表當(dāng)前模塊,..代表上層模塊,...代表上上層模塊,依次類(lèi)推。當(dāng)我們有多個(gè)包時(shí),就可能有需求從一個(gè)包import另一個(gè)包的內(nèi)容,這就會(huì)產(chǎn)生絕對(duì)導(dǎo)入,而這也往往是最容易發(fā)生錯(cuò)誤的時(shí)候,還是以具體例子來(lái)說(shuō)明

目錄結(jié)構(gòu)如下

app
├── __inti__.py
├── mod1
│ ├── file1.py
│ └── __init__.py
├── mod2
│ ├── file2.py
│ └── __init__.py
└── start.py

其中app/start.py內(nèi)容為import mod1.file1

app/mod1/file1.py內(nèi)容為from ..mod2 import file2

為了便于分析,我們?cè)谒衟y文件(包括__init__.py)第一行加入print __file__, __name__

現(xiàn)在app/mod1/file1.py里用到了相對(duì)導(dǎo)入,我們?cè)赼pp/mod1下執(zhí)行python file1.py或者在app下執(zhí)行python mod1/file1.py都會(huì)報(bào)錯(cuò)ValueError: Attempted relative import in non-package

在app下執(zhí)行python -m mod1.file1python start.py都會(huì)報(bào)錯(cuò)ValueError: Attempted relative import beyond toplevel package

具體原因后面再說(shuō),我們先來(lái)看一下導(dǎo)入模塊時(shí)的一些規(guī)則

在沒(méi)有明確指定包結(jié)構(gòu)的情況下,python是根據(jù)__name__來(lái)決定一個(gè)模塊在包中的結(jié)構(gòu)的,如果是__main__則它本身是頂層模塊,沒(méi)有包結(jié)構(gòu),如果是A.B.C結(jié)構(gòu),那么頂層模塊是A。

基本上遵循這樣的原則

  1. 如果是絕對(duì)導(dǎo)入,一個(gè)模塊只能導(dǎo)入自身的子模塊或和它的頂層模塊同級(jí)別的模塊及其子模塊
  2. 如果是相對(duì)導(dǎo)入,一個(gè)模塊必須有包結(jié)構(gòu)且只能導(dǎo)入它的頂層模塊內(nèi)部的模塊

有目錄結(jié)構(gòu)如下

A
├── B1
│ ├── C1
│ │ └── file.py
│ └── C2
└── B2

其中A,B1,B2,C1,C2都為包,這里為了展示簡(jiǎn)單沒(méi)有列出__init__.py文件,當(dāng)file.py的包結(jié)構(gòu)為A.B1.C1.file(注意,是根據(jù)__name__來(lái)的,而不是磁盤(pán)的目錄結(jié)構(gòu),在不同目錄下執(zhí)行file.py時(shí)對(duì)應(yīng)的包目錄結(jié)構(gòu)都是不一樣的)時(shí),在file.py中可采用如下的絕對(duì)的導(dǎo)入

import A.B1.C2
import A.B2

和如下的相對(duì)導(dǎo)入

from .. import C2
from ... import B2

什么情況下會(huì)讓file.py的包結(jié)構(gòu)為A.B1.C1.file呢,有如下兩種

  1. 在A的上層目錄執(zhí)行python -m A.B1.C1.file, 此時(shí)明確指定了包結(jié)構(gòu)
  2. 在A的上層目錄建立文件start.py,在start.py里有import A.B1.C1.file,然后執(zhí)行python start.py,此時(shí)包結(jié)構(gòu)是根據(jù)file.py__name__變量來(lái)的

再看前面出錯(cuò)的兩種情況,第一種執(zhí)行python file1.pypython mod1/file1.py,此時(shí)file.py__name____main__ ,也就是說(shuō)它本身就是頂層模塊,并沒(méi)有包結(jié)構(gòu),所以會(huì)報(bào)錯(cuò)

第二種情況,在執(zhí)行python -m mod1.file1python start.py時(shí),前者明確告訴解釋器mod1是頂層模塊,后者需要導(dǎo)入file1,而file1.py__name__mod1.file1,頂層模塊為也mod1,所以在file1.py中執(zhí)行from ..mod2 import file2時(shí)會(huì)報(bào)錯(cuò) ,因?yàn)閙od2并不在頂層模塊mod1內(nèi)部。通過(guò)錯(cuò)誤堆??梢钥闯觯⒉皇窃?code>start.py中絕對(duì)導(dǎo)入時(shí)報(bào)錯(cuò),而是在file1.py中相對(duì)導(dǎo)入報(bào)的錯(cuò)

那么如何才能偶正確執(zhí)行呢,有兩種方法,一種是在app上層目錄執(zhí)行python -m app.mod1.file1,另一種是改變目錄結(jié)構(gòu),將所有包放在一個(gè)大包中,如下

app
├── pkg
│ ├── __init__.py
│ ├── mod1
│ │ ├── __init__.py
│ │ └── file1.py
│ └── mod2
│ ├── __init__.py
│ └── file2.py
└── start.py

start.py內(nèi)容改成import pkg.mod1.file1,然后在app下執(zhí)行python start.py

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家學(xué)習(xí)或者使用python能帶來(lái)一定的幫助,如有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • python獲取array中指定元素的示例

    python獲取array中指定元素的示例

    今天小編就為大家分享一篇python獲取array中指定元素的示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-11-11
  • Python學(xué)習(xí)之pip包管理工具的使用

    Python學(xué)習(xí)之pip包管理工具的使用

    學(xué)習(xí)?Python?的過(guò)程中,經(jīng)常會(huì)使用?pip?命令去安裝第三方模塊。pip?是?Python?默認(rèn)集成的包管理工具,而其本質(zhì)就是?Python?標(biāo)準(zhǔn)庫(kù)中的一個(gè)包,只是比較特殊一些。本文就來(lái)為你你全面揭示一下?pip?包管理工具的使用
    2022-08-08
  • Django時(shí)區(qū)詳解

    Django時(shí)區(qū)詳解

    這篇文章主要介紹了Django時(shí)區(qū)詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Python?多處理模塊如何使用示例詳解

    Python?多處理模塊如何使用示例詳解

    這篇文章主要為大家介紹了Python?多處理模塊如何使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-09-09
  • python numpy中setdiff1d的用法說(shuō)明

    python numpy中setdiff1d的用法說(shuō)明

    這篇文章主要介紹了python numpy中setdiff1d的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-04-04
  • 最新評(píng)論

    通渭县| 黑龙江省| 玉树县| 赤壁市| 北安市| 临泉县| 涟水县| 建宁县| 烟台市| 浦北县| 闸北区| 泗洪县| 加查县| 越西县| 大英县| 霍林郭勒市| 祁阳县| 新郑市| 嵊泗县| 曲靖市| 苍山县| 遵义市| 定州市| 香格里拉县| 咸宁市| 本溪| 象山县| 改则县| 安徽省| 龙山县| 永安市| 枝江市| 大埔区| 五峰| 信宜市| 英德市| 乌兰县| 苗栗县| 若羌县| 南康市| 榆林市|