黑馬python入門(4):python基礎(序列,異常,操作檔案,模組包,日誌除錯資訊)
python線上手冊 https://docs.python.org/zh-cn/3/
序列
str
- 宣告:test_str=”abcedf” 也可以保留字串裡面的格式來
test_str=””“
<html>
<title>\r\n測試標題</title>
<body>
<span>hello world</span>
</body>
</html>"
””“
- 長度: len(test_str)
- 元素增: join() 分隔符.join(字串1,字串2) 或者 字串1+ 字串2
- 元素減:del(test_str)
- 元素改:test_str = “bcdef”
- 元素查: find()來找 還不會報錯 in not也可以判斷是否存在 但是不如find方便
- 元素輸出: test_str[2]
- 元素切割 :test_str[1:5]
- 遍歷:for v in test_str:就可以
- 排序: 沒有 但是可以轉成list型別然後排序就好 再用join拼接成字串就好
tuple
- 本質:一個無法修改的數字索引陣列
- 宣告:test_tuple=(1, 2, 3, 4, 5) 小括號宣告 注意 宣告一個元素的元組 的格式有點變化 test_tuple=(1,)
- 長度: len(test_tuple)
- 元素增: 固定無法操作
- 元素減:固定無法操作
- 元素改:固定無法操作
- 元素查: in not in 來判斷是否內容是否在tuple中存在 但是無法確定位置 官方使用index()來確定位置下標但是報錯 還是用自己的index_plus()來解決吧
- 元素輸出: test_tuple[2] 這是中括號 而不是元組宣告的小括號
- 元素切割 :test_tuple[1:5]
- 遍歷:for v in aa_tuple:就可以
- 排序:固定無法操作
小知識:序列查詢函式index()和index_plus
index()是查詢序列元素並返回找到的元素下標的函式 但是美中不足是 找不到卻會報錯 導致整個程式碼的崩潰
不知道其他人是怎麼解決這個問題的 我用異常來控制報錯暫時解決這個問題
def index_plus(ob, __value): """ :param ob: 要查詢的序列 :param __value: 要找的內容 :return: int 找不到返回-1 找的到返回下標 function:index的升級版 解決了找不到報錯的問題 """ try: temp1 = ob.index(__value) except: temp1 = -1 else: pass finally: return temp1
import zjl aa_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9) print(zjl.index_plus(aa_tuple,8)) # 7 print(zjl.index_plus(aa_tuple,10)) # -1
list
- 本質:一個數字索引陣列
- 宣告:test_list=[1, 2, 3, 4, 5]
- 長度: len(test_tuple)
- 元素增:
- test_list.append(新元素)->自動在list末尾新增新元素 實際上等於test_list.insert(len(test_list), 新元素) insert是可以在list任何位置插入新元素的
- list.insert(插入的下標,插入的元素內容)
- 元素減:
- list.pop(刪除的元素下標)
- list.remove(刪除元素的內容)
- list.pop(len(list)-1)刪除末尾的元素
- 元素改:test_list[2] = 23
- 元素查: in not in 來判斷是否內容是否存在 但是無法確定位置 使用index_plus()來確定位置下標
- 元素輸出: test_list[2] 這是中括號 而不是元組宣告的小括號
- 元素切割 :test_list[1:5]
- 遍歷:for v in test_list:就可以
- 排序:list.sort() list.reverse()
- 複製 test_list.copy() 因為列表字典這些都是傳地址的 所以為了不干擾到原始的列表字典 只能用命令複製一個和原始列表字典一樣的變數 但是記憶體地址完全獨立 這樣我們修改新的變數不會影響到原始資料
- 清空 test_list.clear()
dict
- 本質:一個非數字索引的table 不能是數字索引 是數字索引就是set了
- 宣告:test_dict=(“name”:”zjl”,
“age”:18,
“sex”:True,
“adress”:”shandong”}
- 長度: len(test_dict)
- 元素增: test_dict[“id”] = 00023
- 元素減:test_dict.pop(要刪除的元素的key)
- 元素改:test_dict[“id”] = 00024
- 元素查: in not in 來判斷是否內容是否存在 但是無法確定位置 使用index_plus()來確定位置下標
- 元素輸出: test_dict[2] 這是中括號 而不是元組宣告的小括號
- 遍歷:for k, v in test_dict.items():就可以 注意items返回的是[(”name”,”zjl”), (”age”,18), (”sex”,True), (”adress”,”shandong”)]
- 排序:只能轉成list 然後list.sort()排序了 實際上字典的元素本來就沒什麼順序
- 合併: 2字典合併為一個 test_dict.update(新字典) 如果兩個字典的Key有衝突 後面的字典會覆蓋前面的
- 複製 test_dict.copy() 因為列表字典這些都是傳地址的 所以為了不干擾到原始的列表字典 只能用命令複製一個和原始列表字典一樣的變數 但是記憶體地址完全獨立 這樣我們修改新的變數不會影響到原始資料
- 清空 空字典 test_dict.clear()
set
- 本質:一個元素內容不重複的集合 沒有key 無論是數字key還是非數字key 並且集合的元素必須是不可變型別就是說 集合內必須是數字 字串 元組這種不可變元素 一般是用來求交集並集差集的
- 宣告:test_set=(“name”, ”zjl”, 18, (12, 34)} 或者 set(字串列表元素或者range()) test_set=([“name”, ”zjl”, 18, (12, 34)])
- 長度: len(test_set)
- 元素增: test_set.add(元素)
- 元素減:test_set.discard(刪除元素內容)
- 元素改:沒有Key來標識每個元素 無法對集合的元素進行修改 除非你重新宣告 無法類似 test_dict[0] = 11 XXX
- 元素查: in not in 來判斷是否內容是否存在
- 元素輸出: 沒有Key來標識每個元素 無法
- 遍歷:for v in test_set就可以
- 排序:只能轉成list 然後list.sort()排序了
- 交集並集差集: & | -
print({1,2} & {2,3,4}) # {2} print({1,2} | {2,3,4}) # {1, 2, 3, 4} print({1,2} - {2,3,4}) # {1}
- 複製 test_set.copy() 因為這些都是傳地址的 所以為了不干擾到原始的列表字典 只能用命令複製一個和原始列表字典一樣的變數 但是記憶體地址完全獨立 這樣我們修改新的變數不會影響到原始資料
- 清空 空字典 test_set.clear()
https://www.cnblogs.com/hukey/p/9242339.html
序列的公共方法和屬性
- * +
- in not in
- len()
- del()
- max() min() 字典的是獲取Key的最大最小
異常
完整的異常處理結構
import traceback
import logging # 匯入日誌模組
logger = logging.getLogger("traceback_test") # 配合 traceback.format_exc 輸出更詳細的情況
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s",
datefmt="%d-%m-%Y:%H:%M:%S")
try: # ==================主程式碼============================= # a = 1/a raise Exception("自定義異常丟擲") # 自己丟擲異常 可以自定義個異常類 也可以不用想太多直接用這個方式即可 except ValueError as e: # 同時應對多種異常的寫法 logging.debug("數字格式異常") logging.debug(repr(e)) # 返回普通的異常資訊,包括異常資訊的型別 # traceback.print_tb(sys.exc_info()[2]) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except ArithmeticError as e: # 同時應對多種異常的寫法 logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except (ValueError, ArithmeticError): # 同時應對多種異常的寫法 logging.debug("程式發生了數字格式異常、算術異常之一") except Exception as e: # Exception as e 放在else之前表示 如果上面都沒找到錯誤應對 那麼剩下的異常都歸這裡 # 輸出錯誤資訊 但是並沒有太詳細 更加詳細複雜的錯誤反饋需要用到 traceback 模組 logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # traceback.print_tb(sys.exc_info()[2]) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 else: logging.debug("無異常") # 沒發生異常就跳轉到這裡 finally: logging.debug("不管有無異常都要執行這") # 不管有無異常都要執行這
異常處理的原理
理解異常型別
異常其實都是一個類 這些異常的關係是如下
所有異常的父類都是BaswException類 常見的細化的類都是BaswException類的子類Exception類的子類 我們常用的自定義異常類也要以Exception為父類才可以
平時程式碼裡面出現的異常都是這些底層的子類的例項而已
異常執行的流程
首先Python直譯器 遇到的錯誤 就是丟擲一個異常 我們用try except 結構來接收這個異常的例項 然後根據異常例項的型別的不同 有針對性的進行處理
定義自己的異常類
1.命名是大坨峰法
2.父類都是Exception
3.try except裡面可以新增自定義型別來針對處理了 如果不需要這樣 就不用自定義異常類了 直接Exception的例項就可以了
class SignFailError(Exception): """ 簽到失敗 """ # 自定義異常型別的初始化 def __init__(self, value): self.value = value # 返回異常類物件的說明資訊 def __str__(self): return "SignFailError:{} ".format(repr(self.value)) class LogFailError(Exception): """ 登入失敗 """ # 自定義異常型別的初始化 def __init__(self, value): self.value = value # 返回異常類物件的說明資訊 def __str__(self): return "LogFailError:{} ".format(repr(self.value)) class RegisteFailError(Exception): """ 註冊失敗 """ # 自定義異常型別的初始化 def __init__(self, value): self.value = value # 返回異常類物件的說明資訊 def __str__(self): return "RegisteFailError:{} ".format(repr(self.value)) def main(): logging.debug("======start=%s======" % str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) # 標誌著除錯開始 e = None a = 0 try: # ==================主程式碼============================= # a = 1/a # raise Exception("自定義異常丟擲") # 自己丟擲異常 可以自定義個異常類 也可以不用想太多直接用這個方式即可 raise SignFailError("簽到失敗") except ValueError as e: # 同時應對多種異常的寫法 logging.debug("數字格式異常") logging.debug(repr(e)) # 返回普通的異常資訊,包括異常資訊的型別 # traceback.print_tb(sys.exc_info()[2]) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except ArithmeticError as e: # 同時應對多種異常的寫法 logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except SignFailError as e: # 同時應對多種異常的寫法 # logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except LogFailError as e: # 同時應對多種異常的寫法 # logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except RegisteFailError as e: # 同時應對多種異常的寫法 # logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except (ValueError, ArithmeticError): # 同時應對多種異常的寫法 logging.debug("程式發生了數字格式異常、算術異常之一") except Exception as e: # Exception as e 放在else之前表示 如果上面都沒找到錯誤應對 那麼剩下的異常都歸這裡 # 輸出錯誤資訊 但是並沒有太詳細 更加詳細複雜的錯誤反饋需要用到 traceback 模組 logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # traceback.print_tb(sys.exc_info()[2]) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 else: logging.debug("無異常") # 沒發生異常就跳轉到這裡 finally: logging.debug("不管有無異常都要執行這") # 不管有無異常都要執行這
手動丟擲異常和常見用法
一般是用於讓程式碼和異常處理分離 不過 我們也可以定義自己的異常類 來標識自己獨有的異常 比如說 簽到操作沒有完成 但是程式碼沒有錯誤 這個時候我們可以自定義一個異常類型別 然後自己命名這個異常型別的名字和提示的錯誤資訊 發現簽到操作沒完成 就丟擲一個SignFailError的自定義異常型別 在try except裡面捕獲這個自定義型別然後針對性的處理
異常資訊的反饋提示
import traceback
import logging # 匯入日誌模組
logger = logging.getLogger("traceback_test") # 配合 traceback.format_exc 輸出更詳細的情況
logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊
模組 包 庫 函式 類
函式
類
模組
本質:模組 每個py檔案都是一個模組 裡面包含了變數 函式 類 等等
匯入方式
1.import 模組名1 [as 別名1], 模組名2 [as 別名2],… 這種呼叫需要 模組1.方法1()
2.from 模組名 import 成員名1 [as 別名1],成員名2 [as 別名2],… 這種可以直接呼叫 成員名()
不推薦 form zjl import * 因為可能模組zjl裡面有和當前頁面重名的函式 變數 類 等等 因為這種方式呼叫不用加名稱空間 無法和本地的變數區分開來
匯入多個相同模組的問題
一個頁面匯入相同模組多次 或者 main頁面 匯入了一個aa的模組 但是 main模組中 還呼叫了工具模組 而工具模組中依然匯入了aa的模組 會發生什麼
編譯器會智慧識別 只會呼叫一次 所以我們無需擔心 在main檔案呼叫一批模組或者第三方庫 然後由於有需要 還在自定義模組裡面再次呼叫這些東西
匯入模組的本質
實際上就是將整個模組載入到記憶體中先編譯執行 然後將整個模組的內容賦值給和模組名同名的變數 該變數型別為module
自定義模組編寫說明文件
在模組開頭寫上即可 在模組名上停留或者ctrl+q 就可以看到這些提示 提示該模組包含的變數 類 函式等等
'''
demo 模組中包含以下內容:
name 字串變數:初始值為“Python教程”
add 字串變數:初始值為“http://c.biancheng.net/python”
say() 函式
CLanguage類:包含 name 和 add 屬性和 say() 方法。
'''
載入特殊的有空格的或者數字開頭的模組
__import__("demo text")
找不到模組檔案怎麼辦
檢視模組路徑(包也是一種特殊模組 一樣可以檢視)
print(my_module1.__file__)
我們可以使用這個屬性 獲取到絕對路徑
比如假設某個模組肯定位於根目錄下
my_package.__file__.split(”module1”)[0] 這樣就獲取到了目錄的絕對路徑
包
本質:本質就是個資料夾 也是一種特殊的模組 但是這個資料夾有個特殊的__init__.py檔案來管理這個特殊資料夾的內容 包含多個模組
建立包
- file->new->python package 建立包
- 在包資料夾裡面建立模組檔案 寫入模組內的程式碼
- 在__init__.py裡面 增加包內模組檔案的匯入語句 把模組匯入進包裡面
from . import 模組名1 # 這裡.就是指代當前包的包名
from . import 模組名2
匯入方式
import 包名[.模組名 [as 別名]] 推薦
from 包名 import 模組名 [as 別名]
from 包名.模組名 import 成員名 [as 別名]
匯入包的本質
其實就是執行了__init__.py 然後把執行結果賦值給了和包名同名的變數 等待進一步的呼叫
檢視包結構
dir(包名或者類名)
庫
庫由多個包構成
模組開發原則和py檔案的基本結構
1.每個py檔案都可能隨時變成模組 所以我們每個py檔案裡面都要引入main()函式 所有要執行的程式碼都扔進這個main()函式裡面執行
2.使用__name__來判斷當前頁面是作為執行還是作為模組被呼叫 以此來決定是否執行本頁面的main()
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # author:albert time:2020/9/6 # import random # 匯入random庫 import datetime # 日期時間模組 # import zjl # import sys # import test_model as tm import traceback import logging # 匯入日誌模組 import test_pack logger = logging.getLogger("traceback_test") # 配合 traceback.format_exc 輸出更詳細的情況 # ========================================控制檯==================================================== config_dict = dict() # 作者相關 config_dict["author"] = "zjl" config_dict["QQ"] = "1847154827" # 日誌 config_dict["islog"] = 1 # 是否開啟除錯 config_dict["islogfile"] = 0 # 是否輸出到日誌檔案 config_dict["logfilepath"] = "log_" + datetime.datetime.now().strftime("%Y-%m-%d") + ".txt" # ========================================配置函式==================================================== def config_fun(temp_config_dict): # 配置除錯和日誌 if temp_config_dict["islogfile"] == 1: logging.basicConfig(filename=temp_config_dict["logfilepath"], level=logging.DEBUG, format="%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s", datefmt="%d-%m-%Y:%H:%M:%S") else: logging.basicConfig(level=logging.DEBUG, format="%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s", datefmt="%d-%m-%Y:%H:%M:%S") if temp_config_dict["islog"] == 1: pass else: logging.disable(logging.DEBUG) # ========================================類函式區(或者放到一個模組裡面)==================================================== class SignFailError(Exception): """ 簽到失敗 """ # 自定義異常型別的初始化 def __init__(self, value): self.value = value # 返回異常類物件的說明資訊 def __str__(self): return "SignFailError:{} ".format(repr(self.value)) class LogFailError(Exception): """ 登入失敗 """ # 自定義異常型別的初始化 def __init__(self, value): self.value = value # 返回異常類物件的說明資訊 def __str__(self): return "LogFailError:{} ".format(repr(self.value)) class RegisteFailError(Exception): """ 註冊失敗 """ # 自定義異常型別的初始化 def __init__(self, value): self.value = value # 返回異常類物件的說明資訊 def __str__(self): return "RegisteFailError:{} ".format(repr(self.value)) # ========================================本頁主函式 配上異常處理部分======================================== def main(): logging.debug("======start=%s======" % str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) # 標誌著除錯開始 e = None a = 0 try: # ==================主程式碼============================= # a = 1/a # raise Exception("自定義異常丟擲") # 自己丟擲異常 可以自定義個異常類 也可以不用想太多直接用這個方式即可 raise SignFailError("簽到失敗") except ValueError as e: # 同時應對多種異常的寫法 logging.debug("數字格式異常") logging.debug(repr(e)) # 返回普通的異常資訊,包括異常資訊的型別 # traceback.print_tb(sys.exc_info()[2]) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except ArithmeticError as e: # 同時應對多種異常的寫法 logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except SignFailError as e: # 同時應對多種異常的寫法 # logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except LogFailError as e: # 同時應對多種異常的寫法 # logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except RegisteFailError as e: # 同時應對多種異常的寫法 # logging.debug("算術異常") logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # logging.debug(str(traceback.print_tb(sys.exc_info()[2]))) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 except (ValueError, ArithmeticError): # 同時應對多種異常的寫法 logging.debug("程式發生了數字格式異常、算術異常之一") except Exception as e: # Exception as e 放在else之前表示 如果上面都沒找到錯誤應對 那麼剩下的異常都歸這裡 # 輸出錯誤資訊 但是並沒有太詳細 更加詳細複雜的錯誤反饋需要用到 traceback 模組 logging.debug(repr(e)) # 返回較全的異常資訊,包括異常資訊的型別 # traceback.print_tb(sys.exc_info()[2]) logger.error(traceback.format_exc(limit=3)) # 輸出更多的反饋資訊 else: logging.debug("無異常") # 沒發生異常就跳轉到這裡 finally: logging.debug("不管有無異常都要執行這") # 不管有無異常都要執行這 logging.debug("======end=%s======" % str(datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))) # 標誌著除錯結束 # 當前頁面是入口檔案才會執行main函式 被呼叫的時候不會執行 if __name__ == "__main__": config_fun(config_dict) main()
檔案目錄操作
建立檔案資料夾
os.mkdir() 只能建立一層目錄 無法遞迴建立
os.makedirs() 能遞迴建立目錄 不會報錯 推薦 但是如果目錄已經存在了 兩個函式都會報錯 所以要配合os.path.exist() 使用
temp1_path = os.getcwd() +os.sep + "log" + os.sep + "a" if os.path.exists(temp1_path): # 目錄存在不用建立 logging.debug("[%s] 已經存在" % temp1_path) else: # 目錄不存在則建立 logging.debug(os.makedirs(temp1_path))
複製檔案資料夾
shutil.copyfile("oldfile","newfile") # oldfile和newfile都只能是檔案 操作前還是要判斷下是否都是檔案或者都是資料夾
移動檔案資料夾
shutil.move("oldpos","newpos") # 操作前還是要判斷下是否都是檔案或者都是資料夾
重新命名檔案資料夾
os.renames(old, new) # 遞迴重新命名 沒什麼說的
刪除檔案資料夾
刪除目錄 os.rmdir(path) os.removedirs(path)(兩者都不推薦 如果資料夾不為空 則刪除報錯)
推薦 shutil.rmtree 刪除目錄 不管你空不空 都刪除乾淨
刪除檔案 os.remove() 刪除檔案一樣要先判斷存在再刪除 因為刪除的檔案不在 一樣要報錯
import shutil temp1_path = os.getcwd() +os.sep + "a" + os.sep + "bb" logging.debug(os.listdir(temp1_path)) if os.path.exists(temp1_path): # 目錄存在要刪除 shutil.rmtree(temp1_path) # logging.debug(os.removedirs(temp1_path)) logging.debug("[%s] 刪除成功" % temp1_path) else: # 目錄不存在 不用刪除 logging.debug("[%s] 不存在不用刪除" % temp1_path)
判斷檔案資料夾 是否存在 os.path.exists
logging.debug(os.path.exists('..\\python1')) # 可以判斷檔案 目錄 支援相對路徑和絕對路徑 如果配合os.path.isfile os.path.isdir 可以進一步的判斷是目錄還是檔案
def file_dir_exists(temp1_path): """ :param temp1_path: 要檢測的路徑 支援檔案路徑 目錄路徑 :return: -1 表示不存在 0 表示存在而且是檔案 1 表示存在 是資料夾 :function: 是判斷檔案或者目錄是否存在 :base: 需要os模組的支援 """ temp1_result = -1 if os.path.exists(temp1_path): if os.path.isfile(temp1_path): temp1_result = 0 elif os.path.isdir(temp1_path): temp1_result = 1 else: temp1_result = -1 else: temp1_result = -1 return temp1_result
遍歷資料夾
logging.debug(os.listdir(os.getcwd())) # 返回一個包含當前目錄下的所有檔案資料夾的列表
路徑拼接 os.path.join
logging.debug(os.getcwd()) # 取當前所在檔案的目錄絕對路徑
logging.debug(os.path.abspath("test1.py")) # 相對轉絕對地址1
logging.debug(os.path.abspath(".\\test1.py")) # 相對轉絕對地址2
logging.debug(os.path.split(a)) 將路徑轉換為dirname 和basename兩部分的元組 相對路徑也可以拆分 但是感覺怪怪的
logging.debug(os.path.dirname(a))
logging.debug(os.path.basename(a))
logging.debug(os.sep) # 會根據當前系統情況來輸出正確的路徑斜線
logging.debug(os.path.join(os.path.dirname(a), os.path.basename(a))) # 利用前面提到的這些拼接成完整路徑 E:\python\test1.py
logging.debug(os.path.join(os.getcwd(), “test1.py”)
Python的路徑的斜線問題
眾所周知 window下路徑的斜線用\ 但是linux下的路徑斜線用/ 而且在windows下手寫路徑寫入\ 還要考慮轉義字元問題\\->\ 那麼我們平時Python的路徑 應該怎麼處理才能適應多個曹組系統
1.logging.debug(os.sep) # os.sep 會根據當前系統情況來輸出正確的路徑斜線
2.logging.debug(os.path.join(".", "python", "test1111.py")) # 把路徑的部分拆開 然後用os.path.join拼接到一起 或者用os.path.dirname 或者os.getcwd() 提取出目錄地址 然後用os.path.join拼接成一個完整路徑
3 Python3.4+的os.path.pathlib模組
import pathlib # 匯入pathlib
logging.debug(pathlib.Path("e:/python/test_pack/test_pack_module1.py")) # 以正斜線來描述路徑 pathlib.Path會自動根據系統返回合適的路徑
open()函式
file = open(file_name [, mode='r' [ , buffering=-1 [ , encoding = None ]]])
file_name:就是要打開了檔案路徑 為了以防萬一還是要檢測下該檔案是否是檔案 是否存在
mode:這個都明白 常見備選的有 r r+ w w+ a a+
buffering:就是對檔案操作的時候 是否開啟緩衝區 但是這個引數意義不大 因為如果我們寫入文字檔案的時候 緩衝區必須是開啟的 不然會報錯 開啟緩衝區的作用只是讓操作 比如寫入操作不會立刻執行 而是等一系列操作後 遇到close() 的時候 從緩衝區讀取系列操作 一次性執行完畢 如果沒遇到close但是想立刻執行則 使用flush()來實現階段性的執行
encoding:沒什麼說的 文字檔案使用的編碼格式
讀取檔案內容
- f = open("a.txt", 'r')
- temp1 = f.read()
- print(temp1)
- f.close()
寫入原理
我們寫入文字檔案的時候 緩衝區必須是開啟的 不然會報錯 開啟緩衝區的作用只是讓操作 比如寫入操作不會立刻執行 而是等一系列操作後 遇到close() 的時候 從緩衝區讀取系列操作 一次性執行完畢 如果沒遇到close但是想立刻執行則 使用flush()來實現階段性的執行
寫入檔案內容
- f = open("a.txt", 'w')
- f.write("覆蓋寫入")
- f.close()
追加檔案內容
- f = open("a.txt", 'a')
- f.write("追加寫入")
- f.close()
讀取檔案指定行內容
- f = open("a.txt", 'r')
- temp1 = f.readline() # 讀取一行內容
- print(temp1)
- f.close()
讀取檔案內容返回列表
- f = open('a.txt', 'r')
- n = open('b.txt','w+')
- n.writelines(f.readlines())
- n.close()
- f.close()
with as的使用 (推薦這個方式 會自動close 報錯也會自動執行close)
with open(temp1_path, "r") as f:
logging.debug(f.read())
使用這種形式非常方便 就算程式碼內部出錯了一樣會自動close 推薦這個方式
日誌除錯資訊
完整的日誌除錯程式碼
import logging # 匯入日誌模組 # =====配置除錯資訊======= 是否輸出到檔案 除錯資訊等級 資訊格式等等 設定所在檔案 設定行號 如果要變成日誌輸出到日誌檔案 則 # 日誌檔案:logging.basicConfig(filename='demo.txt', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(level=logging.DEBUG,
format="%(asctime)s,%(msecs)d %(levelname)-8s [%(filename)s:%(lineno)d] %(message)s",
datefmt="%d-%m-%Y:%H:%M:%S"
) """ logging.CRITICAL: 致命錯誤 最高等級 logging.ERROR: 用於記錄錯誤,它導致程式做某事失敗 logging.WARNING:用於表示可能的問題,它不會阻止程式的工作,但將來可能會。 logging.INFO:用於記錄程式中一般事件的資訊,或確認一切工作正常 logging.DEBUG:最低級別,用於小細節,通常只有在診斷問題時,才會關心這些訊息 logging.disable 會把引數的錯誤等級和該引數下面的錯誤等級一起關閉 這些錯誤都不會出現在除錯資訊裡面 """ # logging.disable(logging.DEBUG) # 控制除錯資訊的顯示等級 控制是否顯示除錯資訊 logging.debug("======start=======") # 標誌著除錯開始 # logging.debug支援print的字串格式化 aa = 100 logging.debug("======start=====%d==" % aa) for i in range(10): logging.debug('i: ' + str(i)) # 正常的除錯資訊 logging.debug("======end=======") # 標誌著除錯結束
logging的強大功能 似乎print也被完全代替了 之後程式碼都採用logging來反饋資訊
結果