主要是想通過python之流的腳本語言來進行文件系統的遍歷,處理文本以及使用簡易數據庫的操作。
本文基於陳皓的:《程序員技術練級攻略》
一.Python csv
對於電子表格和數據庫導出文件,比較常見的文件格式是.csv,所以python中的csv模塊也是一個比較重要的模塊。下面介紹csv常用的方法。
1.csv.reader(csvfile, dialect='excel', **fmtparams)
- 該函數返回一個reader對象,能夠以行遍歷的形式遍歷行里面的數據。
- csvfile——需要是支持迭代(Iterator)的對象,並且每次調用next方法的返回值是字符串(string),通常的文件(file)對象,或者列表(list)對象都是適用的,如果是文件對象,打開是需要加"b"標志參數。
- dialect——編碼風格,默認為excel方式,也就是逗號(,)分隔,另外csv模塊也支持excel-tab風格,也就是制表符(tab)分隔。其它的方式需要自己 定義,然后可以調用register_dialect方法來注冊,以及list_dialects方法來查詢已注冊的所有編碼風格列表。
- fmtparams——格式化參數,用來覆蓋之前dialect對象指定的編碼風格
看一下示例:
#!/usr/bin/env python #-*- coding:utf-8 -*- import csv #定義一個字符串 st = "I am a student." #定義列表,注意csv只接受以ACSII編碼的字符串序列 li = [1,2,3,4,5] #不符合要求 lis = ['a','b','c'] reader1 = csv.reader(st) for line in reader1: print line, #['I'] [' '] ['a'] ['m'] [' '] ['a'] [' '] ['s'] ['t'] ['u'] ['d'] ['e'] ['n'] ['t'] ['.'] print '\n'+str(reader1.line_num) #輸出行數 reader2 = csv.reader(lis) for line in reader2: print line, #打開文件對象 with open ('./egg.csv','rb') as csvfile: reader3 = csv.reader(csvfile) for row in reader3: print row,
對於每個line或row支持next,dialect,fieldnames,line_num方法。
2.csv.writer(csvfile, dialect='excel', **fmtparams)
參數表同上,注意在建立了writer對象之后,要通過writerow寫入一行,而通過writerows寫入多行。
#!/usr/bin/env python #-*- coding:utf-8 -*- import csv #注:with語句有兩個作用:1.關閉文件句柄;2.更好的處理異常 with open('./egg.csv','wb') as csvfile: #注:w是重新覆蓋,a是直接追加 writer = csv.writer(csvfile) writer.writerow(['姓名','年齡','電話']) data = [('何輝宇','21','1234'),('何輝寧','21','5678')] writer.writerows(data)
3.dialect
csv
模組巧妙地運用 dialect 的概念,將不同應用程式對 CSV 處理方式上的差異隱藏起來。
這裡的差異指的是欄位分隔字元(delimiter)跟識別資料內容的引號(quoting character)等。目前 csv
模組內建兩種 dialect - excel
(.csv
) 及 excel-tab
(.tsv
),可以用來讀取 Excel 寫出、或是寫出 Excel 可以讀取的檔案格式,而不用去管 Excel 慣用的格式為何。
4.class csv.DictReader(csvfile, fieldnames=None, restkey=None, restval=None, dialect='excel', *args, **kwds)
跟reader差不多,只不過是以字典形式呈現。
#!/usr/bin/env python #-*- coding:utf-8 -*- import csv with open('./egg.csv','rb') as csvfile: reader = csv.DictReader(csvfile) for line in reader: print line,
結果:
dzhwen@deng:~/python文件/csv$ python dictreader.py {'\xe7\x94\xb5\xe8\xaf\x9d': '1234', '\xe5\xb9\xb4\xe9\xbe\x84': '21', '\xe5\xa7\x93\xe5\x90\x8d': '\xe4\xbd\x95\xe8\xbe\x89\xe5\xae\x87'} {'\xe7\x94\xb5\xe8\xaf\x9d': '5678', '\xe5\xb9\xb4\xe9\xbe\x84': '21', '\xe5\xa7\x93\xe5\x90\x8d': '\xe4\xbd\x95\xe8\xbe\x89\xe5\xae\x81'}
5.class csv.DictWriter(csvfile, fieldnames, restval='', extrasaction='raise', dialect='excel', *args, **kwds)
與之類似。
二.Python open
1.內建函數open()
file_object = open(file_name,access_mode = 'r',buffering = -1)
文件對象的訪問模式:
- r——讀方式
- w——寫方式
- a——追加模式
- r+,w+,a+——以讀寫模式打開
- rb,wb,ab——以二進制模式讀寫追加
- rb+,wb+,ab+——以二進制讀寫模式打開
2.工廠函數file()
open()和file()函數具有相同的功能,可以任意替換。您所看到任何使用open()的地方,都可以使用file()替換它。
3.輸入/輸出
read(size),readline(),readlines(),write()
4.文件內移動
- file.seek(off,whence=0)——在文件中移動文件指針,從whence(0代表文件起始,1代表當前位置,2代表文件末尾)偏移off字節。
- file.tell()——返回當前在文件中的位置
5.文件迭代
for eachLine in f:
pass
6.其他
- file.close() —— 關閉文件
- file.fileno() —— 返回文件的描述符(file descriptor,FD,整型值)
- file.flush() —— 直接把內部緩沖區中的數據立刻寫入文件,而不是被動地等待輸出緩沖區被寫入。
三.Python sys
sys模塊中的函數非常多,挑幾個有用的來講講。
1.sys.argv —— 對命令行參數的訪問
- sys.argv是命令行參數的列表
- len(sys.argv) 是命令行參數個數(也就是argc)
2.sys.platform() —— 輸出平台信息
>>> import sys >>> sys.platform 'linux2'
實現一個清除終端,linux下用clear,windows下用cls
#!/usr/bin/env python #-*- coding:utf-8 -*- import sys ostype = sys.platform() if ostype == "linux" or ostype == "linux2": cmd = "clear" else: cmd = "cls"
3.sys.exit(n)
執行至主程序的末尾時,解釋器會自動退出. 但是如果需要中途退出程序, 你可以調用sys.exit 函數, 它帶有一個可選的整數參數返回給調用它的程序. 這意味着你可以在主程序中捕獲對sys.exit 的調用。(注:0是正常退出,其他為不正常,可拋異常事件供捕獲!)(相當與C++的return函數)
#!/usr/bin/env python #-*- coding:utf-8 -*- import sys def exitfunc(value): print value sys.exit(0) print "hello" try: sys.exit(1) except SystemExit,value: exitfunc(value) print "come?
4.sys.path —— 與程序有關的執行路徑
>>> import sys >>> sys.path ['', '/usr/local/lib/python2.7/dist-packages/tornado-1.2.1-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/uWSGI-2.0.3-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/python_memcached-1.53-py2.7.egg', '/usr/local/lib/python2.7/dist-packages/protobuf-2.5.0-py2.7.egg', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/usr/lib/python2.7/dist-packages/gst-0.10', '/usr/lib/python2.7/dist-packages/gtk-2.0', '/usr/lib/pymodules/python2.7', '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']
添加模塊路徑:
sys.path.append(“mine module path”).
5.sys.modules —— python的所有模塊
使用方法:
>>> sys.modules
常用方法:
for names in sys.modules.keys(): if names != ’sys’: pass
5.sys.stdin,stdout,stderr —— 標准輸入輸出,錯誤輸出
標准輸入和標准錯誤 (通常縮寫為 stdout 和 stderr) 是內建在每一個 UNIX 系統中的管道。
當你 print 某些東西時,結果前往 stdout 管道;
當你的程序崩潰並打印出調試信息 (例如 Python 中的 traceback (錯誤跟蹤)) 的時候,信息前往 stderr 管道。
- stdout 是一個類文件對象;調用它的 write 函數可以打印出你給定的任何字符串。
- 實際上,這就是 print 函數真正做的事情;它在你打印的字符串后面加上一個硬回車,然后調用 sys.stdout.write 函數。在最簡單的例子中,stdout 和 stderr 把它們的輸出發送到相同的地方。
- 和 stdout 一樣,stderr 並不為你添加硬回車;如果需要,要自己加上。
-
stdout 和 stderr 都是類文件對象,但是它們都是只寫的。它們都沒有 read 方法,只有 write 方法。然而,它們仍然是類文件對象,因此你可以將其它任何 (類) 文件對象賦值給它們來重定向其輸出。
>>> import sys >>> for i in range(3): ... print 'Hello!' ... Hello! Hello! Hello! >>> for i in range(3): ... sys.stdout.write('Hello!') ... Hello!Hello!Hello! >>> for i in range(3): ... sys.stderr.write('Hello!') ... Hello!Hello!Hello!
使用sys重定向輸出
#!/usr/bin/env python #-*- coding:utf-8 -*- import sys print 'Dive in' # 標准輸出 saveout = sys.stdout # 終在重定向前保存stdout,這樣的話之后你還可以將其設回正常 fsock = open('out.log', 'w') # 打開一個新文件用於寫入。如果文件不存在,將會被創建。如果文件存在,將被覆蓋。 sys.stdout = fsock # 所有后續的輸出都會被重定向到剛才打開的新文件上。 print 'This message will be logged instead of displayed' # 這樣只會將輸出結果“打印”到日志文件中;屏幕上不會看到輸出 sys.stdout = saveout # 在我們將 stdout 搞亂之前,讓我們把它設回原來的方式。 fsock.close() # 關閉日志文件。
使用sys.stdin讀取
>>> r = sys.stdin.readline() sasasa >>> r 'sasasa\n'
重定向錯誤信息
fsock = open('error.log', 'w') # 打開你要存儲調試信息的日志文件。 sys.stderr = fsock # 將新打開的日志文件的文件對象賦值給stderr以重定向標准錯誤。 raise Exception, 'this error will be logged' # 引發一個異常,沒有在屏幕上打印出任何東西,所有正常的跟蹤信息已經寫進error.log #還要注意你既沒有顯式關閉日志文件,也沒有將 stderr 設回最初的值。 #這樣挺好,因為一旦程序崩潰 (由於引發的異常),Python 將替我們清理並關閉文件
打印到 stderr——向標准錯誤寫入錯誤信息是很常見的,所以有一種較快的語法可以立刻導出信息
>>> print 'entering function' entering function >>> import sys >>> print >> sys.stderr, 'entering function' entering function
print 語句的快捷語法可以用於寫入任何打開的文件 (或者是類文件對象)。
在這里,你可以將單個print語句重定向到stderr而且不用影響后面的print語句。
四.Python os,path
os 模塊的文件/目錄訪問函數
文件處理
- mkfifo()/mknod() —— 創建命名管道/創建文件系統節點
- remove()/unlink() —— 刪除文件
- rename()/renames() —— 重命名文件
- stat() —— 返回文件信息
- symlink() —— 創建符號鏈接
- utime() —— 更新時間戳
- tmpfile() —— 創建並打開('w'+'b')一個新的臨時文件
- walk() —— 生成一個目錄樹下的所有文件名
目錄/文件夾
- chdir() —— 改變當前工作目錄
- chroot() —— 改變當前進程的根目錄
- listdir() —— 列出指定目錄的文件
- getcwd() —— 返回當前工作目錄
- mkdir()/makedirs() —— 創建目錄/創建多層目錄
- rmdir()/removedirs() —— 刪除目錄/刪除多層目錄
訪問/權限
- access() —— 檢驗權限模式
- chmod() —— 改變權限模式
- chown() —— 改變owner和GID,但不會跟蹤鏈接
- umask() —— 設置默認權限模式
文件描述符操作
- open() —— 打開文件
- read() / write() —— 讀取/寫入文件
os.path 模塊的文件/目錄訪問函數
分隔
- basename() —— 去掉目錄路徑,返回文件名
- dirname() —— 去掉文件名,返回目錄路徑
- join() —— 將分離的各部分組合成一個路徑名
- split() —— 返回(dirname(),basename())元組
- splitdrive() —— 返回(drivename,pathname)元組
- splitext —— 返回(filename,extension)元組
信息
- getatime() —— 返回最近訪問時間
- getctime() —— 返回文件創建時間
- getmtime() —— 返回最近文件修改時間
- getsize() —— 返回文件大小(以字節為單位)
查詢
- exists() —— 指定路徑(文件或目錄)是否存在
- isabs() —— 指定路徑是否為絕對路徑
- isdir() —— 指定路徑是否存在且為一個目錄
- isfile() —— 指定路徑是否存在且為一個文件
- islink() —— 指定路徑是否存在且為一個符號鏈接
- ismount —— 指定路徑是否存在且為一個掛載點
- samefile —— 兩個路徑名是否指向同一個文件
五.Python sqlite
Sqllite是一個小巧的內嵌型數據庫,也就是說沒有獨立的維護進程。
1.導入模塊
>>> import sqlite3
2. 創建/打開數據庫
可以打開數據庫:
cx = sqlite3.connect('./test.db')
也可以存在內存當中:
con = sqlite3.connect(":memory:")
3.數據庫連接對象
打開數據庫時返回的對象cx就是一個數據庫連接對象,它可以有以下操作:
- commit()--事務提交
- rollback()--事務回滾
- close()--關閉一個數據庫連接
- cursor()--創建一個游標
關於commit(),如果isolation_level隔離級別默認,那么每次對數據庫的操作,都需要使用該命令,你也可以設置isolation_level=None,這樣就變為自動提交模式。
4.使用游標查詢數據庫cu = cx.cursor()
游標對象有以下的操作:
- execute()--執行sql語句
- executemany--執行多條sql語句
- close()--關閉游標
- fetchone()--從結果中取一條記錄,並將游標指向下一條記錄
- fetchmany()--從結果中取多條記錄
- fetchall()--從結果中取出所有記錄
- scroll()--游標滾動
5.建表
>>> cu.execute('Create Table users(login varchar(8),uid integer)') <sqlite3.Cursor object at 0xb71db5e0>
6.插入數據
>>> cu.execute('Insert into users values("join",100)') <sqlite3.Cursor object at 0xb71db5e0>
請注意避免以下寫法:
# Never do this -- insecure 會導致注入攻擊 pid=200 c.execute("... where pid = '%s'" % pid)
正確的做法如下,如果t只是單個數值,也要采用t=(n,)的形式,因為元組是不可變的。
for t in[(0,10,'abc','Yu'),(1,20,'cba','Xu')]: cx.execute("insert into catalog values (?,?,?,?)", t)
簡單的插入兩行數據,不過需要提醒的是,只有提交了之后,才能生效.我們使用數據庫連接對象cx來進行提交commit和回滾rollback操作.
>>> cx.commit()
7.查詢
>>> cu.execute('Select * From Users') <sqlite3.Cursor object at 0xb71db5e0> >>> for eachUser in cu.fetchall(): ... print eachUser ... (u'join', 100) (u'jane', 110)
8.修改
>>> cu.execute('Update Users set login="Betty" where uid = 110') <sqlite3.Cursor object at 0xb71db5e0> >>> cu.execute('Select * From Users') <sqlite3.Cursor object at 0xb71db5e0> >>> for eachUser in cu.fetchall(): ... print eachUser ... (u'join', 100) (u'Betty', 110)
>>> cx.commit()
9.刪除
>>> cu.execute('Delete from Users where uid = 110') <sqlite3.Cursor object at 0xb71db5e0> >>> cu.execute('Select * From Users') <sqlite3.Cursor object at 0xb71db5e0> >>> for eachUser in cu.fetchall(): ... print eachUser ... (u'join', 100) >>> cx.commit()
10.單獨取一行
>>> cu.execute('Select * From Users') <sqlite3.Cursor object at 0xb71db5e0> >>> r = cu.fetchone() >>> type(r) <type 'tuple'> >>> r (u'join', 100) >>> r[0] u'join' >>> r[1] 100
代碼匯總:
>>> import sqlite3 >>> cx = sqlite3.connect('./test.db') >>> cu = cx.cursor() >>> cu.execute('Create Table users(login varchar(8),uid integer)') <sqlite3.Cursor object at 0xb71db5e0> >>> cu.execute('Insert into users values("join",100)') <sqlite3.Cursor object at 0xb71db5e0> >>> cu.execute('Insert into users values("jane",110)') <sqlite3.Cursor object at 0xb71db5e0> >>> cx.commit() >>> cu.execute('Select * From Users') <sqlite3.Cursor object at 0xb71db5e0> >>> for eachUser in cu.fetchall(): ... print eachUser ... (u'join', 100) (u'jane', 110) >>> cu.execute('Update Users set login="Betty" where uid = 110') <sqlite3.Cursor object at 0xb71db5e0> >>> cu.execute('Select * From Users') <sqlite3.Cursor object at 0xb71db5e0> >>> for eachUser in cu.fetchall(): ... print eachUser ... (u'join', 100) (u'Betty', 110) >>> cx.commit() >>> cu.execute('Delete from Users where uid = 110') <sqlite3.Cursor object at 0xb71db5e0> >>> cu.execute('Select * From Users') <sqlite3.Cursor object at 0xb71db5e0> >>> for eachUser in cu.fetchall(): ... print eachUser ... (u'join', 100) >>> cx.commit() >>> cu.execute('Select * From Users') <sqlite3.Cursor object at 0xb71db5e0> >>> r = cu.fetchone() >>> type(r) <type 'tuple'> >>> r (u'join', 100) >>> r[0] u'join' >>> r[1] 100
終於寫完了,累趴了。
轉載請注明出處:http://www.cnblogs.com/sysu-blackbear/ 謝謝!