Python 高階 模組 包

2021-09-23 01:29:05 字數 4615 閱讀 8742

命名空間和變數作用域的比較

變數名的查詢覆蓋

匯入模組

模組匯入的特性

模組內建函式

package 包

預設的模組搜尋路徑在 python 解析器編譯安裝時被指定, 我們可以通過 sys 模組來檢視和修改它:

in [4]: sys.path

out[4]:

['',

'/usr/bin',

'/usr/lib/python2.7',

'/usr/lib/python2.7/plat-x86_64-linux-gnu',

'/usr/lib/python2.7/lib-tk',

'/usr/lib/python2.7/lib-old',

'/usr/lib/python2.7/lib-dynload',

'/usr/local/lib/python2.7/dist-packages',

'/opt/stack/keystone',

'/opt/stack/glance',

'/opt/stack/cinder',

'/opt/stack/nova',

'/opt/stack/horizon',

'/opt/stack/tempest',

'/opt/stack/oslo.vmware',

'/usr/lib/python2.7/dist-packages',

'/usr/lib/python2.7/dist-packages/ipython/extensions']

存在於搜尋路徑列表的路徑下的模組就可以直接被 import 了.

我們還能夠通過 sys.models 可以找到當前匯入了那些模組和它來自薩滿路徑和地方.

note: 這個路徑每個人都不盡相同, 在安裝 openstack 專案時, 每乙個專案的根目錄都會加入到該目錄列表中

命名空間: 是變數名(識別符號)到實際物件的對映, 是乙個字典. python 的命名空間型別有 內建命名空間/全域性命名空間/巢狀命名空間/區域性命名空間.

python 解析器啟動時, 首先會載入 內建命名空間 , 該空間的變數名對映被包含在__builtin__模組中, 我們可以通過__builtin__.__dict__來檢視其包含的變數字典, 主要包含了error/內建函式等型別.

注意:__builtin__模組和__builtins__模組的名稱非常相似, 在標準的 python 環境中__builtins__含有__builtin__內的所有變數名對映, 卻別在於__builtins__是可以被修改的, 用於建立乙個 「沙盒」 環境, 但少有人用, 所以兩者並不相等.

作用域: 變數名有效的區域定義. 指定了乙個變數名在乙個指定的區域內有效.

兩者的區別: 作用域和命名空間非常相似, 乙個作用域的建立伴隨著新的命名空間的生成, 其一般是具有對應的關係. 所以往往命名空間中含有的變數名在對應的作用域中都是有效的. 但本質的區別是: 命名空間是純粹意義上的變數名和物件的對映關係, 而作用域還指出了在**中的那個物理位置(模組內/類內/函式類)可以訪問到命名空間的變數名, 從而得到其對映的物件.

無限制的命名空間: python 的乙個特性在於我們可以動態的為乙個函式物件新增變數, 這種變數也稱之為例項屬性. 所以 python 的命名空間是無限制的.

in [9]: def func():

...: print "this is a func"

...:

in [10]: func.__dict__

out[10]: {}

in [13]: func.name = 'jmilkfan'

in [14]: func.__dict__

out[14]:

當我們 call 乙個變數名時, python 解析器的查詢順序如下:

1. 先從區域性命名空間開始找, 如果找到了, 則引用變數名對映的物件. 若沒有找到, 則進行下一步

2. 到巢狀命名空間找, 如果沒有找到, 則進行下一步

3. 到全域性命名空間找, 如果沒有找到, 則進行下一步

4. 到內建命名空間找, 如果沒有找到, 則進入下一步

從這個變數名查詢演算法可以看出, 當我們在**物理位置定義了乙個變數時, 這個變數就會新增到命名空間中. 而且這個命名空間為變數名的查詢提供了清單. 更重要的一點是這個查詢演算法還有效的覆蓋了外層作用域的同名變數. 區域性作用域 覆蓋 巢狀作用域 覆蓋 全域性作用域 覆蓋 內建作用域.

