乐趣区

关于python:Python基础之Python中的IO

简介

IO 就是输出和输入,任何一个程序如果和内部心愿有交互的话,都须要应用到 IO。绝对于 java 而言,Python 中的 IO 更加的简略,易用。

本文将会具体介绍 Python 中的 IO 操作。

linux 输入输出

linux 中有三种规范输入输出,别离是 STDIN,STDOUT,STDERR,对应的数字是 0,1,2。

STDIN 是规范输出,默认从键盘读取信息;

STDOUT 是规范输入,默认将输入后果输入至终端;

STDERR 是规范谬误,默认将输入后果输入至终端。

咱们罕用的 2>&1,指将规范输入、规范谬误指定为同一输入门路。

格式化输入

python 中,咱们能够应用 print 办法来输入信息。

咱们看下 print 函数的定义:

print(*objects, sep='', end='\n', file=sys.stdout, flush=False)

print 函数将 objects 打印到 file 指定的文本流,以 sep 分隔并在开端加上 endsep, end, fileflush 如果存在,那么必须以关键字参数的模式给出。

所有非关键字参数都会被转换为字符串,并会被写入到流,以 sep 宰割,并在开端加上 endsepend 都必须为字符串;它们也能够为 None,这意味着应用默认值。如果没有给出 objects,则 print() 将只写入 end

file 参数必须是一个具备 write(string) 办法的对象;如果参数不存在或为 None,则将应用 sys.stdout。因为要打印的参数会被转换为文本字符串,因而 print()不能用于二进制模式的文件对象。对于这些对象,能够应用 file.write(...)

输入是否被缓存通常决定于 file,但如果 flush 关键字参数为真值,输入流会被强制刷新。

能够看到 print 的输入格局还是比较简单的。咱们接下来看一下怎么丰盛输入的格局。

f 格式化

如果想要格式化字符串,能够在字符串的开始引号之前加上 fF

这样的话,咱们能够间接在字符串中引入变量值,只须要把变量放在 {} 两头即可。

>>> year = 2016
>>> event = 'Referendum'
>>> f'Results of the {year} {event}'
'Results of the 2016 Referendum'

除了在 {} 中放入 Python 变量之外,还能够在其中放入函数:

>>> import math
>>> print(f'The value of pi is approximately {math.pi:.3f}.')
The value of pi is approximately 3.142.

':' 后传递一个整数能够让该字段成为最小字符宽度。不便列对齐:

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678}
>>> for name, phone in table.items():
...     print(f'{name:10} ==> {phone:10d}')
...
Sjoerd     ==>       4127
Jack       ==>       4098
Dcab       ==>       7678

{}中的变量前面还能够跟着转值符号:'!a' 示意利用 ascii()'!s' 示意利用 str(),还有 '!r' 示意利用 repr()

>>> animals = 'eels'
>>> print(f'My hovercraft is full of {animals}.')
My hovercraft is full of eels.
>>> print(f'My hovercraft is full of {animals!r}.')
My hovercraft is full of 'eels'.

format 格式化

除此之外,str 自身自带一个功能强大的format 函数:

str.format(*args, **kwargs)

调用此办法的字符串能够蕴含字符串字面值或者以花括号 {} 括起来的替换域,每个替换域能够蕴含一个地位参数的数字索引,或者一个关键字参数的名称。返回的字符串正本中每个替换域都会被替换为对应参数的字符串值。

>>> "The sum of 1 + 2 is {0}".format(1+2)
'The sum of 1 + 2 is 3'

再看一个应用索引的例子:

>>> print('{0} and {1}'.format('spam', 'eggs'))
spam and eggs
>>> print('{1} and {0}'.format('spam', 'eggs'))
eggs and spam

看一个关键字的例子:

>>> print('This {food} is {adjective}.'.format(...       food='spam', adjective='absolutely horrible'))
This spam is absolutely horrible.

再看一个组合的例子:

>>> print('The story of {0}, {1}, and {other}.'.format('Bill', 'Manfred',
                                                       other='Georg'))
The story of Bill, Manfred, and Georg.

还有非常复杂的组合的例子:

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {0[Jack]:d}; Sjoerd: {0[Sjoerd]:d};'
...       'Dcab: {0[Dcab]:d}'.format(table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

或者应用 ‘**’ 符号将 table 作为关键字参数传递:

>>> table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 8637678}
>>> print('Jack: {Jack:d}; Sjoerd: {Sjoerd:d}; Dcab: {Dcab:d}'.format(**table))
Jack: 4098; Sjoerd: 4127; Dcab: 8637678

还能够应用 n 类型 '{:n}' 来格式化数字:

>>> yes_votes = 42_572_654
>>> no_votes = 43_132_495
>>> percentage = yes_votes / (yes_votes + no_votes)
>>> '{:-9} YES votes  {:2.2%}'.format(yes_votes, percentage)
'42572654 YES votes  49.67%'

repr 和 str

如果咱们只是想要将 Python 对象转换为字符串,那么能够应用 repr() 或者 str(), str() 函数是用于返回人类可读的值的示意,而 repr() 是用于生成解释器可读的示意。

举个例子:

>>> s = 'Hello, world.'
>>> str(s)
'Hello, world.'
>>> repr(s)
"'Hello, world.'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'The value of x is' + repr(x) + ', and y is' + repr(y) + '...'
>>> print(s)
The value of x is 32.5, and y is 40000...
>>> # The repr() of a string adds string quotes and backslashes:
... hello = 'hello, world\n'
>>> hellos = repr(hello)
>>> print(hellos)
'hello, world\n'
>>> # The argument to repr() may be any Python object:
... repr((x, y, ('spam', 'eggs')))
"(32.5, 40000, ('spam','eggs'))"

