Python Buildin IO

one2inf發表於2019-02-16

file & open

兩者的呼叫方法:

file(name[, mode[, buffering]]) open(filename [, mode [, bufsize]])

兩者的區別

file()file型別的建構函式,open()為Python內建函式。兩者的引數、作用大致相同。

但在Python3之中file()已經不存在了,所以從發展趨勢來看的話,建議使用open()

兩者的引數說明:

如果檔案不存在且mode為寫或追加時,檔案將被建立。

新增b到mode引數中,將對檔案以二進位制形式操作。

新增+到mode引數中,將允許對檔案同時進行讀 寫操作

引數filename:檔名稱。

引數moder(讀)、w(寫)、a(追加)。

引數buffering

  • 如果為0表示不進行緩衝,
  • 如果為1表示進行行緩衝,
  • 如果是一個大於1的數表示緩衝區的大小 。

返回值:

兩者都返回一個file物件

由於兩者的用法區別不大,下面以open為例:

In [15]: f1 = open(`test1.txt`, `r`)        # 以只讀的方式開啟

In [16]: type(f1)
Out[16]: file

file物件支援的方法:

方法 描述
file.close() 關閉檔案,關閉後檔案不能再進行讀寫操作,<br/>但也節省了資源!
file.flush() 重新整理檔案內部緩衝,直接把內部緩衝區的資料立刻寫入檔案,<br/>而不是被動的等待檔案資源關閉後,緩衝區自然輸出
file.fileno() 返回一個整型的檔案描述符(file descriptor FD贅型),<br/>可以用在如os模組的read方法等一些底層操作上,
file.isatty() 如果檔案連線到一個終端裝置返回:True ,否則返回False
file.next() 返回檔案下一行。
file.read (size) 從檔案讀取指定的位元組數,如果未給定或為負則讀取所有。
file.readline( [size]) 讀取整行,包括”n”字元,
file.readlines([sizehint]) 讀取所有行並返回列表,若給定sizehint > 0,<br/>返回總和大約為sizehint位元組的行,實際讀取值可能比sizhint較大
file.seek(offset[, whence])] 設檔案指標當前位置
file.tell() 返回檔案指標當前位置,若是EOF,則等於-1
file.truncate( [size]) 擷取檔案,擷取的位元組通過size指定,預設為當前檔案位置開始。
file.write(str) 將字串寫入檔案,沒有返回值
file.writelines(sequence) 寫入一個字串列表,需要換行則要加入每行的換行符。(LF或者CRLF)

常用的屬性:

