1. 程式人生 > 實用技巧 >黑馬python入門(4):python基礎(序列,異常,操作檔案,模組包,日誌除錯資訊)

黑馬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)
  • 元素增:
  1. test_list.append(新元素)->自動在list末尾新增新元素 實際上等於test_list.insert(len(test_list), 新元素) insert是可以在list任何位置插入新元素的
  2. list.insert(插入的下標,插入的元素內容)
  • 元素減:
  1. list.pop(刪除的元素下標)
  2. list.remove(刪除元素的內容)
  3. 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


序列的公共方法和屬性

  1. * +
  2. in not in
  3. len()
  4. del()
  5. 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檔案來管理這個特殊資料夾的內容 包含多個模組

建立包

  1. file->new->python package 建立包
  2. 在包資料夾裡面建立模組檔案 寫入模組內的程式碼
  3. 在__init__.py裡面 增加包內模組檔案的匯入語句 把模組匯入進包裡面

from . import 模組名1 # 這裡.就是指代當前包的包名

from . import 模組名2

匯入方式

  1. import 包名[.模組名 [as 別名]] 推薦
  2. from 包名 import 模組名 [as 別名]
  3. 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:沒什麼說的  文字檔案使用的編碼格式

讀取檔案內容

  1. f = open("a.txt", 'r')
  2. temp1 = f.read()
  3. print(temp1)
  4. f.close()

寫入原理

我們寫入文字檔案的時候 緩衝區必須是開啟的 不然會報錯 開啟緩衝區的作用只是讓操作 比如寫入操作不會立刻執行 而是等一系列操作後 遇到close() 的時候 從緩衝區讀取系列操作 一次性執行完畢 如果沒遇到close但是想立刻執行則 使用flush()來實現階段性的執行

寫入檔案內容

  1. f = open("a.txt", 'w')
  2. f.write("覆蓋寫入")
  3. f.close()

追加檔案內容

  1. f = open("a.txt", 'a')
  2. f.write("追加寫入")
  3. f.close()

讀取檔案指定行內容

  1. f = open("a.txt", 'r')
  2. temp1 = f.readline() # 讀取一行內容
  3. print(temp1)
  4. f.close()

讀取檔案內容返回列表

  1. f = open('a.txt', 'r')
  2. n = open('b.txt','w+')
  3. n.writelines(f.readlines())
  4. n.close()
  5. 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來反饋資訊

結果