鐵樂學python_day28_模塊學習3

来源:https://www.cnblogs.com/tielemao/archive/2018/04/27/8964984.html
-Advertisement-
Play Games

什麼是模塊? 常見的場景:一個模塊就是一個包含了python定義和聲明的文件,文件名就是模塊名字加上.py的尾碼。 但其實import載入的模塊分為四個通用類別:    1 使用python編寫的代碼(.py文件)   2 已被編譯為共用庫或DLL的C或C++擴展   3 包好一組模塊的包   4 ... ...


大部份內容摘自授課老師的博客http://www.cnblogs.com/Eva-J/

OS模塊複習一二

>>> import os
>>> os.getcwd()  # 獲取當前所在目錄
'D:\\PortableSoft\\Python35'

>>> os.chdir('d:\\PortableSoft')  # 改變工作目錄,相當於cd命令
>>> os.getcwd()
'd:\\PortableSoft'

>>> os.curdir  # 獲取'.'字元串,相當於當前目錄
'.'
>>> os.pardir # 獲取'..'字元串,相當於上級(父目錄)目錄
'..'

>>> import os
>>> os.sep
'\\'
>>> os.linesep
'\r\n'
>>> os.pathsep
';'
>>> os.name
'nt'

os.system('dir')  # 直接就運行完命令了
print(os.popen('dir').read()) # 執行的輸出有返回值

 驅動器 E 中的捲是 VM
 捲的序列號是 4AE6-716D

 E:\Python\day28 的目錄

2018-04-25  17:21    <DIR>          .
2018-04-25  17:21    <DIR>          ..
2018-04-25  17:11                 4 new.txt
2018-04-25  17:21               323 OS模塊.py
               2 個文件            327 位元組
               2 個目錄 62,048,944,128 可用位元組

print(os.path)  # <module 'ntpath' from 'D:\\PortableSoft\\Python35\\lib\\ntpath.py'>
print(os.path.abspath(os.curdir))           # E:\Python\day28
print(os.path.split('E:\Python\day28'))   # ('E:\\Python', 'day28')
print(os.path.abspath(os.pardir))           # E:\Python
print(os.path.dirname('E:\Python\day28'))    # E:\Python
print(os.path.basename('E:\Python\day28'))  # day28
print(os.path.exists('E:\Python\day28'))  # True
print(os.path.exists('E:\Python\day29'))  # False
print(os.path.join('E:\Python', 'day28', 'OS模塊.py'))  # E:\Python\day28\OS模塊.py
print(os.path.getmtime('E:\Python\day28'))  # 1524649925.9140468 獲取到的是時間戳,所以還需要轉格式化字元串的時間
res = os.path.getmtime('E:\Python\day28')
print(time.strftime('%Y-%m-%d %X', time.gmtime(res)))  # 2018-04-25 09:57:58
補充:os.walk
os.walk輸入一個路徑名稱,以yield的方式(其實是一個生成器)返回一個三元組 dirpath, dirnames, filenames

例子:列印輸出目錄樹

import os
def travelTree(currentPath, count):
    '''
    以樹狀的方式遞歸顯示文件目錄
    :param currentPath: 要顯示的目錄路徑
    :param count: 要顯示的目錄層級
    :return: 沒有返回值,直接遞歸列印輸出格式化好的文件樹
    '''
    # 判斷傳入進來的路徑存不存在,不存在直接返回None
    if not os.path.exists(currentPath):
        return
    # 判斷傳入進來的路徑是否為文件
    if os.path.isfile(currentPath):
        # 是文件則返迴文件名
        fileName = os.path.basename(currentPath)
        # 列印輸出定義好的 層級製表符 拼接 樹狀符號 再加文件名
        print('\t' * count + '├── ' + fileName)
    # 當路徑是一個目錄時
    elif os.path.isdir(currentPath):
        # 列印輸出定義好的 層級製表符 拼接 樹狀符號 再加目錄路徑
        print('\t' * count + '├── ' + currentPath)
        # 將目錄以列表方式放入一個列表中
        pathList = os.listdir(currentPath)
        # for迴圈並且遞歸重覆前面操作
        for eachPath in pathList:
            travelTree(currentPath + '/' + eachPath, count + 1)

什麼是模塊?

常見的場景:一個模塊就是一個包含了python定義和聲明的文件,文件名就是模塊名字加上.py的尾碼。
但其實import載入的模塊分為四個通用類別: 
  1 使用python編寫的代碼(.py文件)
  2 已被編譯為共用庫或DLL的C或C++擴展
  3 包好一組模塊的包
  4 使用C編寫並鏈接到python解釋器的內置模塊

為何要使用模塊?

如果你退出python解釋器然後重新進入,那麼你之前定義的函數或者變數都將丟失,因此我們通常將程式寫到文件中以便永久保存下來,需要時就通過python test.py方式去執行,此時test.py被稱為腳本script。

隨著程式的發展,功能越來越多,為了方便管理,我們通常將程式分成一個個的文件,這樣做程式的結構更清晰,方便管理。這時我們不僅僅可以把這些文件當做腳本去執行,還可以把他們當做模塊來導入到其他的模塊中,實現了功能的重覆利用。

