1. 程式人生 > >python入門教程,格式化輸出,檔案物件

python入門教程,格式化輸出,檔案物件

Python格式化輸出:

Python的字串格式化有兩種方式: 百分號方式、format方式

百分號的方式相對來說比較老,而format方式則是比較先進的方式,企圖替換古老的方式,目前兩者並存。[PEP-3101]

(1)百分號格式化

%[(name)][flags][width][.precision]typecode ....
  • (name) 可選,用於選擇指定的key
  • flags 可選,可供選擇的值有:

    + 右對齊;正數前加正好,負數前加負號;
    - 左對齊;正數前無符號,負數前加負號;
    空格 右對齊;正數前加空格,負數前加負號;
    0 右對齊;正數前無符號,負數前加負號;用0填充空白處

  • width 可選,佔有寬度
  • .precision 可選,小數點後保留的位數
  • typecode 必選

    s,獲取傳入物件的__str__方法的返回值,並將其格式化到指定位置
    r,獲取傳入物件的__repr__方法的返回值,並將其格式化到指定位置
    c,整數:將數字轉換成其unicode對應的值,10進位制範圍為 0 <= i <= 1114111(py27則只支援0-255);字元:將字元新增到指定位置
    o,將整數轉換成 八 進製表示,並將其格式化到指定位置
    x,將整數轉換成十六進位制表示,並將其格式化到指定位置
    d,將整數、浮點數轉換成 十 進製表示,並將其格式化到指定位置
    e,將整數、浮點數轉換成科學計數法,並將其格式化到指定位置(小寫e)
    E,將整數、浮點數轉換成科學計數法,並將其格式化到指定位置(大寫E)
    f, 將整數、浮點數轉換成浮點數表示,並將其格式化到指定位置(預設保留小數點後6位)
    F,同上
    g,自動調整將整數、浮點數轉換成 浮點型或科學計數法表示(超過6位數用科學計數法),並將其格式化到指定位置(如果是科學計數則是e;)
    G,自動調整將整數、浮點數轉換成 浮點型或科學計數法表示(超過6位數用科學計數法),並將其格式化到指定位置(如果是科學計數則是E;)
    %,當字串中存在格式化標誌時,需要用 %%表示一個百分號

 

注意:%s, %d, %f這3個是非常常用的,當不確定用%s or %d,最好使用%s不會出錯

>>> d = {'x':32,'y':27.49325,'z':65}

>>> print('%(x)-10d %(y)0.3g' % d)
32 27.5

一些例子

複製程式碼
tpl = "i am %s" % "tomcat"
 
tpl = "i am %s age %d" % ("tomcat", 18)
 
tpl = "i am %(name)s age %(age)d" % {"name": "tomcat", "age": 18}
 
tpl = "percent %.2f" % 99.97623
 
tpl = "i am %(pp).2f" % {"pp": 123.425556, }
 
tpl = "i am %.2f %%" % {"pp": 123.425556, }
複製程式碼

 

(2)Format()方式:

