列表
列表是Python中內置有序、可變序列,列表的所有元素放在一對中括號“[]”中,並使用逗號分隔開;
當列表元素增加或刪除時,列表對象自動進行擴展或收縮內存,保證元素之間沒有縫隙;
在Python中,一個列表中的數據類型可以各不相同,可以同時分別爲整數、實數、字符串等基本類型,甚至是列表、元組、字典、集合以及其他自定義類型的對象。
常用方法
方法
說明
lst.append(x)
將元素x添加至列表lst尾部
lst.extend(L)
將列表L中所有元素添加至列表lst尾部
lst.insert(index, x)
在列表lst指定位置index處添加元素x,該位置後面的所有元素後移一個位置
lst.remove(x)
在列表lst中刪除首次出現的指定元素,該元素之後的所有元素前移一個位置
lst.pop([index])
刪除並返回列表lst中下標爲index(默認爲-1)的元素
lst.clear()
刪除列表lst中所有元素,但保留列表對象
lst.index(x)
返回列表lst中第一個值爲x的元素的下標,若不存在值爲x的元素則拋出異常
lst.count(x)
返回指定元素x在列表lst中的出現次數
lst.reverse()
對列表lst所有元素進行逆序
lst.sort(key=None, reverse=False)
對列表lst中的元素進行排序,key用來指定排序依據,reverse決定升序(False)還是降序(True)
lst.copy()
返回列表lst的淺複製
列表推導式
列表推導式在內部實際上是一個循環結構,只是形式更加簡潔,例如:
aList = [x*x for x in range(10)]
相當於
aList = []
for x in range(10): aList.append(x*x)
過濾不符合條件的元素
aList = [-1,-4,6,7.5,-2.3,9,-11]
[i for i in aList if i>0]
[6, 7.5, 9]
元組
元組和列表類似,但屬於不可變序列,元組一旦創建,用任何方法都不可以修改其元素。 元組的定義方式和列表相同,但定義時所有元素是放在一對圓括號“()”中,而不是方括號中。
與列表的區別
元組一旦定義就不允許更改
元組沒有append()、extend()和insert()等方法,無法向元組中添加元素
元組沒有remove()或pop()方法,也無法對元組元素進行del操作,不能從元組中刪除元素
從效果上看,tuple( )凍結列表,而list( )融化元組
優點
元組的速度比列表更快
如果定義了一系列常量值,而所需做的僅是對它進行遍歷,那麼一般使用元組而不用列表。
元組對不需要改變的數據進行“寫保護”將使得代碼更加安全。 元組可用作字典的“鍵”,也可以作爲集合的元素
列表永遠不能當做字典鍵使用,也不能作爲集合的元素,因爲列表不是不可變的
字典
字典是無序、可變序列。 定義字典時,每個元素的鍵和值用冒號分隔,元素之間用逗號分隔,所有的元素放在一對大括號“{}”中。 字典中的鍵可以爲任意不可變數據,比如整數、實數、複數、字符串、元組等等。 globals()返回包含當前作用域內所有全局變量和值的字典 locals()返回包含當前作用域內所有局部變量和值的字典
創建
使用=將一個字典賦值給一個變量
a_dict = {‘server’: ‘db.diveintopython3.org’, ‘database’: ‘mysql’}
a_dict {‘database’: ‘mysql’, ‘server’: ‘db.diveintopython3.org’}
x = {} #空字典
x {}
使用dict利用已有數據創建字典
keys = [‘a’, ‘b’, ‘c’, ‘d’]
values = [1, 2, 3, 4]
dictionary = dict(zip(keys, values))
dictionary {‘a’: 1, ‘c’: 3, ‘b’: 2, ‘d’: 4}
x = dict() #空字典
x {}
元素獲取
以鍵作爲下標可以讀取字典元素,若鍵不存在則拋出異常
使用字典對象的get方法獲取指定鍵對應的值,並且可以在鍵不存在的時候返回指定值
使用字典對象的items()方法可以返回字典的鍵、值對
使用字典對象的keys()方法可以返回字典的鍵
使用字典對象的values()方法可以返回字典的值
元素添加
當以指定鍵爲下標爲字典賦值時:
1)若鍵存在,則可以修改該鍵的值;
2)若不存在,則表示添加一個鍵、值對。
aDict[‘age’] = 38 #修改元素值
aDict {‘age’: 38, ‘name’: ‘Dong’, ‘sex’: ‘male’}
aDict[‘address’] = ‘SDIBT’ #增加新元素
aDict {‘age’: 38, ‘address’: ‘SDIBT’, ‘name’: ‘Dong’, ‘sex’: ‘male’}
元素刪除
使用del刪除字典中指定鍵的元素
使用字典對象的clear()方法來刪除字典中所有元素
使用字典對象的pop()方法刪除並返回指定鍵的元素
使用字典對象的popitem()方法刪除並返回字典中的一個元素
字典推導式
s = {x:x.strip() for x in (’ he ', 'she ‘, ’ I’)}
s
{’ he ‘: ‘he’, ’ I’: ‘I’, 'she ': ‘she’}
集合
集合是無序、可變序列,使用一對大括號界定,元素不可重複,同一個集合中每個元素都是唯一的。 集合中只能包含數字、字符串、元組等不可變類型(或者說可哈希)的數據,而不能包含列表、字典、集合等可變類型的數據。
創建
直接將集合賦值給變量
a = {3, 5}
a.add(7) #向集合中添加元素
a {3, 5, 7}
使用set將其他類型數據轉換爲集合
a_set = set(range(8,14))
a_set {8, 9, 10, 11, 12, 13}
b_set = set([0, 1, 2, 3, 0, 1, 2, 3, 7, 8]) #自動去除重複
b_set {0, 1, 2, 3, 7, 8}
c_set = set() #空集合
c_set set()
使用del刪除整個集合
當不再使用某個集合時,可以使用del命令刪除整個集合。集合對象的pop()方法彈出並刪除其中一個元素,remove()方法直接刪除指定元素,clear()方法清空集合。
切片
切片適用於列表、元組、字符串、range對象等類型,但作用於列表時功能最強大。可以使用切片來截取列表中的任何部分,得到一個新列表,也可以通過切片來修改和刪除列表中部分元素,甚至可以通過切片操作爲列表對象增加元素。
切片使用2個冒號分隔的3個數字來完成
第一個數字表示切片開始位置(默認爲0)
第二個數字表示切片截止(但不包含)位置(默認爲列表長度)
第三個數字表示切片的步長(默認爲1),當步長省略時可以順便省略最後一個冒號
切片操作不會因爲下標越界而拋出異常,而是簡單地在列表尾部截斷或者返回一個空列表,代碼具有更強的健壯性。
aList = [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
aList[::] #返回包含所有元素的新列表 [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
aList[::-1] #逆序的所有元素 [17, 15, 13, 11, 9, 7, 6, 5, 4, 3]
aList[::2] #偶數位置,隔一個取一個 [3, 5, 7, 11, 15]
aList[1::2] #奇數位置,隔一個取一個 [4, 6, 9, 13, 17]
aList[3::] #從下標3開始的所有元素 [6, 7, 9, 11, 13, 15, 17]
aList[3:6] #下標在[3, 6)之間的所有元素 [6, 7, 9]
aList[0💯1] #前100個元素,自動截斷 [3, 4, 5, 6, 7, 9, 11, 13, 15, 17]
aList[100:] #下標100之後的所有元素,自動截斷 []
aList[100] #直接使用下標訪問會發生越界 IndexError: list index out of range
切片返回的是列表元素的淺複製,所謂淺複製,是指生成一個新的列表,並且把原列表中所有元素的引用都複製到新列表中。如果原列表中只包含整數、實數、複數等基本類型或元組、字符串這樣的不可變類型的數據,一般是沒有問題的。如果原列表中包含列表之類的可變數據類型,由於淺複製時只是把子列表的引用複製到新列表中,這樣的話修改任何一個都會影響另外一個。
序列解包
可以使用序列解包功能對多個變量同時賦值
x, y, z = 1, 2, 3 #多個變量同時賦值
v_tuple = (False, 3.5, ‘exp’)
(x, y, z) = v_tuple
x, y, z = v_tuple
x, y, z = range(3) #可以對range對象進行序列解包
x, y, z = iter([1, 2, 3]) #使用迭代器對象進行序列解包
x, y, z = map(str, range(3)) #使用可迭代的map對象進行序列解包
a, b = b, a #交換兩個變量的值
x, y, z = sorted([1, 3, 2]) #sorted()函數返回排序後的列表
a, b, c = ‘ABC’ #字符串也支持序列解包
x = [1, 2, 3, 4, 5, 6]
x[:3] = map(str, range(5)) #切片也支持序列解包
x [‘0’, ‘1’, ‘2’, ‘3’, ‘4’, 4, 5, 6]
序列解包遍歷多個序列
keys = [‘a’, ‘b’, ‘c’, ‘d’]
values = [1, 2, 3, 4]
for k, v in zip(keys, values): print((k, v), end=’ ')
(‘a’, 1) (‘b’, 2) (‘c’, 3) (‘d’, 4)
字符串
格式化
格式字符
說明
%s
字符串 (採用str()的顯示)
%r
字符串 (採用repr()的顯示)
%c
單個字符
%d
十進制整數
%i
十進制整數
%o
八進制整數
%x
十六進制整數
%e
指數 (基底寫爲e)
%E
指數 (基底寫爲E)
%f、%F
浮點數
%g
指數(e)或浮點數 (根據顯示長度)
%G
指數(E)或浮點數 (根據顯示長度)
%%
一個字符"%"
常用方法
find()、rfind()、index()、rindex()、count()
find()和rfind方法分別用來查找一個字符串在另一個字符串指定範圍(默認是整個字符串)中首次和最後一次出現的位置,如果不存在則返回-1;
index()和rindex()方法用來返回一個字符串在另一個字符串指定範圍中首次和最後一次出現的位置,如果不存在則拋出異常;
count()方法用來返回一個字符串在當前字符串中出現的次數。
split()、rsplit()、partition()、rpartition()
split()和rsplit()方法分別用來以指定字符爲分隔符,把當前字符串從左往右或從右往左分隔成多個字符串,並返回包含分隔結果的列表;
partition()和rpartition()用來以指定字符串爲分隔符將原字符串分隔爲3部分,即分隔符前的字符串、分隔符字符串、分隔符後的字符串,如果指定的分隔符不在原字符串中,則返回原字符串和兩個空字符串。
不推薦使用+運算符連接字符串,優先使用join()方法。
lower()、upper()、capitalize()、title()、swapcase()
s = “What is Your Name?”
s.lower() #返回小寫字符串 ‘what is your name?’
s.upper() #返回大寫字符串 ‘WHAT IS YOUR NAME?’
s.capitalize() #字符串首字符大寫 ‘What is your name?’
s.title() #每個單詞的首字母大寫 ‘What Is Your Name?’
s.swapcase() #大小寫互換 ‘wHAT IS yOUR nAME?’
查找替換replace(),類似於Word中的“全部替換”功能。
strip()、rstrip()、lstrip()
s = " abc "
s.strip() #刪除空白字符 ‘abc’
‘\n\nhello world \n\n’.strip() #刪除空白字符 ‘hello world’
“aaaassddf”.strip(“a”) #刪除指定字符 ‘ssddf’
“aaaassddf”.strip(“af”) ‘ssdd’
“aaaassddfaaa”.rstrip(“a”) #刪除字符串右端指定字符 ‘aaaassddf’
“aaaassddfaaa”.lstrip(“a”) #刪除字符串左端指定字符 ‘ssddfaaa’
s.startswith(t)、s.endswith(t),判斷字符串是否以指定字符串開始或結束
isalnum()、isalpha()、isdigit()、isdecimal()、isnumeric()、isspace()、isupper()、islower(),用來測試字符串是否爲數字或字母、是否爲字母、是否爲數字字符、是否爲空白字符、是否爲大寫字母以及是否爲小寫字母。
異常
簡單地說,異常是指程序運行時引發的錯誤,引發錯誤的原因有很多,例如除零、下標越界、文件不存在、網絡異常、類型錯誤、名字錯誤、字典鍵錯誤、磁盤空間不足,等等。 如果這些錯誤得不到正確的處理將會導致程序終止運行,而合理地使用異常處理結構可以使得程序更加健壯,具有更強的容錯性,不會因爲用戶不小心的錯誤輸入或其他運行時原因而造成程序終止。 也可以使用異常處理結構爲用戶提供更加友好的提示。 程序出現異常或錯誤之後是否能夠調試程序並快速定位和解決存在的問題也是程序員綜合水平和能力的重要體現方式之一。
可以繼承Python內置異常類來實現自定義的異常類。如果try範圍內捕獲了異常,就執行except塊;如果try範圍內沒有捕獲異常,就執行else塊。
try…except…finally結構,finally子句中的內容無論是否發生異常都會執行,常用來做一些清理工作以釋放try子句中申請的資源。
class ShortInputException(Exception):
def init(self, length, atleast):
Exception.init(self)
self.length = length
self.atleast = atleast
try:
s = input('請輸入 --> ')
if len(s) < 3:
raise ShortInputException(len(s), 3)
except ShortInputException as x:
print(‘ShortInputException: 長度是 %d, 至少應是 %d’ % (x.length, x.atleast))
else: print (‘沒有異常發生.’)
Requests 庫
中文官方文檔指引(https://2.python-requests.org//zh_CN/latest/user/quickstart.html)
pip安裝requests
pip install requests
引入包
import requests
get或post請求
不帶可選參數的get請求
r = requests.get(url=‘https://github.com/timeline.json’)
不帶可選參數的post請求
r = requests.post(url=“http://httpbin.org/post”)
其他請求(直接路過,很少很少用到,本教程也不多講)
r = requests.put(“http://httpbin.org/put”)
r = requests.delete(“http://httpbin.org/delete”)
r = requests.head(“http://httpbin.org/get”)
r = requests.options(“http://httpbin.org/get”)
1、get\post參數說明
http請求get與post是最常用的,url爲必選參數,常用常用參數有params、data、json、files、timeout、headers、cookies;其他基本用不到的有verify,cert,auth,allow_redirects,proxies,hooks,stream。
下面列表對具體的參數說明:
重點在params、data、json、files、timeout,其次headers、cookies
preview
2、get請求文本與二進制數據內容(圖片)
get請求是最簡單的、發送的數據量比較小。
示例2.1:帶多個參數的請求,返回文本數據
import requests
帶參數的GET請求,timeout請求超時時間
params = {‘key1’: ‘python’, ‘key2’: ‘java’}
r = requests.get(url=‘http://httpbin.org/get’, params=params, timeout=3)
注意觀察url地址,它已經將參數拼接起來
print(‘URL地址:’, r.url)
響應狀態碼,成功返回200,失敗40x或50x
print(‘請求狀態碼:’, r.status_code)
print(‘header信息:’, r.headers)
print(‘cookie信息:’, r.cookies)
print(‘響應的數據:’, r.text)
如響應是json數據 ,可以使用 r.json()自動轉換爲dict
print(‘響應json數據’, r.json())
示例2.2:get返回二進制數據,如圖片。
from PIL import Image
from io import BytesIO
import requests
請求獲取圖片並保存
r = requests.get(‘https://pic3.zhimg.com/247d9814fec770e2c85cc858525208b2_is.jpg’)
i = Image.open(BytesIO(r.content))
i.show() # 查看圖片
將圖片保存
with open(‘img.jpg’, ‘wb’) as fd:
for chunk in r.iter_content():
fd.write(chunk)
注意: PIL 無法使用請安裝pip install pillow
3、post請求,上傳表單,文本,文件\圖片
post請求比get複雜,請求的數據有多種多樣,有表單(form-data),文本(json\xml等),文件流(圖片\文件)等。
表單形式提交的post請求,只需要將數據傳遞給post()方法的data參數。見示例3.1.
json文本形式提交的post請求,一種方式是將json數據dumps後傳遞給data參數,另一種方式就是直接將json數據傳遞給post()方法的json參數。見示例3.2.
單個文件提交的post請求,將文件流給post()方法的files參數。見示例3.3。
多個文件提交的post請求,將文件設到一個元組的列表中,其中元組結構爲 (form_field_name, file_info);然後將數據傳遞給post()方法的files。見示例3.4.
示例3.1:post 表單請求
import requests, json
帶參數表單類型post請求
data={‘custname’: ‘woodman’,‘custtel’:‘13012345678’,‘custemail’:‘[email protected]’,
‘size’:‘small’}
r = requests.post(‘http://httpbin.org/post’, data=data)
print(‘響應數據:’, r.text)
示例3.2:post json請求
json數據請求
url = ‘https://api.github.com/some/endpoint’
payload = {‘some’: ‘data’}
可以使用json.dumps(dict) 對編碼進行編譯
r = requests.post(url, data=json.dumps(payload))
print(‘響應數據:’, r.text)
可以直接使用json參數傳遞json數據
r = requests.post(url, json=payload)
print(‘響應數據:’, r.text)
示例3.3:post提交單個文件
上傳單個文件
url = ‘http://httpbin.org/post’
注意文件打開的模式,使用二進制模式不容易發生錯誤
files = {‘file’: open(‘report.txt’, ‘rb’)}
也可以顯式地設置文件名,文件類型和請求頭
files = {‘file’: (‘report.xls’, open(‘report.xls’, ‘rb’), ‘application/vnd.ms-excel’, {‘Expires’: ‘0’})}
r = requests.post(url, files=files)
r.encoding = ‘utf-8’
print(r.text)
注意:文件的上傳使用二進制打開不容易報錯。
示例3.4:上傳多個文件
url = ‘http://httpbin.org/post’
multiple_files = [
(‘images’, (‘foo.png’, open(‘foo.png’, ‘rb’), ‘image/png’)),
(‘images’, (‘bar.png’, open(‘bar.png’, ‘rb’), ‘image/png’))]
r = requests.post(url, files=multiple_files)
print(r.text)
示例3.5:拓展,將字符串作爲文件上傳
可以把字符串當着文件進行上傳,只能用顯示設置文件名上傳
url = ‘http://httpbin.org/post’
files = {‘file’: (‘report.csv’, ‘some,data,to,send\nanother,row,to,send\n’)}
r = requests.post(url, files=files)
print(r.text)
4、get與post請求的header與cookie管理
獲取get與post請求響應的header與cookie分別使用r.headers與r.cookies。如果提交請求數據是對header與cookie有修改,需要在get()與post()方法中加入headers或cookies參數,它們值的類型都是字典。
示例4.1:定製請求頭header
import requests
url = ‘https://api.github.com/some/endpoint’
headers = {‘user-agent’: ‘my-app/0.0.1’}
r = requests.get(url, headers=headers)
print(r.headers) # 獲取響應數據的header信息
注意:requests自帶headers管理,一般情況下不需要設置header信息。Requests 不會基於定製 header 的具體情況改變自己的行爲。只不過在最後的請求中,所有的 header 信息都會被傳遞進去。
示例4.2:定製cookie信息
直接以字典型時傳遞cookie
url = ‘http://httpbin.org/cookies’
cookies = {“cookies_are”:‘working’}
r = requests.get(url, cookies=cookies)
獲取響應的cookie信息,返回結果是RequestsCookieJar對象
print(r.cookies)
print(r.text)
import requests.cookies
我們也可以使用 RequestsCookieJar 對象提交cookies信息
jar = requests.cookies.RequestsCookieJar()
jar.set(‘tasty_cookie’, ‘yum’, domain=‘httpbin.org’, path=’/cookies’)
jar.set(‘gross_cookie’, ‘blech’, domain=‘httpbin.org’, path=’/elsewhere’)
url = ‘http://httpbin.org/cookies’
r = requests.get(url, cookies=jar)
print(r.text)
注意:RequestsCookieJar傳遞cookies信息,它的行爲和字典類似,它非常適合跨域名跨路徑使用。
5、session與cookie存儲
如果你向同一主機發送多個請求,每個請求對象讓你能夠跨請求保持session和cookie信息,這時我們要使用到requests的Session()來保持回話請求的cookie和session與服務器的相一致。
示例5.1:創建一個session會話:
s = requests.Session()
session會話的get與post請求
不帶可選參數的get請求
r = s.get(url=‘https://github.com/timeline.json’)
不帶可選參數的post請求
r = s.post(url=“http://httpbin.org/post”)
session會話對象的get與post請求參數與requests()的get與post請求參數一致。
session會話還可以用作with前後文管理器:
示例5.2:
with requests.Session() as s:
s.get(‘http://httpbin.org/cookies/set/sessioncookie/123456789’)
這樣能確保 with 區塊退出後會話能被關閉,即使發生了異常也一樣。
requests的session會話需要注意的是會話方法級別的參數也不會被跨請求保持。
如下示例5.3:
s = requests.Session()
r = s.get(‘http://httpbin.org/cookies’, cookies={‘from-my’: ‘browser’})
print(r.text)
‘{“cookies”: {“from-my”: “browser”}}’
r = s.get(‘http://httpbin.org/cookies’)
print(r.text)
‘{“cookies”: {}}’
第一個get請求中加入方法級別cookies參數,在第二個get請求中不會保持第一個get請求的cookies參數。
6、requests請求返回對象Response的常用方法
requests.get(url)與requests.post(url)的返回對象爲Response 類對象。
Response響應類常用屬性與方法:
Response.url 請求url,[見示例2.1]
Response.status_code 響應狀態碼,[見示例2.1]
Response.text 獲取響應內容,[見示例2.1]
Response.json() 活動響應的JSON內容,[見示例2.1]
Response.ok 請求是否成功,status_code<400 返回True
Response.headers 響應header信息,[見示例2.1]
Response.cookies 響應的cookie,[見示例2.1]
Response.elapsed 請求響應的時間。
Response.links 返回響應頭部的links連接,相當於Response.headers.get(‘link’)
Response.raw 獲取原始套接字響應,需要將初始請求參數stream=True
Response.content 以字節形式獲取響應提,多用於非文本請求,[見示例2.2]
Response.iter_content() 迭代獲取響應數據,[見示例2.2]
Response.history 重定向請求歷史記錄
Response.reason 響應狀態的文本原因,如:“Not Found” or “OK”
Response.close() 關閉並釋放鏈接,釋放後不能再次訪問’raw’對象。一般不會調用。
示例5.1:
import requests
r = requests.get(‘http://github.com’, stream=True)
print(‘狀態碼:’,r.status_code)
print(‘請求是否成功:’,r.ok)
print(‘響應提文本內容:’,r.reason)
print(‘重定向歷史:’,r.history)
print(‘header的link:’,r.links)
print(‘響應時長:’,r.elapsed)
r.raw 獲取到內容,請求時將stream設爲True
print(‘原始套接字響應:’,r.raw)
print(‘原始套接字響應:’,r.raw.read())
Python DB API
文件操作
用於文件內容讀寫時,with語句的用法如下:
with open(filename, mode, encoding) as fp: #這裏寫通過文件對象fp讀寫文件內容的語句
另外,上下文管理語句with還支持下面的用法,進一步簡化了代碼的編寫:
with open(‘test.txt’, ‘r’) as src, open(‘test_new.txt’, ‘w’) as dst:
dst.write(src.read())
文件打開方式
模式
說明
r
讀模式(默認模式,可省略),如果文件不存在則拋出異常
w
寫模式,如果文件已存在,先清空原有內容
x
寫模式,創建新文件,如果文件已存在則拋出異常
a
追加模式,不覆蓋文件中原有內容
b
二進制模式(可與其他模式組合使用)
t
文本模式(默認模式,可省略)
讀、寫模式(可與其他模式組合使用)
文件對象常用屬性
方法
功能說明
close()
把緩衝區的內容寫入文件,同時關閉文件,並釋放文件對象
detach()
分離並返回底層的緩衝,底層緩衝被分離後,文件對象不再可用,不允許做任何操作
flush()
把緩衝區的內容寫入文件,但不關閉文件
read([size])
從文本文件中讀取size個字符(Python 3.x)的內容作爲結果返回,或從二進制文件中讀取指定數量的字節並返回,如果省略size則表示讀取所有內容
readable()
測試當前文件是否可讀
readline()
從文本文件中讀取一行內容作爲結果返回
readlines()
把文本文件中的每行文本作爲一個字符串存入列表中,返回該列表,對於大文件會佔用較多內存,不建議使用
seek(offset[, whence])
把文件指針移動到新的位置,offset表示相對於whence的位置。whence爲0表示從文件頭開始計算,1表示從當前位置開始計算,2表示從文件尾開始計算,默認爲0
seekable()
測試當前文件是否支持隨機訪問,如果文件不支持隨機訪問,則調用方法seek()、tell()和truncate()時會拋出異常
tell()
返回文件指針的當前位置
truncate([size])
刪除從當前指針位置到文件末尾的內容。如果指定了size,則不論指針在什麼位置都只留下前size個字節,其餘的一律刪除
write(s)
把s的內容寫入文件
writable()
測試當前文件是否可寫
writelines(s)
把字符串列表寫入文本文件,不添加換行符