str 对象还提供了一些对字符串进行手动格式化的办法:

>>> for x in range(1, 11):
...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
...     # Note use of 'end' on previous line
...     print(repr(x*x*x).rjust(4))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

字符串对象的 str.rjust()办法通过在左侧填充空格来对给定宽度的字段中的字符串进行右对齐。相似的办法还有 str.ljust()str.center()

如果输出的字符串太长,它们不会截断字符串,而是原样返回。

如果想保障字符串的长度,则能够应用切片:x.ljust(n)[:n]

还能够应用 str.zfill()来用 0 填充字符串:

>>> '12'.zfill(5)
'00012'
>>> '-3.14'.zfill(7)
'-003.14'
>>> '3.14159265359'.zfill(5)
'3.14159265359'

% 格式化办法

% 也能够用来格式化字符串,给定 'string' % values,则 string 中的 % 实例会以零个或多个 values 元素替换。此操作通常被称为字符串插值。

>>> import math
>>> print('The value of pi is approximately %5.3f.' % math.pi)
The value of pi is approximately 3.142.

读写文件

python 中文件读取非常简单,应用 open() 办法即可。

open()会返回一个文件对象。咱们看一下它的定义:

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

第一个参数是文件名。

第二个参数是文件关上的模式,可用的模式有:

字符 意义
'r' 读取(默认)
'w' 写入,并先截断文件
'x' 排它性创立,如果文件已存在则失败
'a' 写入,如果文件存在则在开端追加
'b' 二进制模式
't' 文本模式(默认)
'+' 关上用于更新(读取与写入)

默认模式为 'r'

看一个 open 文件的例子:

>>> f = open('workfile', 'w')

文件关上了,天然须要被敞开,所以咱们须要显示调用 f.close() 办法:

>>> f.close()

有没有相似 java 中的 try with resource 的主动敞开文件的性能呢?

咱们能够应用 with,这样文件在应用结束之后,会主动被敞开,十分的好用。

>>> with open('workfile') as f:
...     read_data = f.read()

>>> # We can check that the file has been automatically closed.
>>> f.closed
True

文件被敞开之后,如果想要再次读取,就会报错:

>>> f.close()
>>> f.read()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: I/O operation on closed file.

文件对象的办法

获取到文件对象之后,咱们就能够调用文件中的办法了。

f.read(size) 会读取一些数据并将其作为字符串(在文本模式下)或字节串对象(在二进制模式下)返回。

size 是一个可选的数值参数。当 size 被省略或者为正数时,将读取并返回整个文件的内容;当取其余值时,将读取并返回至少 size 个字符(在文本模式下)或 size 个字节(在二进制模式下)。如果已达到文件开端,f.read() 将返回一个空字符串 ('')。

>>> f.read()
'This is the entire file.\n'
>>> f.read()
''

f.readline() 从文件中读取一行;换行符(\n)留在字符串的开端,如果文件不以换行符结尾,则在文件的最初一行省略。如果 f.readline() 返回一个空的字符串,则示意曾经达到了文件开端,而空行应用 '\n' 示意,该字符串只蕴含一个换行符。

>>> f.readline()
'This is the first line of the file.\n'
>>> f.readline()
'Second line of the file\n'
>>> f.readline()
''

还有一种更加简略的读取办法,就是从文件中遍历:

>>> for line in f:
...     print(line, end='')
...
This is the first line of the file.
Second line of the file

如果你想以列表的模式读取文件中的所有行,你也能够应用 list(f)f.readlines()

f.write(string) 会把 string 的内容写入到文件中,并返回写入的字符数。

>>> f.write('This is a test\n')
15

如果是在文本模式下,那么在写入文件之前,须要把对象转换成为文本模式,咱们能够应用 str() 来进行转换。

>>> value = ('the answer', 42)
>>> s = str(value)  # convert the tuple to string
>>> f.write(s)
18

应用 f.seek(offset, whence) 能够定位文件指针的地位,而后后续会从该地位开始进行读取操作。

whence 的 0 值示意从文件结尾起算,1 示意应用以后文件地位,2 示意应用文件开端作为参考点。whence 如果省略则默认值为 0,即应用文件结尾作为参考点。

>>> f = open('workfile', 'rb+')
>>> f.write(b'0123456789abcdef')
16
>>> f.seek(5)      # Go to the 6th byte in the file
5
>>> f.read(1)
b'5'
>>> f.seek(-3, 2)  # Go to the 3rd byte before the end
13
>>> f.read(1)
b'd'

应用 json

JSON 是一个很不便进行信息交换的文件格式。咱们看下怎么应用 JSON 来将对象转换为字符串:

>>> import json
>>> json.dumps([1, 'simple', 'list'])
'[1,"simple","list"]'

dumps 是将对象转换为 json str。json 还有一个 dump 办法,能够间接将对象存入到文件中。

json.dump(x, f)

要从文件中解析出 json 字符串,能够应用 load:

x = json.load(f)

JSON 中的键 - 值对中的键永远是 str类型的。当一个对象被转化为 JSON 时,字典中所有的键都会被强制转换为字符串。这所造成的后果是字典被转换为 JSON 而后转换回字典时可能和原来的不相等。换句话说,如果 x 具备非字符串的键,则有 loads(dumps(x)) != x


本文已收录于 http://www.flydean.com/08-python-io/

最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!

欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!

退出移动版