[[fill]align][sign][#][0][width][,][.precision][type]
  • fill 【可選】空白處填充的字元
  • align 【可選】對齊方式(需配合width使用)
  • <,內容左對齊
  • >,內容右對齊(預設)
  • =,內容右對齊,將符號放置在填充字元的左側,且只對數字型別有效。 即使:符號+填充物+數字
  • ^,內容居中
  • sign 【可選】有無符號數字
    • +,正號加正,負號加負;
    • -,正號不變,負號加負;
    • 空格,正號空格,負號加負;
  • # 【可選】對於二進位制、八進位制、十六進位制,如果加上#,會顯示 0b/0o/0x,否則不顯示
  • , 【可選】為數字新增分隔符,如:1,000,000
  • width 【可選】格式化位所佔寬度
  • .precision 【可選】小數位保留精度
  • type 【可選】格式化型別
    • 傳入” 字串型別 “的引數
      • s,格式化字串型別資料
      • 空白,未指定型別,則預設是None,同s
    • 傳入“ 整數型別 ”的引數
      • b,將10進位制整數自動轉換成2進製表示然後格式化
      • c,將10進位制整數自動轉換為其對應的unicode字元
      • d,十進位制整數
      • o,將10進位制整數自動轉換成8進製表示然後格式化;
      • x,將10進位制整數自動轉換成16進製表示然後格式化(小寫x)
      • X,將10進位制整數自動轉換成16進製表示然後格式化(大寫X)
    • 傳入“ 浮點型或小數型別 ”的引數
      • e, 轉換為科學計數法(小寫e)表示,然後格式化;
      • E, 轉換為科學計數法(大寫E)表示,然後格式化;
      • f , 轉換為浮點型(預設小數點後保留6位)表示,然後格式化;
      • F, 轉換為浮點型(預設小數點後保留6位)表示,然後格式化;
      • g, 自動在e和f中切換
      • G, 自動在E和F中切換
      • %,顯示百分比(預設顯示小數點後6位)

一些例子:

複製程式碼
tpl = "i am {}, age {}, {}".format("seven", 18, 'alex')
  
tpl = "i am {}, age {}, {}".format(*["seven", 18, 'alex'])
  
tpl = "i am {0}, age {1}, really {0}".format("seven", 18)
  
tpl = "i am {0}, age {1}, really {0}".format(*["seven", 18])
  
tpl = "i am {name}, age {age}, really {name}".format(name="seven", age=18)
  
tpl = "i am {name}, age {age}, really {name}".format(**{"name": "seven", "age": 18})
  
tpl = "i am {0[0]}, age {0[1]}, really {0[2]}".format([1, 2, 3], [11, 22, 33])
  
tpl = "i am {:s}, age {:d}, money {:f}".format("seven", 18, 88888.1)
  
tpl = "i am {:s}, age {:d}".format(*["seven", 18])
  
tpl = "i am {name:s}, age {age:d}".format(name="seven", age=18)
  
tpl = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
 
tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
 
tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
 
tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)
複製程式碼

更多格式化操作:https://docs.python.org/3/library/string.html

 

python檔案物件

檔案系統和檔案:
  檔案系統是OS用於明確磁碟或分割槽上的檔案的方法和資料結構--即在磁碟上組織檔案的方法
  計算機檔案(或稱檔案、電腦檔案、檔案)是儲存在某種長期儲存裝置或臨時儲存裝置中的一段資料流,並且歸屬於計算機檔案系統管理之下

概括來講:
  檔案是計算機中由OS管理的具有名字的儲存區域
  在Linux系統上,檔案被看作是位元組序列

 

batyes()這個內建函式,這個方法是將字串轉換為位元組型別

複製程式碼
# utf-8 一個漢子:3個位元組
# gbk一個漢子:2個位元組, 1bytes = 8bit
# 字串轉換位元組型別:bytes(只要轉換的字串,按照什麼編碼)

s = "李納斯"
n = bytes(s,encoding="utf-8")
print(n)
n = bytes(s,encoding="gbk")
print(n)

# 位元組轉化成字串
new_str = str(bytes(s,encoding="utf-8"),encoding="utf-8")
print(new_str)
複製程式碼

 

open()內建函式用於檔案操作

操作檔案時,一般需要經歷如下步驟:

  • 開啟檔案
  • 操作檔案
  • 關閉檔案

每次都要關閉檔案很麻煩,with open('檔案路徑','模式') as filename: 這種方式來開啟檔案。

複製程式碼
#'r'為只讀,'1.txt'為檔案路徑
f=open('1.txt','r',encoding='utf-8')  #開啟檔案
data=f.read()                #操作檔案
f.close()                  #關閉檔案
print(data)
 
# 用with語句開啟,不需要自動關閉
with open('1.txt','r',encoding='utf-8') as f:
    print(f.read())
複製程式碼

 

一、開啟檔案

檔案控制代碼 = open(file, mode='r', buffering=-1, encoding=None)

開啟檔案時,需要指定檔案路徑和以何等方式開啟檔案,開啟後,即可獲取該檔案控制代碼,日後通過此檔案控制代碼對該檔案操作。

開啟檔案的模式有:

  • r ,只讀模式【預設】
  • w,只寫模式【不可讀;不存在則建立;存在則清空內容;】
  • x, 只寫模式【不可讀;不存在則建立,存在則報錯】
  • a, 追加模式【可讀;   不存在則建立;存在則只追加內容;】

