python 程式設計基礎 —— 大廈必不可少的磚瓦水泥

2020-09-28 10:00:50

掌握python基本語法後,我們可以在騷騷地寫一些小指令碼,當時總感覺少了點什麼?

檔案讀寫

我們要載入外部的檔案怎麼辦?我們要儲存自己計算好的資料怎麼辦呢?這個時候我們需要用到檔案讀寫功能。我們先開啟一個檔案物件

# file = open(file_name [, access_mode][, buffering])
file_1 = open('python大法是好劍客.txt', 'r') # 唯讀檔案

file_name是檔名或著檔案的path,access_mode用來制定檔案操作的模式,如果是唯讀檔案,pattern=‘r’; 只寫檔案,pattern=‘w’,明細引數可以參考下圖(來自菜鳥教學); buffering 表示是否寄存,基本不會用到。
python 檔案讀取參數設定
然後我們就可以讀取檔案物件中的內容或者寫入內容,常用操作

  • 讀取: file.readline() 逐行讀取; file.readlines()一次性讀取所有行 (小檔案可以,大檔案很危險!)
  • 寫入:file.write(string) 字串寫入檔案;file.writelines(sequence)
# 第一行內容是:你又在胡說八道什麼了!
print(file.readline())

除了檔案讀寫,可能還需要補充一些檔案路徑方面的操作,在os庫裡面定義了豐富的工具函數

  • os.mkdir(dir)新建目錄; 加強版os.makedirs() 建立完成的路徑目錄,比如你在/user下要建立 /user/python/base/helloworld/,在python/base/不存在的情況下,os.makdirs
  • os.getcwd() 獲取當前目錄
  • os.rmdir(dir)刪除目錄,刪除操作很危險,儘量少用
  • os.path.exists(path) 判斷路徑是否存在
  • os.path.join(str1, str2, str3) 會把str1,str2,str3連線成一個路徑。

命令列引數

大家在學python的時候一定會到類似如下的命令

python say_hello.py  LiMing

在py指令碼後多了一個字串,你會問它到底是什麼?有什麼用呢?我們看一下say_hello.py的內部實現

import sys

print("hello, {}! ".format(sys.argv[1]))

其實就是想和遇到的小夥伴套個近乎,但是需要知道小夥伴的姓名,這個使用通過一個命令列引數傳遞傳遞進來。sys.argv[ind],ind=0取的是當前執行的指令碼名,1才是第一個引數,依次遞推。

使用sys.argv的優點是傳遞引數很簡單,有個問題你都不知道傳遞的引數什麼意思?而且還沒發給預設引數?那麼怎麼解決這寫問題呢?python大法說,不要慌,我們還有一個神奇的argparse標準, 用法

import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--name", type=str, default="HanMeimei",  help="小夥伴的姓名")
args = parser.parse_args()
print("hello, {}! ".format(args.name))

呼叫方式就改成了

python say_hello.py  --name LiMing

如果你沒有傳引數,系統預設所有的人都是HanMeimei!

列印紀錄檔

大家在執行程式的時候,如果程式很長,只是傻傻地等待程式執行結束的話,過程往往很煎熬,而且容易出問題。

比如你的程式有bug,中間結果計算並正確?或者你在做機器學習的時候,初始化引數不好,模型一開始就不收斂,我們需要及時止損。即便不止損,我們知道程式的進度,也還安排晚上是去花天酒地呢?還是繼續後續的操作。

那麼怎麼辦呢?最簡單的直接方案藉助print來列印中間結果/進度條,print函數好

from wuliao import ganhuaishi

count = 0
while (True):
	count += 1
	ganhuaishi()
	if count % 100:
		print("hello world!")

每呼叫ganhuaishi() 函數100次,我們都列印一次hello world!也可以選擇列印某些變數,比如在機器學習裡面訓練模型是往往會列印損失函數、準確率,用來監控模型訓練的效果。