模塊可以包含可執行的語句和函數的定義,這些語句的目的是初始化模塊,它們只在模塊名第一次遇到導入import語句時才執行(import語句是可以在程式中的任意位置使用的,且針對同一個模塊很import多次,為了防止你重覆導入,python的優化手段是:第一次導入後就將模塊名載入到記憶體了,後續的import語句僅是對已經載入大記憶體中的模塊對象增加了一次引用,不會重新執行模塊內的語句)

我們可以從sys.modules中找到當前已經載入的模塊,sys.modules是一個字典,內部包含模塊名與模塊對象的映射,該字典決定了導入模塊時是否需要重新導入。

每個模塊都是一個獨立的名稱空間,定義在這個模塊中的函數,把這個模塊的名稱空間當做全局名稱空間,這樣我們在編寫自己的模塊時,就不用擔心我們定義在自己模塊中全局變數會在被導入時,與使用者的全局變數衝突。

總結:首次導入模塊時會做三件事:

1.為源文件(導入的module模塊)創建新的名稱空間,在當中定義的函數和方法若是使用到了global時訪問的就是這個名稱空間。
2.在新創建的命名空間中執行模塊中包含的代碼;

導入模塊時到底執行了什麼?
In fact function definitions are also ‘statements’ that are ‘executed’; the execution of a module-level function definition enters the function name in the module’s global symbol table.
事實上函數定義也是“被執行”的語句,模塊級別函數定義的執行將函數名放入模塊全局名稱空間表,用globals()可以查看。

3.創建名字用導入的module名來引用該命名空間
這個名字和變數名沒什麼區別,都是‘第一類的’,且使用導入的module名字的方式可以訪問該py文件中定義的名字,被導入的py內的.名字與文件中的名字來自兩個完全不同的地方。

為模塊起別名:

為模塊名起別名,相當於json=seq;pickle=seq

示範用法一:
有兩中sql模塊mysql和oracle,根據用戶的輸入,選擇不同的sql功能

#mysql.py
def sqlparse():
    print('from mysql sqlparse')
#oracle.py
def sqlparse():
    print('from oracle sqlparse')

#test.py
db_type=input('>>: ')
if db_type == 'mysql':
    import mysql as db
elif db_type == 'oracle':
    import oracle as db

db.sqlparse() 

示範用法二: 
為已經導入的模塊起別名的方式對編寫可擴展的代碼很有用,
假設有兩個模塊xmlreader.py和csvreader.py,
它們都定義了函數read_data(filename):用來從文件中讀取一些數據,但採用不同的輸入格式。
可以編寫代碼來選擇性地挑選讀取模塊,例如

if file_format == 'xml':
     import xmlreader as reader
elif file_format == 'csv':
     import csvreader as reader
data=reader.read_date(filename)

from ... import...
對比import my_module,會將源文件的名稱空間'my_module'帶到當前名稱空間中,使用時必須是my_module.名字的方式。
而from 語句相當於import,也會創建新的名稱空間,
但是from是將my_module中的名字直接導入到當前的名稱空間中,
在當前名稱空間中,直接使用名字就可以了。

例:from math import pi

這樣在當前位置直接使用pi就好了,執行時,仍然回math文件全局名稱空間尋找名字pi。
需要特別強調的一點是:python中的變數賦值不是一種存儲操作,而只是一種綁定關係。
from同樣支持as,起別名。

另外
from my_module import * 把my_module中所有不是以下劃線(_)開頭的名字都導入到當前位置,
大部分情況下我們的python程式不應該使用這種導入方式,
因為*你不知道你導入什麼名字,很有可能會覆蓋掉你之前已經定義的名字。
而且可讀性極其的差,在互動式環境中導入時沒有問題。

在my_module.py中新增一行
__all__=['money','read1'] 
#這樣在另外一個文件中用from my_module import * 導入的是列表中規定的兩個名字。

模塊的載入與修改

考慮到性能的原因,每個模塊只被導入一次,放入字典sys.modules中,
如果你改變了模塊的內容,你必須重啟程式,python不支持重新載入或卸載之前導入的模塊,
有的同學可能會想到直接從sys.modules中刪除一個模塊不就可以卸載了嗎,
註意了,你刪了sys.modules中的模塊對象仍然可能被其他程式的組件所引用,因而不會被清除。
特別的對於我們引用了這個模塊中的一個類,用這個類產生了很多對象,因而這些對象都有關於這個模塊的引用。

如果只是你想交互測試的一個模塊,使用 importlib.reload(), 
e.g. import importlib; importlib.reload(modulename),這隻能用於測試環境。

把模塊當做腳本執行 
我們可以通過模塊的全局變數__name__來查看模塊名:

當做腳本運行:
__name__ 等於'__main__'

當做模塊導入:
__name__= 模塊名

作用:用來控制.py文件在不同的應用場景下執行不同的邏輯
if __name__ == '__main__':