屬性 描述
closed 檔案是否關閉
mode 檔案開啟的模式
encoding 檔案的編碼方式
newlines 可以取的值有None,
,
,,
`
,用於區分換行符

一些栗子

檔案描述符

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 開啟檔案
fo = open("test1.txt", "wb")
print "檔名為: ", fo.name

fid = fo.fileno()
print "檔案描述符為: ", fid

# 關閉檔案
fo.close()

執行結果:

檔名為:  runoob.txt
檔案描述符為:  3

裝置連線情況

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 開啟檔案
fo = open("test1.txt", "wb")
print "檔名為: ", fo.name

ret = fo.isatty()
print "返回值 : ", ret

# 關閉檔案
fo.close()

執行結果:

檔名為:  test1.txt
返回值 :  False
[Finished in 0.1s]

迭代方法

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 開啟檔案
fo = open("test1.txt", "r+")
print "檔名為: ", fo.name

for index in range(5):
    line = fo.next()
    print "第 %d 行 - %s" % (index, line)

# 關閉檔案
fo.close()

執行結果:

檔名為:  test1.txt
第 0 行 - 1. Google

第 1 行 - 2. Microsoft

第 2 行 - 3. IBM

第 3 行 - 4. Oracle

第 4 行 - 5. FaceBook

[Finished in 0.1s]

指令碼:

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 開啟檔案
fo = open("test1.txt", "r+")
print "檔名為: ", fo.name

line = fo.read(10)
print "讀取的字串: %s" % (line)

# 關閉檔案
fo.close()

執行結果:

檔名為:  test1.txt
讀取的字串: 1. Google

[Finished in 0.1s]

快取分塊

在處理日誌檔案的時候,常常會遇到這樣的情況:日誌檔案巨大,不可能一次性把整個檔案讀入到記憶體中進行處理,例如需要在一臺實體記憶體為 2GB 的機器上處理一個 2GB 的日誌檔案,我們可能希望每次只處理其中 200MB 的內容。
Python 中,內建的 File 物件直接提供了一個 readlines(sizehint) 函式來完成這樣的事情。以下面的程式碼為例:

file = open(`test.log`, `r`)
sizehint = 209715200   # 200M
position = 0
lines = file.readlines(sizehint)
while not file.tell() - position < 0:
    position = file.tell()
    lines = file.readlines(sizehint)

每次呼叫 readlines(sizehint) 函式,會返回大約 200MB 的資料,而且所返回的必然都是完整的行資料,大多數情況下,返回的資料的位元組數會稍微比 sizehint 指定的值大一點(除最後一次呼叫 readlines(sizehint) 函式的時候)。通常情況下,Python 會自動將使用者指定的 sizehint 的值調整成內部快取大小的整數倍。

截斷檔案

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 開啟檔案
fo = open("test1.txt", "r+")
print "檔名為: ", fo.name

line = fo.readline()
print "讀取第一行: %s" % (line)

# 截斷剩下的字串
fo.truncate()

# 嘗試再次讀取資料
line = fo.readline()
print "讀取資料: %s" % (line)

# 關閉檔案
fo.close()

執行結果:

檔名為:  test1.txt
讀取第一行: 1. Google

讀取資料: 
[Finished in 0.1s]

truncate方法需要檔案物件以可寫的方式開啟,執行之後檔案內容清空。注意操作

寫入多選

需要指定換行符

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# 開啟檔案
fo = open("test.txt", "w")
print "檔名為: ", fo.name
seq = ["hello the cruel world! 1
", "hello the cruel world! 2"]
fo.writelines(seq)

# 關閉檔案
fo.close()

執行結果:

檔名為:  test.txt
[Finished in 0.1s]

檢視檔案內容:

✐ at [10/30/17][22:59:10] on master✂ ☁☁☁
✎ ➤  cat test.txt
hello the cruel world! 1
hello the cruel world! 2

raw_input & input

Python2 提供了 inputraw_input 等用於輸入,但在 Python3 中發生了一些改變,raw_input 已經沒有了,input 的用法發生了變化,

input([prompt]) & raw_input([prompt])

inputrepr相似的是兩者都要精確,raw_inputstr相似的是兩者都要可讀

  • 首先看 Python2 中的 raw_input,它的用法如下:
raw_input(prompt)

其中,prompt 表示輸入提示。raw_input 會讀取控制檯的輸入,並返回字串型別。

一些栗子

>>> name = raw_input(`please enter your name: `)
please enter your name: ethan     # 輸入一個字串
>>> name
`ethan`
>>> type(name)
<type `str`>
>>>
>>> num = raw_input(`please enter your id: `)
please enter your id: 12345       # 輸入一個數值
>>> num
`12345`
>>> type(num)
<type `str`>
>>>
>>> sum = raw_input(`please enter a+b: `)
please enter a+b: 3+6             # 輸入一個表示式
>>> sum
`3+6`
>>> type(sum)
<type `str`>

可以看到,不管我們輸入一個字串、數值還是表示式,raw_input 都直接返回一個字串。

  • input 的用法跟 raw_input 類似,形式如下:
input(prompt)

事實上,input 本質上是使用 raw_input 實現的,如下:

def input(prompt):
    return (eval(raw_input(prompt)))

也就是說,呼叫 input 實際上是通過呼叫 raw_input 再呼叫 eval 函式實現的。

這裡的 eval 通常用來執行一個字串表示式,並返回表示式的值,它的基本用法如下:

>>> eval(`1+2`)
3
>>> a = 1
>>> eval(`a+9`)
10

這就說明需要精確輸入表示式才不會報錯。現在,讓我們看看 input 的用法:

>>> name = input(`please input your name: `)
please input your name: ethan         # 輸入字串如果沒加引號會出錯
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name `ethan` is not defined
>>>
>>> name = input(`please input your name: `)
please input your name: `ethan`       # 新增引號
>>> name
`ethan`
>>>
>>> num = input(`please input your id: `)
please input your id: 12345           # 輸入數值
>>> num                               # 注意返回的是數值型別,而不是字串
12345
>>> type(num)
<type `int`>
>>>
>>> sum = input(`please enter a+b: `)  # 輸入數字表示式,會對錶達式求值
please enter a+b: 3+6
>>> sum
9
>>> type(sum)
<type `int`>
>>>
>>> sum = input(`please enter a+b: `)   # 輸入字串表示式,會字串進行運算
please enter a+b: `3`+`6`
>>> sum
`36`

可以看到,使用 input 的時候,如果輸入的是字串,必須使用引號把它們括起來;如果輸入的是數值型別,則返回的也是數值型別;如果輸入的是表示式,會對錶達式進行運算。

  • 再來看一下 Python3 中的 input

事實上,Python3 中的 input 就是 Python2 中的 raw_input,也就是說,原 Python2 中的 raw_input 被重新命名為 input 了。那如果我們想使用原 Python2 的 input 功能呢?你可以這樣做:

eval(input())

也就是說,手動新增 eval 函式。

print

一些栗子

  • 格式化輸出整數
>>> strHello = "the length of (%s) is %d" %(`Hello World`,len(`Hello World`))
>>> print strHello
the length of (Hello World) is 11
  • 格式化輸出16制整數
#%x --- hex 十六進位制
#%d --- dec 十進位制
#%o --- oct 八進位制

>>> nHex = 0x20
>>> print "nHex = %x,nDec = %d,nOct = %o" %(nHex,nHex,nHex)
nHex = 20,nDec = 32,nOct = 40
  • 格式化輸出浮點數(float)
>>> import math
>>> #default
>>> print "PI = %f"%math.pi
PI = 3.141593
>>> #width = 10,precise = 3,align = left
>>> print "PI = %10.3f"%math.pi
PI =      3.142
>>> #width = 10,precise = 3,align = rigth
>>> print "PI = %-10.3f" % math.pi
PI = 3.142     
>>> #前面填充字元
>>> print "PI = %06d" % int(math.pi)
PI = 000003
>>> #顯示正負號
>>> print `%+f`% math.pi
+3.141593
>>> print(format(math.pi,`6.2f`))
  3.14
>>> print(format(math.pi,`6f`))
3.141593
>>> print(format(math.pi,`15f`))
       3.141593
>>> print(format(math.pi,`6.0f`))
     3
>>> print(format(math.pi,`6%`))
314.159265%
  • 格式化輸出字串(string)
>>> #precise = 3
>>> print "%.3s " % ("jcodeer")
jco 
>>> #precise = 4
>>> print "%.*s" % (4,"jcodeer")
jcod
>>> #width = 10,precise = 3
>>> print "%10.3s" % ("jcodeer")
       jco
  • 輸出列表(list)
>>> l = [1,2,3,4,`jcodeer`]
>>> print l
[1, 2, 3, 4, `jcodeer`]
```6.出字典(dictionary)```
>>> d = {1:`A`,2:`B`,3:`C`,4:`D`}
>>> print d
{1: `A`, 2: `B`, 3: `C`, 4: `D`}
  • python print自動換行

print 會自動在行末加上回車,如果不需回車,只需在print語句的結尾新增一個逗號”,“,就可以改變它的行為。

>>> for i in range(0,5):
        print i

        
0
1
2
3
4
>>> for i in range(0,5):
        print i,

        
0 1 2 3 4

或直接使用下面的函式進行輸出:

>>> import sys
>>> sys.stdout.write(`Hello World`)
Hello World
  1. 萬能的 %r
    %r是一個萬能的格式符,它會將後面給的引數原樣列印出來,帶有型別資訊。
>>> formatter = "%r %r %r %r"
>>> print formatter % (1, 2, 3, 4)
1 2 3 4
>>> print formatter % ("one", "two", "three", "four")
`one` `two` `three` `four`
>>> print formatter % (True, False, False, True)
True False False True
>>> print formatter % (formatter, formatter, formatter, formatter)
`%r %r %r %r` `%r %r %r %r` `%r %r %r %r` `%r %r %r %r`
>>> print formatter % (
"I had this thing.",
"That you could type up right.",
 "But it didn`t sing.",
 "So I said goodnight."
 )
