Python form...import...和import的區別(自己理解的)


Python有兩種導入包和模塊的方式,區別如下

form...import... import
相對導包 導入不同包子模塊
可以導入模塊所需變量/函數/類  
init文件的__all__特殊變量(模塊列表)  
   
   
   

 

import 語句
import_stmt     ::=  "import" module ["as" identifier] ("," module ["as" identifier])*
                     | "from" relative_module "import" identifier ["as" identifier]
                     ("," identifier ["as" identifier])*
                     | "from" relative_module "import" "(" identifier ["as" identifier]
                     ("," identifier ["as" identifier])* [","] ")"
                     | "from" module "import" "*"
module          ::=  (identifier ".")* identifier
relative_module ::=  "."* module | "."+
基本的 import 語句(不帶 from 子句)會分兩步執行:

查找一個模塊,如果有必要還會加載並初始化模塊。

在局部命名空間中為 import 語句發生位置所處的作用域定義一個或多個名稱。

當語句包含多個子句(由逗號分隔)時這兩個步驟將對每個子句分別執行,如同這些子句被分成獨立的 import 語句一樣。

第一個步驟即查找和加載模塊的詳情 導入系統 一節中有更詳細的描述,其中也描述了可被導入的多種類型的包和模塊,以及可用於定制導入系統的所有鈎子對象。 請注意這一步如果失敗,則可能說明模塊無法找到,或者 是在初始化模塊,包括執行模塊代碼期間發生了錯誤。

如果成功獲取到請求的模塊,則可以通過以下三種方式一之在局部命名空間中使用它:

如果模塊名稱之后帶有 as,則跟在 as 之后的名稱將直接綁定到所導入的模塊。

如果沒有指定其他名稱,且被導入的模塊為最高層級模塊,則模塊的名稱將被綁定到局部命名空間作為對所導入模塊的引用。

如果被導入的模塊 不是 最高層級模塊,則包含該模塊的最高層級包的名稱將被綁定到局部命名空間作為對該最高層級包的引用。 所導入的模塊必須使用其完整限定名稱來訪問而不能直接訪問。

from 形式使用的過程略微繁復一些:

查找 from 子句中指定的模塊,如有必要還會加載並初始化模塊;

對於 import 子句中指定的每個標識符:

檢查被導入模塊是否有該名稱的屬性

如果沒有,嘗試導入具有該名稱的子模塊,然后再次檢查被導入模塊是否有該屬性

如果未找到該屬性,則引發 ImportError。

否則的話,將對該值的引用存入局部命名空間,如果有 as 子句則使用其指定的名稱,否則使用該屬性的名稱

例如:

import foo                 # foo imported and bound locally
import foo.bar.baz         # foo.bar.baz imported, foo bound locally
import foo.bar.baz as fbb  # foo.bar.baz imported and bound as fbb
from foo.bar import baz    # foo.bar.baz imported and bound as baz
from foo import attr       # foo imported and foo.attr bound as attr
如果標識符列表改為一個星號 ('*'),則在模塊中定義的全部公有名稱都將按 import 語句所在的作用域被綁定到局部命名空間。

一個模塊所定義的 公有名稱 是由在模塊的命名空間中檢測一個名為 __all__ 的變量來確定的;如果有定義,它必須是一個字符串列表,其中的項為該模塊所定義或導入的名稱。 在 __all__ 中所給出的名稱都會被視為公有並且應當存在。 如果 __all__ 沒有被定義,則公有名稱的集合將包含在模塊的命名空間中找到的所有不以下划線字符 ('_') 打頭的名稱。 __all__ 應當包括整個公有 API。 它的目標是避免意外地導出不屬於 API 的一部分的項(例如在模塊內部被導入和使用的庫模塊)。

通配符形式的導入 --- from module import * --- 僅在模塊層級上被允許。 嘗試在類或函數定義中使用它將引發 SyntaxError。

當指定要導入哪個模塊時,你不必指定模塊的絕對名稱。 當一個模塊或包被包含在另一個包之中時,可以在同一個最高層級包中進行相對導入,而不必提及包名稱。 通過在 from 之后指定的模塊或包中使用前綴點號,你可以在不指定確切名稱的情況下指明在當前包層級結構中要上溯多少級。 一個前綴點號表示是執行導入的模塊所在的當前包,兩個點號表示上溯一個包層級。 三個點號表示上溯兩級,依此類推。 因此如果你執行 from . import mod 時所處位置為 pkg 包內的一個模塊,則最終你將導入 pkg.mod。 如果你執行 from ..subpkg2 import mod 時所處位置為 pkg.subpkg1 則你將導入 pkg.subpkg2.mod。 有關相對導入的規范說明包含在 包相對導入 一節中。

importlib.import_module() 被提供用來為動態地確定要導入模塊的應用提供支持。

引發一個 審核事件 import 附帶參數 module, filename, sys.path, sys.meta_path, sys.path_hooks。

 

 

 

官方文檔看來看去還是沒有直接說兩個導包的區別,倒是說了使用方式的不同,導包時處理方法也不同,最后看完還是覺得莫名其妙。。。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM