File I/O & module

學了大部分的資料結構後,其實 Python 已經知道七十趴了歐。

File I/O

但之前說過的各種 list, tuple, dict 這些畢竟都還在程式內部,就算我把整本英漢字典花兩個月打成一個巨大的 Python dict。它還是在程式的那個檔案裡(而且佔一堆空間),所以現在要來講怎麼開檔案!

I/O 就是 input/output 的意思,用程式的角度思考,打開一個檔案,不論要讀還是寫,都是在既有的東西裡擴充、匯入新的東西,所以開檔讀檔稱為 file input。
而 ouput 在程式裡就是呈現結果的意思,例如我們直接 print("Hello") 時,就叫做 terminal output,print 本身就是一個 output 指令而 terminal 就是 output 的目的地,如果把 output 的目的地改成一個檔案,那就會是 output to a file 了。

試試

file = open("test.txt", "w")
file.write("hi")
file.close()

接著試試

file = open("test.txt", "a")
file.write("hi_2")
file.close()

我們成功 write 了一個檔案,又 append 了一行

所有任何的檔案其實都是純文字,每一次程式打開一個檔案時,都會開啟一條程式與那個檔案的溝通途徑,稱為 stream,是一個單向單功能的道路,也就是說讀、寫、新增都需要開各自的 stream。
所有資料都會待在 stream 裡面直到電腦 cpu 有閒才會真正 update 到檔案去(但通常快到不會察覺),所以當不再需要一個 stream 時,記得要關掉它。

試試

file = open("test.txt", "w")
file.write("1st line\n2nd line\n3rd line\n4th line\n5th line")
file.close()
  • for loop 讀法
fref = open("test.txt", "r")
for line in fref:
    print(line)
fref.close()
  • readline() 讀法
fref = open("test.txt", "r")
print(fref.readline())
print(fref.readline())
print(fref.readline())
fref.close()
  • readlines() 讀法
fref = open("test.txt", "r")
print(fref.readlines())
fref.close()
  • read() 讀法
fref = open("test.txt", "r")
print (fref.read())
fref.close()
最後的換行很令人困擾吧,試試
fref = open("test.txt", "r")
for line in fref:
    print(line[:-1])
fref.close()



這就是 Python 最內建的 file I/O 用法,可以開始當 txt 檔的信徒囉

Module

Module 是一個久遠但我們不斷在使用的東西,之前介紹說它是讓我們有辦法用「別的地方來的 code」的機制。像是想要隨機數就 import random 想要日期時間就 import datetime.datetime

但「別的地方來的 code」也可以是我們自己的,只是放在別的檔案的程式!

先創建一個新檔案 myModule.py,然後裡面寫一個叫 random_from_list 的 function,完整註解如下:

def random_from_list(l):
    ''' picks a random element from the list
    args: 
        l(list): the user-input list 
    return: the chosen element
    '''

接下來回到我們的檔案,像 import 所有 module 一樣在最上面打上 import myModule
就像要使用 random 這個 module 的 randrange() function 一樣,我們用點來叫一個檔案(object)裡面的值
在原本的檔案試試下面吧

import myModule

a = [0, 1, 2, 3 ,4 ,5 ,6, 7, 8, 9]
b = ["11", "22", "33", "44", "55", "66", "77", "88"]
print(myModule.random_from_list(a))
print(myModule.random_from_list(b))