Python外部操作 — 外部引用與存取

Wen Chang
11 min readJan 16, 2020

--

單元四 : Python外部操作 — 程式外部引用與存取溝通

為了要使用別人寫好的python程式,以及更好的組織、管理我們寫好的程式碼方便往後使用。我們會將寫好的程式碼包裝成副程式、package/library,並使用import 引入這些外部的python程式供給我們直接使用。

另一方面,為了要方便取得python程式外的檔案、資源以及輸入輸出,我們在課程最後也向大家介紹如何使用python 主要的 IPC(程式間通訊)功能;希望各位同學勤加練習,只要熟稔這些基礎的python操作,您就是相當不錯的python工程師了

python 封裝與引用

使用 import 引用副程式或Library

使用方式

想使用外部 Python 文件如副程式或Library,只需在另一個源文件裡執行 import 語句,語法如下:

import module1[, module2[,... moduleN]

外部模塊就是在你 import 什麼東西去python 腳本的時候會用到的。當python的直譯器遇到 import 語句時,如果模塊在當前python直譯器的搜索路徑範圍內就會​​被導入。

import numpy as np
import matplotlib.pyplot as plt

這裡的 Numpy 和 matplotlib 都是外部模塊, 需要安裝以後才會有的,不屬於 python 自帶的模塊。

範例

import time 指 import time 模塊,這個模塊可以python自帶,也可以是自己安裝的,比如以後會用到numpy這些模塊,需要自己安裝。

import time
print(time.localtime()) #这样就可以print 当地时间了
""""
time.struct_time(tm_year=2016, tm_mon=12, tm_mday=23, tm_hour=14, tm_min=12, tm_sec=48, tm_wday=4, tm_yday=358, tm_isdst=0)
""""

方法二:import time as __,__下劃線縮寫部分可以自己定義,在代碼中把time 定義成 t.

import time as t
print(t.localtime()) # 需要加t.前缀来引出功能
""""
time.struct_time(tm_year=2016, tm_mon=12, tm_mday=23, tm_hour=14, tm_min=12, tm_sec=48, tm_wday=4, tm_yday=358, tm_isdst=0)
""""

方法三:from time import time,localtime ,只import自己想要的部分功能。

from time import time, localtime
print(localtime())
print(time())
""""
time.struct_time(tm_year=2016, tm_mon=12, tm_mday=23, tm_hour=14, tm_min=41, tm_sec=38, tm_wday=4, tm_yday=358, tm_isdst=0)
1482475298.709855
""""

方法四:from time import * 輸入模塊的所有功能

from time import *
print(localtime())
""""
time.struct_time(tm_year=2016, tm_mon=12, tm_mday=23, tm_hour=14, tm_min=41, tm_sec=38, tm_wday=4, tm_yday=358, tm_isdst=0)
""""

將寫好的程式碼檔案封裝成副程式、Package、Library

副程式

建立副程式

這裡是計算五年復利本息的副程式,程式碼如下:寫好後存成副程式,將其命名為:balance.py

d=float(input('Please enter what is your initial balance: \n'))
p=float(input('Please input what is the interest rate (as a number): \n'))
d=float(d+d*(p/100))
year=1
while year<=5:
d=float(d+d*p/100)
print('Your new balance after year:',year,'is',d)
year=year+1
print('your final year is',d)

調用副程式

在同資料夾內新開一個python程式,import balance

import balance""""
Please enter what is your initial balance:
50000 # 要求使用者輸入本金
Please input what is the interest rate (as a number):
2.3 # 要求使用者手動輸入利率
Your new balance after year: 1 is 52326.45
Your new balance after year: 2 is 53529.95834999999
Your new balance after year: 3 is 54761.14739204999
Your new balance after year: 4 is 56020.653782067144
Your new balance after year: 5 is 57309.12881905469
your final year is 57309.12881905469
""""

Library 與 Package

Library 與 Package是一種管理 Python 模塊命名空間的形式,採用”點 — 模塊名稱”。比如一個模塊的名稱是 A.B, 那麼他表示一個包 A中的子模塊 B 。

就好像使用模塊的時候,你不用擔心不同模塊之間的全局變量相互影響一樣,採用點模塊名稱這種形式也不用擔心不同庫之間的模塊重名的情況。
這樣不同的作者都可以提供 NumPy 模塊,或者是 Python 圖形庫。

假設你想設計一套統一處理聲音文件和數據的模塊(或者稱之為一個”Package”)。現存很多種不同的音頻文件格式(基本上都是通過後綴名區分的,例如: .wav,:file:.aiff,:file:.au,),所以你需要有一組不斷增加的模塊,用來在不同的格式之間轉換。
並且針對這些音頻數據,還有很多不同的操作(比如混音,添加迴聲,增加均衡器功能,創建人造立體聲效果),所以你還需要一組怎麼也寫不完的模塊來處理這些操作。
這裡給出了一種可能的Package結構(在分層的文件中):

sound/                          頂層主Package
__init__.py 初始化主Package (sound package)
formats/ 處理文件格式轉換的子Package
__init__.py
wavread.py
wavwrite.py
aiffread.py
aiffwrite.py
auread.py
auwrite.py
...
effects/ 聲音效果子Package
__init__.py
echo.py
surround.py
reverse.py
...
filters/ filters 子Package
__init__.py
equalizer.py
vocoder.py
karaoke.py
...

在導入一個Package的時候,Python 會根據 sys.path 中的目錄來尋找這個包中包含的子目錄。
目錄只有包含一個叫做 __init__.py 的文件才會被認作是一個包,主要是為了避免一些濫俗的名字(比如叫做 string)不小心的影響搜索路徑中的有效模塊。
最簡單的情況,放一個空的 :file:__init__.py就可以了。當然這個文件中也可以包含一些初始化代碼或者為(將在後面介紹的) __all__變量賦值。
用戶可以每次只導入一個Package裡面的特定模塊,比如:

import sound.effects.echo

這將會導入子模塊:sound.effects.echo。他必須使用全名去訪問:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

檔案存取與行程間通訊IPC

檔案IO(Open、Read、Write、Close)

open 開啟文件

使用open 能夠打開一個文件, open 的第一個參數為文件名和路徑’my file.txt’, 第二個參數為將要以什麼方式打開它, 比如w 為可寫方式. 如果計算機沒有找到’my file .txt’ 這個文件, w 方式能夠創建一個新的文件, 並命名為my file.txt

my_file=open('my file.txt','w')   #用法: open('文件名','形式'), 其中形式有'w':write;'r':read.my_file.write(text)               #該語句會寫入先前定義好的 text
my_file.close() #關閉文件

Read 讀文件方式

讀取文件內容 file.read()

使用 file.read() 能夠讀取到文本的所有內容.

file= open('my file.txt','r') 
content=file.read()
print(content)

""""
This is my first test.
This is the second line.
This the third line.
This is appended file.
""""

按行讀取 file.readline()

如果想在文本中一行行的讀取文本文件,可以使用file.readline(), file.readline() 讀取的內容和你使用的次數有關, 使用第二次的時候, 讀取到的是文本的第二行, 並可以以此類推:

file= open('my file.txt','r') 
content=file.readline() # 讀取第一行
print(content)

""""
This is my first test.
""""

second_read_time=file.readline() # 讀取第二行
print(second_read_time)

"""
This is the second line.
"""

讀取所有行 file.readlines()

如果想要讀取所有行, 並可以使用像 for 一樣的迭代器迭代這些行結果, 我們可以使用 file.readlines(), 將每一行的結果存儲在 list 中, 方便以後迭代.

file= open('my file.txt','r') 
content=file.readlines() # python_list 形式
print(content)

""""
['This is my first test.\n', 'This is the second line.\n', 'This the third line.\n', 'This is appended file.']
""""

# 之後如果使用 for 來迭代輸出:
for item in content:
print(item)

"""
This is my first test.

This is the second line.

This the third line.

This is appended file.
"""

Write 寫入文件

我們先保存一個已經有3行文字的 “my file.txt” 文件, 文件的內容如下:

This is my first test. 
This is the second line.
This the third

然後使用添加文字的方式給這個文件添加一行 “This is appended file.”, 並將這行文字儲存在 append_file 裡,注意\n的適用性:

append_text='\nThis is appended file.'  # 為這一行文字前空行 "\n"
my_file=open('my file.txt','a') # 'a'=append 以增加內容的形式打開文件
my_file.write(append_text)
my_file.close()
""""
This is my first test.
This is the second line.
This the third line.
This is appended file.
""""
#運行後再去打開文件,會發現會增加一行代碼中定義的字符串

使用Http協定(使用requests函式庫)

Http協定套件 :

Import requests

Requests.get

Requests.post

Requests.put

Requests.delete

--

--