"+" 表示可以同時讀寫某個檔案

  • r+, 讀寫【可讀,可寫】
  • w+,寫讀【可讀,可寫】
  • x+ ,寫讀【可讀,可寫】
  • a+, 寫讀【可讀,可寫】

 "b"表示以位元組的方式操作

  • rb  或 r+b
  • wb 或 w+b
  • xb 或 w+b
  • ab 或 a+b

 注:以b方式開啟時,讀取到的內容是位元組型別,寫入時也需要提供位元組型別,當以二進位制的方式的效率比較高,因為磁碟底層是以位元組儲存

二、操作

對於檔案也是個迭代物件,所以迴圈遍歷檔案的每一行用的非常多

f = open('/etc/passwd','r')
for line in f:
    print(line)
  2.x   3.x 複製程式碼
f.close()        關閉檔案
f.fileno()      返回檔案描述符
f.readline()     從當前指標讀取一行
f.readlines()    從當前指標讀取到結尾的全部行
f.read()         從當前指標讀多少個位元組,沒有引數讀取全部
f.tell()         告訴當前指標,是位元組
f.seek(offset [whence])    移動指標,f.seek(0)把指標移動第一行第0個位元組位置
    offset: 偏移量
    whence: 位置
        0: 從檔案頭
        1:從當前位置
        2:從檔案尾部
    
f.write(string)    開啟檔案時,檔案不存在,r,r+都會報錯,其他模式則不會
f.writelines()     必須是字串序列,把字串序列當作一個列表寫進檔案
f.flush()          在檔案沒有關閉時,可以將記憶體中的資料刷寫至磁碟
f.truncate()       檔案擷取多少位元組保留,指標後面的內容全部會清空

f.name             是返回檔名字,不是方法,是屬性    
f.closed           判斷檔案是否已經關閉
f.encoding         檢視編碼格式,沒有使用任何編碼,則為None
f.mode             開啟檔案的模式
f.newlines         顯示出換行符的,空為預設\n不顯示
複製程式碼

一些例子:

複製程式碼
#開啟模式沒有b則開啟的字串
f  = open('db','r')
data = f.read()
print(data,type(data))
f.close()

#開啟模式有b則開啟的時位元組
f1  = open('db','rb')
data = f.read()
print(data,type(data))
f.close()

# 開啟模式有w和b則寫入的字串需要轉換成位元組
f2  = open('db','ab')
f.write(bytes("hello",encoding="utf-8"))
f.close()

f3 = open('db','a+',encoding="utf-8") # 如果開啟模式無b,則read,按照字元讀取 data = f3.read(1) # tell當前指標所在的位置(位元組) print(f3.tell()) # 調整當前指標你的位置(位元組),寫的話會覆蓋原來的 f3.seek(f3.tell()) f3.write("777") f3.close()
複製程式碼

 

三、管理上下文

為了避免開啟檔案後忘記關閉,可以通過管理上下文,即:

with open('log','r') as f:        
    ...

如此方式,當with程式碼塊執行完畢時,內部會自動關閉並釋放檔案資源。

在Python 2.7 及以後,with又支援同時對多個檔案的上下文進行管理,即:

(1)讀取一個檔案中的10行寫入另外一個檔案中

複製程式碼
with open('db1','r',encoding="utf-8") as f1,open('db2','w',encoding="utf-8") as f2:
    times = 0
    for line in f1:
        times += 1
        if times <= 10:
            f2.write(line)
        else:
            break
複製程式碼

(2)將一個檔案一行一行讀取並批量替換並寫入另外一個檔案

with open('db1','r',encoding="utf-8") as f1,open('db2','w',encoding="utf-8") as f2:
    for line in f1:
        new_str = line.replace('ales','st')
        f2.write(new_str)

(3)假設現在有這樣一個需求,有一個10G大的檔案,如何拷貝到另一個檔案中去?下面將講一下如何同時開啟兩個檔案進行處理,以及檔案太大的時候如何讀取用with語句就可以同時開啟兩個檔案,一個讀,一個寫。假設1.txt檔案有10G大,如果用read則一次性就將內容讀到記憶體中去了,這顯然不合適,如果用readline()的話雖然也可以讀一行,但是並不知道何時結束,但是可以用for迴圈讀取檔案這個可迭代的物件,一行行的讀取。下面三行程式碼就可以實現了