`I had this thing.` `That you could type up right.` "But it didn`t sing." `So I said goodnight.`
  • print語句輸出包含轉義字元的字串的處理方法
>>> print "I`m OK"
I`m OK
>>> print `Learn "Python" in imooc`
Learn "Python" in imooc
>>> print `Bob said "I`m OK".`
Bob said "I`m OK".
>>> s = `Python was started in 1989 by "Guido".
Python is free and easy to learn.`
>>> s
`Python was started in 1989 by "Guido".
Python is free and easy to learn.`
>>> print s
Python was started in 1989 by "Guido".
Python is free and easy to learn.
>>> print r```"To be, or not to be": that is the question.
Whether it`s nobler in the mind to suffer.```
"To be, or not to be": that is the question.
Whether it`s nobler in the mind to suffer.
  • print語句輸出包含中文字元的字串的處理方法
>>> print u```靜夜思
... 床前明月光,
... 疑是地上霜。
... 舉頭望明月,
... 低頭思故鄉。```
靜夜思
床前明月光,
疑是地上霜。
舉頭望明月,
低頭思故鄉。
  • 輸出類似10000L的字串型別
>>> print(format(math.pi,`6%`))
314.159265%
>>> print repr(`hello,world!`)
`hello,world!`
>>> print repr(10000L)
10000L
>>> print str(`hello,world!`)
hello,world!
>>> print str(10000L)
10000
  • Python3.x中的print 函式