模塊搜索路徑
python解釋器在啟動時會自動載入一些模塊,可以使用sys.modules查看。

在第一次導入某個模塊時(比如my_module),
會先檢查該模塊是否已經被載入到記憶體中(當前執行文件的名稱空間對應的記憶體),如果有則直接引用;
如果沒有,解釋器則會查找同名的內建模塊,如果還沒有找到就從sys.path給出的目錄列表中依次尋找my_module.py文件。

所以總結模塊的查找順序是:記憶體中已經載入的模塊->內置模塊->sys.path路徑中包含的模塊.

sys.path的初始化的值來自於:
The directory containing the input script (or the current directory when no file is specified).
PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).
The installation-dependent default.

需要特別註意的是:我們自定義的模塊名不應該與系統內置模塊重名。雖然每次都說,但是仍然會有人不停的犯錯。 
在初始化後,python程式可以修改sys.path,路徑放到前面的優先於標準庫被載入。
1 >>> import sys
2 >>> sys.path.append('/a/b/c/d')
3 >>> sys.path.insert(0,'/x/y/z') #排在前的目錄,優先被搜索

註意:搜索時按照sys.path中從左到右的順序查找,位於前的優先被查找,
sys.path中還可能包含.zip歸檔文件和.egg文件,python會把.zip歸檔文件當成一個目錄去處理。

至於.egg文件是由setuptools創建的包,這是按照第三方python庫和擴展時使用的一種常見格式,
.egg文件實際上只是添加了額外元數據(如版本號,依賴項等)的.zip文件。
需要強調的一點是:只能從.zip文件中導入.py,.pyc等文件。
使用C編寫的共用庫和擴展塊無法直接從.zip文件中載入(此時setuptools等打包系統有時能提供一種規避方法),
且從.zip中載入文件不會創建.pyc或者.pyo文件,因此一定要事先創建他們,來避免載入模塊是性能下降。

官網鏈接:https://docs.python.org/3/tutorial/modules.html#the-module-search-path
搜索路徑:
當一個命名為my_module的模塊被導入時,解釋器首先會從內建模塊中尋找該名字,找不到,則去sys.path中找該名字。

sys.path從以下位置初始化:

1)執行文件所在的當前目錄
2)PTYHONPATH(包含一系列目錄名,與shell變數PATH語法一樣)
3)依賴安裝時預設指定的

註意:在支持軟連接的文件系統中,執行腳本所在的目錄是在軟鏈接之後被計算的,
換句話說,包含軟鏈接的目錄不會被添加到模塊的搜索路徑中。

在初始化後,我們也可以在python程式中修改sys.path,執行文件所在的路徑預設是sys.path的第一個目錄,
在所有標準庫路徑的前面。這意味著,當前目錄是優先於標準庫目錄的,
需要強調的是:我們自定義的模塊名不要跟python標準庫的模塊名重覆。

end
2018-4-27


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、VO:value object值對象。通常用於業務層之間的數據傳遞,和PO一樣也是僅僅包含數據而已。但應是抽象出的業務對象,可以和表對應,也可以不,這根據業務的需要. 2、 String[]類型列印tosring時顯示為一塊記憶體空間,這時候根據鍵可以判斷值已經成功接收 3、 在對條件進行判斷的時 ...
  • 1、信號和槽 2、自定義信號槽 3、自定義信號槽需要註意的事項 4、信號槽的更多用法 5、案例代碼........ ...
  • 面向對象學習目錄 1 面向對象介紹 2 類、實例、屬性、方法詳解 3 面向過程與面向對象進一步比較 4 類與對象 5 屬性查找與綁定方法 6 小結 7 繼承與派生 8 組合 9 抽象類 10 多態 11 封裝 12 綁定方法與非綁定方法 13 內置方法(上) 14 內置方法(中)之描述符 15 內置 ...
  • 1 class A(object): 2 x = 1 3 4 class B(A): 5 pass 6 7 class C(A): 8 pass 9 10 # 通過父類修改類屬性,子類繼承的類屬性也改變 11 A.x = 3 12 print(A.x, B.x, C.x) 13 # 通過子類修改繼承... ...
  • Python,Python,web,爬蟲,開發,機器學習,人工智慧,數據分析,資料庫,編程,基礎入門 先用電影評論來做情感分析,要看到最後哦 ...
  • 第一種:原生方式 註意點:button標簽的style為submit 第二種:Jquery校驗方式 註意點:button標簽的style為button 流程:點擊提交,首先觸發submitForm()方法,執行校驗及id選擇器,最後提交form表單。 ...
  • 《前言》 <cstring>中有一函式 char * strtok ( char * str, const char * delimiters ); 常用來處理C風格陣列的分割問題。其中str是待分割字元串,delimiters 是分割符字元串,舉列說現在有 str[] = "ab,cd,efg,. ...
  • 當echo一個對象的時候,會報錯誤 Object of class Person could not be converted to string 我們可以通過魔術方法__tostring() 把對象轉成字元串 繼續改造php靜態變數與方法與phar的使用 ghostconfig.php ghost ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...