import module1[, module2, ..., modulen]
python 允許一行匯入多個模組, 但那這並不符合 pep8 的程式設計標準, 所以建議使用多行匯入的方式.

匯入模組型別的順序(中間已單空行隔開):

1. python 標準庫模組

2. python 第三方模組

3. python 自定義模組

note: 模組的匯入遵循作用域的原則, 在頂格匯入的模組, 那麼模組的作用域是全域性的. 在函式或類內匯入的模組, 其作用域就是區域性或巢狀作用域.

如果你希望從乙個模組中匯入指定屬性, 或希望從乙個 package 中匯入乙個模組, 都可以使用form-import語句.

from-import 語句也支援一行匯入多個模組或屬性, eg.

from package import (module1, module2, module3, ..., modulen)
from-import 語句的好處在於: 針對性的匯入可以提高效率和節省空間

note: 我們一般建議匯入到模組即可, 非特殊情況不要匯入包或模組內的屬性

也稱之為別名, 模組之間也會經常出現同名的情況, 如果出現同乙個模組中匯入了兩個或多個同名模組的情況, 那麼應該為每個相同的模組取乙個別名來有效區分. 除此之外, 如果模組的全稱過長, 我們也可以為其取乙個短小的別名. eg.

import module1 as module_one

from package import module1 as module_two

import tkinter as tk

python 解析器在標準模式下啟動會自動的匯入乙個模組, 例如__bulitin__. 我們可以通過sys.modules來檢視已經被匯入到當前環境下模組字典, key 為模組名, value 為模組路徑.

import sys

sys.modules

.keys()

格式:

__import__(module_name[, globals[, locals[, fromlist]]])

# globals 是全域性命名空間的字典 ⇒ globals()

# locals 是區域性命名空間的字典 ⇒ locals()

# fromlist 是 from-import 語句匯入的變數名的列表 ⇒

當我們執行 import 語句的時候, 實際上是呼叫了__import__()內建函式, eg:

import sys 

# 等效於

sys = __import__('sys')

模組是**的組織形式, 包是模組的組織形式. 如果在乙個目錄中建立了__init__.py檔案, 那麼 python 解析器會將該目錄標識為乙個包 package.

note: 我們一般在使用 import 語句的時候, 建議匯入到模組級別, 不要匯入模組屬性, 也不要匯入包.

__init__.py檔案是包的標識檔案, 作為包的初始化模組, from-import 包下的模組會子包時, 需要用到該初始化模組, 所以現在如果乙個包中沒有該模組時, 會觸發importwarning資訊.

如果我們不需要使用初始化模組__init__.py時. 該模組的內容為空, 如果我們需要使用該模組時,import packagename == import packagename._init_.

而且需要注意的是:如果我們執行from package import *時, 會將該包下的所有模組和屬性匯入, 實際上這種做法是不科學的. 所以在包的初始化模組檔案中有乙個特殊屬性__all__,__all__屬性由乙個模組名字組成的列表組成, 這個列表中包含了所有在執行全匯入時應該被匯入的模組和屬性的名字.

高階python 包 和模組

包 簡單而言,包就是資料夾,用來存放檔案。模組 檔案或檔案的集合 python中 和is 的區別 主要 判斷的是兩個變數的值 is 用來判斷兩個變數的記憶體位址 引用傳遞僅僅是資料的引用 is 主要 呼叫的是的是 ip位址 深淺拷貝 1 匯入 copy import copy b copy。copy...

Python高階二 模組和包

同名模組 放入不同包中 import package1.file1 如何區分包和普通目錄 包下面有乙個 init py檔案 匯入模組 from package import file1 或者 import package.file from os import path print path.isd...

Python 高階2 模組與包

在檔案系統上組織 並確保每個目錄都定義了乙個 init py檔案 from import png將檔案合併成乙個單一的邏輯命名空間,後續就可以直接使用from graphics.formats import jpg,png from module import 會匯入檔案中所有不以下劃線開頭的內容,...