到3.x時print語句沒有了,取而代之的是print()函式。 Python 2.6與2.7部分地支援這種形式的print語法。在Python 2.6與Python 2.7裡面,以下四種形式是等價的:

>>> print `fish`
fish
>>> print "fish"
fish
>>> print ("fish")
fish
>>> print("fish")
fish

然而吉多有一個時光機:

>>> from __future__ import print_function
>>> print("numpy","pandas",`scipy`,`matplotlib`,sep=`_`)
numpy_pandas_scipy_matplotlib

format

一些栗子

format(value [, format_spec])
本函式把值valueformat_spec的格式來格式化,
然而函式解釋format_spec是根據value型別來決定的,不同的型別有不同的格式化解釋。
當引數format_spec為空時,本函式等同於函式str(value)的方式。

其實本函式呼叫時,是把format(value, format_spec)的方式轉換為
type(value).__format__(format_spec)方式來呼叫,
因此在value型別裡就查詢方法__format__()
如果找不到此方法,就會返回異常TypeError

其中format_spec的編寫方式如下形式:

format_spec ::= [[fill]align][sign][#][0][width][,][.precision][type]

fill ::= <any character>

align ::= "<" | ">" | "=" | "^"

sign ::= "+" | "-" | " "

width ::= integer

precision ::= integer

type ::= "b"|"c"|"d"|"e"|"E"|"f"|"F"|"g"|"G"|"n"|"o"|"s"|"x"|"X"|"%"

fill是表示可以填寫任何字元。

align是對齊方式,<是左對齊, >是右對齊,^是居中對齊。

sign是符號, +表示正號, -表示負號。

width是數字寬度,表示總共輸出多少位數字。

precision是小數保留位數。

type是輸出數字值是的表示方式,比如b是二進位制表示;比如E是指數表示;比如X是十六進位制表示。

>>> print(format(2918))
2918
>>> print(format(0x500,`X`))
500
>>> print(format(0x500,`x`))
500
>>> import math
>>> print(format(math.pi,`0=10`))
3.14159265359
>>> print(format(math.pi,`0=20`))
00000003.14159265359
>>> print(format(math.pi,`E`))
3.141593E+00
>>> print(format(math.pi,`e`))
3.141593e+00
>>> print(format(math.pi,`05.3`))
03.14
>>> print(format(math.pi,`5.3`))
 3.14
>>> print(format(`test`,`<20`))
test
>>> print(format(`test`,`>20`))
                test
>>> print(format(`test`,`^20`))
        test
>>> print(format(math.pi,`0=+20`))
+0000003.14159265359
>>> print(format(math.pi,`0^+20`))
000+3.14159265359000

相關文章