一·input和raw_input
input()輸入嚴(yán)格按照Python的語法宴霸,是字符就加 ' ' ,數(shù)字就是數(shù)字蟹地,并且input()可以接收一個Python表達(dá)式作為輸入贯莺,并將運(yùn)算結(jié)果返回。
raw_input()隨便輸都是字符串柱衔,會從標(biāo)準(zhǔn)輸入(sys.stdin)讀取一個輸入并返回一個字符串樊破,且尾部的換行符從末尾移除。
測試代碼如下:
x1 = input('input number:')
x2 = input('input string:')
print type(x1),type(x2)
x3 = raw_input('raw_input number:')
x4 = raw_input('raw_input string:')
print type(x3),type(x4)
x5 = input('input [x*2 for x in range(5)]:')
x6 = raw_input('raw_input [x*2 for x in range(5)]:')
print x5,x6
x7 = input('input "[x*2 for x in range(5)]":')
x8 = raw_input('raw_input "[x*2 for x in range(5)]":')
print x7,x8
運(yùn)行結(jié)果:
二·文件讀寫
1.open(file_name [, access_mode][, buffering])
filename:如果只只傳入這一參數(shù)秀存,文件不存在時會返回一個錯誤捶码。
access_mode:決定了打開文件的模式:只讀,寫入或链,追加等,這個參數(shù)是非強(qiáng)制的,默認(rèn)文件訪問模式為只讀(r)
buffering:為0档押,I/O操作為無緩沖澳盐,直接寫入磁盤祈纯,為1,有緩沖叼耙,先寫到內(nèi)存腕窥,在調(diào)用flush和close時更新到磁盤,大于1筛婉,表示緩沖區(qū)的大小(單位:字節(jié))簇爆,-1為使用默認(rèn)緩沖區(qū)大小。
為了避免在打開文件時產(chǎn)生IO error爽撒,以及提高代碼的健壯性入蛆,可將打開文件代碼寫為:
with open(r'../test.txt','w+') as f:
f.write(‘......’)
打開文件,讀寫完畢后要調(diào)用close關(guān)閉釋放資源硕勿,避免浪費(fèi)有限的IO資源哨毁。
下面是幾種常用mode對應(yīng)的文件權(quán)限圖:
2.文件讀取,可以采用read()和readlines()一次性將文件全部讀入內(nèi)存中源武,文件太大時扼褪,應(yīng)采用read(size)和readline()的方式進(jìn)行讀取。(但readline()不能輸出指定行粱栖』敖剑可使用text = linecache.getline(filename, 2)來讀取指定行)。此外還可以通過迭代文件的方式讀取(文件也是個可迭代對象):
with open(filename, 'r') as flie:
for line in file:
....
3.文件寫入
使用write寫入字符串闹究,但不可寫入可迭代對象凳枝,而writelines則相反。
三.操作文件和目錄
在 Python中對文件和目錄的操作經(jīng)常用到os模塊和 shutil模塊跋核。接下來主要介紹一些操作文件和目錄的常用方法:
獲得當(dāng)前 Python腳本工作的目錄路徑: os.getcwd岖瑰。
返回指定目錄下的所有文件和目錄名: os.listdir()。
例如返回C盤下的文件os.listdir("C: \")
刪除一個文件: os.remove(filepath)
刪除多個空目錄: os.removedirs(r"d:\python")
檢驗(yàn)給出的路徑是否是一個文件: os.path.isfile( filepath)
檢驗(yàn)給出的路徑是否是一個目錄: os.path.isdir( filepath)
判斷是否是絕對路徑: os.path.isabs()砂代。
檢驗(yàn)路徑是否真的存在: os.path.exists()蹋订。例如檢測D盤下是否有 Python文件夾os.path.exists(r"d: \ python")
分離一個路徑的目錄名和文件名: os.path. split()。例如:
os.path.split(r" home/qiye/qiye. txt")刻伊,返回結(jié)果是一個元組:('home/qiye','qiye.txt')
分離擴(kuò)展名: os path.splitext()露戒。例如 os.path. splite(r"/home/ /qiye/qiye.txt"),返回結(jié)果
是一個元組:('/home/ qiye/qiye','.txt')
獲取路徑名: os.path.dirname( filetpath)
獲取文件名: os.path.basename( filepath)
讀取和設(shè)置環(huán)境變量: os.getenv()與 os.putenv()捶箱。
給出當(dāng)前平臺使用的行終止符: os.linesep(),Windows使用"\r\n'智什, Linux使用'\n'而Mac使用'\r'
指示你正在使用的平臺:os.name對于 Windows,它是nt丁屎,而對于 Linux/Unix用戶,它是'posix'荠锭。
重命名文件或者目錄: os.rename( old, new).
創(chuàng)建多級目錄: os.makedirs(r"c:\Python\test")。
創(chuàng)建單個目錄: os.mkdir("test")
獲取文件屬性: os.stat(file)
修改文件權(quán)限與時間戳: os.chmod(file)
獲取文件大谐看ā: os.path.getsize(filename)
復(fù)制文件夾: shutil.copytree(" olddir"," newdir") o olddir和 newdir都只能是目錄证九,且 newdir
必須不存在删豺。
復(fù)制文件: shutil.copyfile(" oldfile"," newfile"), oldfile和 newfile都只能是文件愧怜; shutil
copy("oldfile"," newfile"), oldfile只能是文件呀页, newfile可以是文件,也可以是目標(biāo)目錄拥坛。
移動文件(目錄): shutil.move("oldpos"," nepos").
刪除目錄: os.rmdir("dir")蓬蝶,只能刪除空目錄;
shutil.rmtree("dir"),空目錄猜惋、有內(nèi)容的
目錄都可以刪.
四.字符編碼
字符編碼
要讀取非UTF-8編碼的文本文件丸氛,需要給open()函數(shù)傳入encoding參數(shù),例如惨奕,讀取GBK編碼的文件:
>>> f = open('test.txt', 'r', encoding='gbk')
>>> f.read()
遇到有些編碼不規(guī)范的文件雪位,你可能會遇到UnicodeDecodeError,因?yàn)樵谖谋疚募锌赡軍A雜了一些非法編碼的字符梨撞。遇到這種情況雹洗,open()函數(shù)還接收一個errors參數(shù),表示如果遇到編碼錯誤后如何處理卧波。最簡單的方式是直接忽略:
>>> f = open('test.txt', 'r', encoding='gbk', errors='ignore')
五.序列化與反序列化
可從這查看原文 廖雪峰-序列化
把變量從內(nèi)存中變成可存儲或傳輸?shù)倪^程稱之為序列化时肿,在Python中叫pickling,在其他語言中也被稱之為serialization港粱,marshalling螃成,flattening等等,都是一個意思查坪。
序列化之后寸宏,就可以把序列化后的內(nèi)容寫入磁盤,或者通過網(wǎng)絡(luò)傳輸?shù)絼e的機(jī)器上偿曙。
反過來氮凝,把變量內(nèi)容從序列化的對象重新讀到內(nèi)存里稱之為反序列化,即unpickling望忆。
Python提供兩個模塊來實(shí)現(xiàn)序列化:cPickle和pickle罩阵。這兩個模塊功能是一樣的,區(qū)別在于cPickle是C語言寫的启摄,速度快稿壁,pickle是純Python寫的,速度慢歉备,跟cStringIO和StringIO一個道理傅是。用的時候,先嘗試導(dǎo)入cPickle,如果失敗落午,再導(dǎo)入pickle:
try:
import cPickle as pickle
except ImportError:
import pickle
兩個例子:
>>> d = dict(name='Bob', age=20, score=88)
>>> pickle.dumps(d)
"(dp0\nS'age'\np1\nI20\nsS'score'\np2\nI88\nsS'name'\np3\nS'Bob'\np4\ns."
pickle.dumps()方法把任意對象序列化成一個str谎懦,然后肚豺,就可以把這個str寫入文件溃斋。或者用另一個方法pickle.dump()直接把對象序列化后寫入一個file-like Object:
>>> f = open('dump.txt', 'wb')
>>> pickle.dump(d, f)
>>> f.close()
看看寫入的dump.txt文件吸申,一堆亂七八糟的內(nèi)容梗劫,這些都是Python保存的對象內(nèi)部信息。
當(dāng)我們要把對象從磁盤讀到內(nèi)存時截碴,可以先把內(nèi)容讀到一個str梳侨,然后用pickle.loads()方法反序列化出對象,也可以直接用pickle.load()方法從一個file-like Object中直接反序列化出對象日丹。我們打開另一個Python命令行來反序列化剛才保存的對象:
>>> f = open('dump.txt', 'rb')
>>> d = pickle.load(f)
>>> f.close()
>>> d
{'age': 20, 'score': 88, 'name': 'Bob'}
當(dāng)然走哺,這個變量和原來的變量是完全不相干的對象,它們只是內(nèi)容相同而已哲虾。
Pickle的問題和所有其他編程語言特有的序列化問題一樣丙躏,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容束凑,因此晒旅,只能用Pickle保存那些不重要的數(shù)據(jù),不能成功地反序列化也沒關(guān)系汪诉。
JSON
要在不同的編程語言之間傳遞對象废恋,就必須把對象序列化為標(biāo)準(zhǔn)格式,比如XML扒寄,但更好的方法是序列化為JSON鱼鼓,因?yàn)镴SON表示出來就是一個字符串,可以被所有語言讀取该编,也可以方便地存儲到磁盤或者通過網(wǎng)絡(luò)傳輸迄本。JSON不僅是標(biāo)準(zhǔn)格式,并且比XML更快上渴,而且可以直接在Web頁面中讀取岸梨,非常方便。
JSON表示的對象就是標(biāo)準(zhǔn)的JavaScript語言的對象稠氮,JSON和Python內(nèi)置的數(shù)據(jù)類型對應(yīng)如下:
JSON類型?????Python類型
?{}??????dict
?[]??????list
"string"??'str'或u'unicode'
1234.56????int或float
true/false??True/False
?null?????None
Python內(nèi)置的json模塊提供了非常完善的Python對象到JSON格式的轉(zhuǎn)換:
>>> import json
>>> d = dict(name='Bob', age=20, score=88)
>>> json.dumps(d)
'{"age": 20, "score": 88, "name": "Bob"}'
dumps()方法返回一個str曹阔,內(nèi)容就是標(biāo)準(zhǔn)的JSON。類似的隔披,dump()方法可以直接把JSON寫入一個file-like Object赃份。
要把JSON反序列化為Python對象,用loads()或者對應(yīng)的load()方法,前者把JSON的字符串反序列化抓韩,后者從file-like Object中讀取字符串并反序列化:
>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'
>>> json.loads(json_str)
{u'age': 20, u'score': 88, u'name': u'Bob'}
有一點(diǎn)需要注意纠永,就是反序列化得到的所有字符串對象默認(rèn)都是unicode而不是str。由于JSON標(biāo)準(zhǔn)規(guī)定JSON編碼是UTF-8谒拴,所以我們總是能正確地在Python的str或unicode與JSON的字符串之間轉(zhuǎn)換尝江。
JSON進(jìn)階
對Python的類如定義Student
類,進(jìn)行序列化:
import json
class Student(object):
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
s = Student('Bob', 20, 88)
print(json.dumps(s))
運(yùn)行代碼英上,毫不留情地得到一個TypeError
:
Traceback (most recent call last):
...
TypeError: <__main__.Student object at 0x10aabef50> is not JSON serializable
錯誤的原因是Student
對象不是一個可序列化為JSON的對象炭序。
仔細(xì)看看dumps()
方法的參數(shù)列表,可以發(fā)現(xiàn)苍日,除了第一個必須的obj
參數(shù)外惭聂,dumps()
方法還提供了一大堆的可選參數(shù):
https://docs.python.org/2/library/json.html#json.dumps
這些可選參數(shù)就是讓我們來定制JSON序列化。前面的代碼之所以無法把Student
類實(shí)例序列化為JSON相恃,是因?yàn)槟J(rèn)情況下辜纲,dumps()
方法不知道如何將Student
實(shí)例變?yōu)橐粋€JSON的{}
對象。
可選參數(shù)default
就是把任意一個對象變成一個可序列為JSON的對象拦耐,我們只需要為Student
專門寫一個轉(zhuǎn)換函數(shù)耕腾,再把函數(shù)傳進(jìn)去即可:
def student2dict(std):
return {
'name': std.name,
'age': std.age,
'score': std.score
}
print(json.dumps(s, default=student2dict))
這樣,Student
實(shí)例首先被student2dict()
函數(shù)轉(zhuǎn)換成dict
揩魂,然后再被順利序列化為JSON幽邓。
不過悉抵,下次如果遇到一個Teacher
類的實(shí)例殖熟,照樣無法序列化為JSON。我們可以偷個懶家肯,把任意class
的實(shí)例變?yōu)?code>dict:
print(json.dumps(s, default=lambda obj: obj.__dict__))
同樣的道理倦挂,如果我們要把JSON反序列化為一個Student
對象實(shí)例畸颅,loads()
方法首先轉(zhuǎn)換出一個dict
對象,然后方援,我們傳入的object_hook
函數(shù)負(fù)責(zé)把dict
轉(zhuǎn)換為Student
實(shí)例:
def dict2student(d):
return Student(d['name'], d['age'], d['score'])
json_str = '{"age": 20, "score": 88, "name": "Bob"}'
print(json.loads(json_str, object_hook=dict2student))
運(yùn)行結(jié)果如下:
<__main__.Student object at 0x10cd3c190>
打印出的是反序列化的Student
實(shí)例對象没炒。
小結(jié)
Python語言特定的序列化模塊是pickle
,但如果要把序列化搞得更通用犯戏、更符合Web標(biāo)準(zhǔn)送火,就可以使用json
模塊。