但是print函數太簡單了,對於大型的應用程式要上紀錄檔系統?僅僅用print往往不夠用。那麼python有木有成熟的紀錄檔庫呢?python大法又來了,這個必須有啊!它就是logging庫,專業紀錄檔輸出神器。logging不僅能輸出到控制檯,還能寫入檔案,使用TCP協定,將紀錄檔資訊傳送到網路等等,功能十分強大, 具體大家參考[4],我不展開了,以後有機會單獨講解(言外之意我還沒有搞透!)。可以參考以下程式碼:

# -*- coding: UTF-8 -*-
import os
import logging
import time

def logger_init(log_dir):
    """初始化紀錄檔模組"""
    logger = logging.getLogger()
    logger.setLevel(logging.INFO)

    # 定義輸出路徑
    rq = time.strftime("%Y%m%d%H%M", time.localtime(time.time()))
    log_path = os.path.join(log_dir, "{}.log".format(rq))
    fh = logging.FileHandler(log_path, mode="w")
    fh.setLevel(logging.INFO)

    # 定義輸出格式
    formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
    fh.setFormatter(formatter)

    # 輸出到螢幕
    console = logging.StreamHandler()
    console.setLevel(logging.INFO)
    console.setFormatter(formatter)
    logger.addHandler(fh)
    logger.addHandler(console)

    return logger

if __name__ == "__main__":
    logger = logger_init("../logs")
    logger.info("hello logger!")

例外處理

最早是在學生階段知道了例外處理這個東西,但年自己也不是計算機專業,寫程式碼純粹是為了處理點資料,水個文章。但是總是有的程式碼跑一半就掉了,但是也不是什麼大問題,我就想怎麼跳過這些問題呢?某一天有個師兄說,你可以試試try/catch語句(當時還只會用matlab)!

在python中try/except來進行異常捕獲,捕獲異常後,我們可以進行例外處理,如果不跳出程式,就不會影響後續的程式碼執行。

try:
	ganhuaishi()
except Exception:
	print("時候未到!")

print("hello world!")	

try的語法

try:
<語句>        #執行別的程式碼
except <名字>:
<語句>        #如果在try部份引發了'name'異常
except <名字>,<資料>:
<語句>        #如果引發了'name'異常,獲得附加的資料
else:
<語句>        #如果沒有異常發生

try的工作原理是,當開始一個try語句後,python就在當前程式的上下文中作標記,這樣當異常出現時就可以回到這裡,try子句先執行,接下來會發生什麼依賴於執行時是否出現異常:

  • 如果當try後的語句執行時發生異常,python就跳回到try並執行第一個匹配該異常的except子句,例外處理完畢,控制流就通過整個try語句(除非在處理異常時又引發新的異常)。
  • 如果在try後的語句裡發生了異常,卻沒有匹配的except子句,異常將被遞交到上層的try,或者到程式的最上層(這樣將結束程式,並列印預設的出錯資訊)。
  • 如果在try子句執行時沒有發生異常,python將執行else語句後的語句(如果有else的話),然後控制流通過整個try語句。[5]

當然用try時候很危險啊,因為你把一些異常跳過去了,這個時候except中必須加提示和處理,此次是重點!!!

除了try/except語句,python還提供assert斷言語句,用來做一些異常檢查,一旦不滿足assert語句,程式會立馬中斷並報錯。

比如程式要求輸入名字為LiMing,結果輸入了HanMeimei,那麼

assert name=="LiMing", "請輸入LiMing,{} 是乖寶寶".format(name)

assert斷言語句個人感覺很好,當你寫一個功能的時候對輸入、中間結果、輸出必須正確把握,做測試的時候就可以用assert來檢查一些中間結果,及時止損,免得輸掉麵包錢![6]

至此你已經學會了python的地基(基礎語法,好像還缺函數和物件導向程式設計,回頭補哈)和 磚瓦水泥,能建成怎樣的高樓大廈(茅草屋),就看個人修行了。來開始你的表演。

參考

  1. https://www.liaoxuefeng.com
  2. https://www.runoob.com/python/python-files-io.html
  3. https://www.cnblogs.com/dengtou/p/8413609.html
  4. https://blog.csdn.net/zgf605506394/article/details/88595135
  5. https://www.runoob.com/python/python-exceptions.html
  6. https://blog.csdn.net/qq_39247153/article/details/81082313

在這裡插入圖片描述