with open('1.txt','r',encoding='utf-8') as fread,open('2.txt','w') as fwrite:
    for line in fread:          #一行行的讀
        fwrite.write(line)        #一行行的寫

 大量練習:

  View Code

 

檔案系統功能:import os
目錄相關:
os.getcwd() 返回當前工作目錄
os.chdir() 切換目錄
os.chroot() 設定當前程序的根目錄
os.listdir() 列出指定目錄下的所有檔名
os.mkdir() 建立指定目錄
os.makedirs() 建立多級目錄
os.rmdir() 刪除陌路
os.removedirs() 刪除多級目錄

檔案相關:
os.mkfifo() 建立管道檔案
os.mknod() 建立裝置檔案
os.remove() 刪除檔案

os.rename() 檔案重新命名
os.stat() 檢視檔案的狀態屬性

os.symlink() 建立連結檔案
os.unlink() 刪除連結檔案

os.utime() 更新檔案時間戳
os.tmpfile() 建立並開啟(w+b)一個新的
os.walk() 生成目錄結構的生成器

訪問許可權:
os.access() 檢驗檔案某個使用者是否有訪問許可權
os.chmod() 修改許可權
os.chown() 修改屬主屬組
os.umask() 設定預設許可權模式

檔案描述符:
os.open() 根據檔案描述開啟
os.read() 根據檔案描述讀
os.write() 根據檔案描述符寫

建立裝置:
os.mkdev() 建立裝置檔案
os.major() 獲取裝置主版本號
os.minor() 獲取裝置次版本號


使用者相關:
os.getuid() 獲取當前使用者的uid
os.getgid() 獲取當前使用者的gid


檔案路徑:
os.path.basename() 路徑基名
os.path.dirname() 路徑目錄名
os.path.join() 將dirname()和basename()連線起來
os.path.split() 返回dirname(),basename()元組
os.path.splitext() 返回(filename,extension)元組

os.path.getatime()
os.path.getctime()
os.path.getmtime()
os.path.getsize() 返回檔案的大小

os.path.exists() 判斷指定檔案是否存在
os.path.isabs() 判斷指定的路徑是否為絕對路徑
os.path.isdir() 判斷是否為目錄
os.path.isfile() 判斷是否為檔案
os.path.islink() 判斷是否為連結檔案
os.path.ismount() 判斷是否為掛載點
os.path.samefile() 判斷兩個路徑是否指向了同一個檔案

物件持久儲存:
  pickle模組
  marshal
  
DMB介面
shelve模組


pickle.dump()
pickle.load()

複製程式碼
示例:
>>> dir1 = os.path.dirname('/etc/sysconfig/network-scripts')

>>> file1 = os.path.basename('/etc/sysconfig/network-scripts')

>>> print(dir1,file1)
/etc/sysconfig network-scripts

>>> os.path.join(dir1,file1)
'/etc/sysconfig/network-scripts'


示例:
>>> for filename in os.listdir('/tmp'):
        print(os.path.join('/tmp',filename))


示例:判斷檔案是否存在,存在則開啟
讓使用者通過鍵盤反覆輸入多行資料
追加儲存至此檔案中

#!/usr/bin/env python27

import os
import os.path

filename = '/tmp/test2.txt'

if os.path.isfile(filename):
    f1 = open(filename,'a+')

while True:
    line = raw_input('Enter somethin> ')
    if line == 'q' or line == 'quit':
        break
    f1.write(line+'\n')

f1.close()


示例:將字典寫入檔案中,並還原
>>> import pickle
>>> d1 = {'x':123,'y':567,'z':'hello world'}
>>> f5 = open('/tmp/dfile.txt','a+')
>>> pickle.dump(d1,f5)
>>> f5.flush()
>>> f5.close()


>>> f6 = open('/tmp/dfile.txt','r')
>>> d2 = pickle.load(f6)
>>> print(d2)
{'y': 567, 'x': 123, 'z': 'hello world'}
複製程式碼