Edit


笔记内容:Python3 输入和输出
笔记日期:2017-11-05


  • 输出格式美化

  • 旧式字符串格式化

  • 读取键盘输入

  • 读和写文件

  • 文件对象的方法

  • pickle 模块

Python3 输入和输出

输出格式美化

Python有两种较为常用的输出方式::表达式语句和 print() 函数。
第三种方式则是使用文件对象的 write() 方法,标准输出文件可以使用sys.stdout 。
如果你希望输出的形式更加多样,可以使用 str.format() 函数来格式化输出值。
如果你希望将输出的值转成字符串,可以使用 repr() 或 str() 函数来实现。

  • str(): 函数返回一个用户易读的表达形式。

  • repr(): 产生一个解释器易读的表达形式。
    例如:

>>> s = 'Hello'
>>> str(s)   # 返回一个用户易读的表达形式
'Hello'
>>> repr(s)  # 产生一个解释器易读的表达形式
"'Hello'"
>>> str(1/7)
'0.14285714285714285'
>>> x = 10 * 3.25
>>> y = 200 * 200
>>> s = 'x 的值为: ' + repr(x) + ',  y 的值为:' + repr(y) + '...'
>>> print(s)
x 的值为: 32.5,  y 的值为:40000...
>>> #  repr() 函数可以转义字符串中的特殊字符
... hello = 'hello\n'
>>> hello2 = repr(hello)
>>> print(hello2)
'hello\n'
>>> # repr() 的参数可以是 Python 的任何对象
... repr((x, y, ('Google', 'Baidu')))
"(32.5, 40000, ('Google', 'Baidu'))"

str.format() 的基本使用如下:

>>> print('{}网址:"{}!"'.format('zero','www.zero01.org'))  # 一个大括号对应一个字符串
zero网址:"www.zero01.org!"

大括号及其里面的字符 (称作格式化字段) 将会被 format() 中的参数替换。
在括号中的数字用于指向传入对象在 format() 中的位置,如下所示:

>>> print('{0} 和 {1} 不是好朋友'.format('小明', '小红'))
小明 和 小红 不是好朋友
>>> print('{1} 和 {0} 不是好朋友'.format('小明', '小红'))
小红 和 小明 不是好朋友

如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数。

>>> print('{name}网址:"{host}!"'.format(name='zero',host='www.zero01.org'))
zero网址:"www.zero01.org!"

可以将以上两种使用方法结合一起使用:

# 索引要使用在参数的前面
>>> print('{0}{name}网址:"{host}"!'.format('Test:',name='zero',host='www.zero01.org'))
Test:zero网址:"www.zero01.org"!

使用以下几个字符可以在格式化某个值之前对其进行转化:

  • !a 等于调用了 ascii( ) 函数进行转化

  • !s 等于调用了 str( ) 函数进行转化

  • !r 等于调用了 repr( ) 函数进行转化

代码示例:

print('{!a}'.format('hello'))
print('{!s}'.format('hello'))
print('{!r}'.format('hello'))

运行结果:

‘hello’
 hello
 ‘hello’

如果我们要保留n位小数时,可以使用冒号 ’ : ’ 来进行指定保留几位小数,例如下面的示例将 Pi 保留三位小数:

import math

# f的作用是表示这个是个浮点数类型
print('保留三位小数的PI:{0:.3f}'.format(math.pi))

运行结果:

保留三位小数的PI:3.142

在 ‘:’ 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用。

>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
>>> for name, number in table.items():
...     print('{0:10} ==> {1:10d}'.format(name, number))
...
Runoob     ==>          2
Taobao     ==>          3
Google     ==>          1

如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。
最简单的就是传入一个字典, 然后使用方括号 ‘[]’ 来访问键值 :

>>> table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
# d是用来接收整型数值的
>>> print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; Taobao: {0[Taobao]:d}'.format(table))
Runoob: 2; Google: 1; Taobao: 3


旧式字符串格式化

% 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串. 例如:

>>> import math
>>> print('常量 PI 的值近似为:%5.3f。' % math.pi)
常量 PI 的值近似为:3.142。

因为 str.format() 比较新的函数, 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format(),所以了解一下即可。


读取键盘输入

Python提供了一个内置函数 input() ,可以从标准输入读入一行文本,默认的标准输入是键盘,在PyCharm工具中使用这个函数就可以允许你从控制台中进行输入。
input 可以接收一个Python表达式作为输入,并将运算结果返回。

str = input("请输入:")
print ("你输入的内容是: ", str)

这会产生如下的对应着输入的结果:

 请输入:hello
 你输入的内容是:  hello

如果你要通过键盘的输入进行一个运算的话,需要把类型转换成数字类型,例如:

num=int(input("请输入:"))
print("输入的数字平方是:",num*num)

运行结果:

 请输入:3
 输入的数字平方是: 9

如果不转类型的话,会按照字符串类型去进行运算,所以结果当然是错误的,错误示例:

num=input("请输入:")
print("输入的数字乘以二是:",num*2)

运行结果:

 请输入:3
 输入的数字乘以二是: 33


读和写文件

在python中有一个内置的 open( ) 函数,这个函数可以用于打开某个文件进行读写操作,此函数会返回一个file对象,基本语法格式如下:

open(filename, mode)

  • filename 变量用于表示你要访问的文件路径。

  • mode则决定了打开文件的模式:只读,写入,追加等。所有可取值见如下的完全列表。这个参数是非强制的,如果提供参数的话,默认的文件访问模式为只读(r)。

不同模式打开文件的完全列表:

以下使用一个示例,演示将一段文字写入到一个文件中:

# 打开一个文件,并指定访问模式为写
output=open("E:/test.txt","w")

# 往这个文件写入一段文字,换行使用\n来换行
output.write("Python 是一个非常好的语言。\n是的,人生苦短我用python!!\n")

# 关闭打开的文件,不然会导致资源占用
output.close()
  • 第一个参数为要打开的文件名。

  • 第二个参数描述文件如何使用的字符。 mode 可以是 ‘r’ 如果文件只读, ‘w’ 只用于写 (如果存在同名文件则将被删除), 和 ‘a’ 用于追加文件内容; 所写的任何数据都会被自动增加到末尾. ‘r+’ 同时用于读写。 mode 参数是可选的; ‘r’ 将是默认值。

运行结果:

打开此文件可以看到我们写入的内容。

以下再使用一个示例,读取我们刚刚写入的那个文件中的内容:

file_str=open("E:/test.txt")  # 参数为这个文件的路径

print(file_str.readline()) # 使用此方法可以读取一行文字,返回值是一个字符串
print(file_str.readline())

file_str.close()

运行结果:

 Python 是一个非常好的语言。

是的,人生苦短我用python!!


文件对象的方法

上面已经介绍过两个文件对象的方法了,这两个方法也是最主要的方法,一个用于写文件一个用于读文件。除了这两个方法还有以下几个方法:

  • read( size )   此方法有一个默认参数,这个参数用于定义这个方法一次读取多少数据,单位是字节。然后读取的结果会作为字符串或字节对象返回。
    因为size 是一个可选的数字类型的参数,所以当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。

代码示例:

file_str=open("E:/test.txt")

str=file_str.read(10)
print(str)

file_str.close()

运行结果:

Python 是一个

因为设定只读取10个字节,所以文件内容没有被全部读取出来。

如果想要读取全部内容,就不需要指定这个参数:

file_str=open("E:/test.txt")

str=file_str.read()
print(str)

file_str.close()

运行结果:

 Python 是一个非常好的语言。
 是的,人生苦短我用python!!

  • readline( ) 这个方法上面的示例也使用过了,这个方法能按行读取文件内容,换行符为’ \n ’ 。如果此方法返回了一个空字符串, 说明文件已经读完了。

代码示例:

file_str = open("E:/test.txt")

while True:
    str = file_str.readline()

    if str == "":
        print("文件已经读取完了!")
        break

    print(str)

file_str.close()

运行结果:

Python 是一个非常好的语言。

是的,人生苦短我用python!!

文件已经读取完了!

  • readlines( )  此方法会以列表的形式返回文件中所有的行,此方法也有一个可选参数,此参数用于指定读取的字节长度,并且会将这些字节按行分割。

代码示例:

file_str = open("E:/test.txt")

print(type(file_str.readlines()))

file_str.close()

运行结果:

从结果可以看到返回的对象类型是list列表。


我们可以通过遍历列表,来取出里面的元素:
代码示例:

file_str = open("E:/test.txt")

listfile=file_str.readlines()

print("获得的是一个列表:",listfile,"\n")

print("可以使用循环将列表中的内容遍历出来:")
for i in listfile:
    print(i)

file_str.close()

运行结果:

获得的是一个列表: [‘Python 是一个非常好的语言。\n’, ‘是的,人生苦短我用python!!\n’]

可以使用循环将列表中的内容遍历出来:
 Python 是一个非常好的语言。

是的,人生苦短我用python!!

这个方法并不常用,毕竟用 readline( ) 方法就可以了。

  • write( ) 此方法在之前的示例也用到过,可以将一段字符串内容写入到某个指定的文件中,如需换行得使用 \n 转义符。但是如果想要将数字类型或者其他的非字符串类型写入到文件中,需要提前转换成字符串类型:

代码示例:

file_str = open("E:/test.txt", "w")  # 设置为写模式

data = ["TestNumber:", 123, 45, 12.5]
outData = str(data)  # 转换成字符串类型
file_str.write(outData)  # 写入到文件中

file_str.close()  # 记得一定要关闭资源

运行结果:

  • tell( ) 此方法会告诉你当前读取了多少个字节,这个数字是从文件开头算起的字节数。

代码示例:

file_str = open("E:/test.txt")

print(file_str.read())
print("读取了:",file_str.tell(),"个字节")

file_str.close()

运行结果:

 [‘TestNumber:’, 123, 45, 12.5]
 读取了: 31 个字节

  • seek( )  
    如果要改变文件当前的读取位置, 可以使用 f.seek(offset, from_what) 函数。
    from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾,例如:

    • seek( x , 0 ) : 从起始位置即文件首行首字符开始移动 x 个字符

    • seek( x , 1 ) : 表示从当前位置往后移动x个字符

    • seek( -x , 2 ):表示从文件的结尾往前移动x个字符

from_what 值为默认为0,即文件开头。下面给出一个完整的例子:

# 以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。
file_str = open("E:/test.txt","rb+")

file_str.write(b'0123456789')

print(file_str.seek(5,0),end=" ") # 移动到文件的第六个字节
print(file_str.seek(3,1),end=" ")  # 从当前的读取位置移动三个字节
print(file_str.seek(-3,2),end=" ")  # 移动到文件的倒数第三字节

file_str.close()

运行结果:

5 8 7

  • close( ) 方法,从以上演示可以看到每一个示例代码的末尾都调用了这个方法,这是因为要关闭对文件的操作资源占用,如果不关闭的话,当程序运行时去打开这个文件就会显示文件被占用。因为一个file对象调用close( ) 方法后就会关闭文件并释放系统资源,所以如果再尝试通过该对象去进行读写文件的操作,就会抛出异常。

代码示例:

>>> file_str = open("E:/test.txt")
>>> file_str.close()
>>> file_str.read()
Traceback (most recent call last):
  File "", line 1, in ?
ValueError: I/O operation on closed file


with 关键字

    当处理一个file对象时, 使用 with 关键字是非常好的方式。在文件读写操作结束后, 它会自动帮你正确的关闭文件。这样就不需要每次都使用finally最终块来确保关闭资源了。
代码示例:

# 需要使用as关键字来把file对象赋值给一个变量,所以在这里file_str是一个变量
>>> with open("E:/test.txt") as file_str:
...     read_data = file_str.read()
>>> f.closed  # 如果资源关闭返回出True,否则返回False
True

    从上面这个示例可以看到,我并没有调用 close( ) 方法,with自动帮我正确的关闭了文件,因为with的这一个方便之处,所以with关键字很常用。

文件对象还有其他方法, 如 isatty() 和 trucate(), 但这些通常比较少用,就不赘述了。


pickle 模块

    python的pickle模块实现了基本的数据序列和反序列化。
通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去,永久存储。
通过pickle模块的反序列化操作,我们能够从文件中创建上一次程序保存的对象。
简单来说,pickle可以保存和加载几乎任何的python数据对象,例如列表、字典、元组等。我们可以通过pickle把这些数据对象存储到文件中(序列化),反过来(反序列化)也可以把文件中保存的这些数据再读取到程序的内存中。

    pickle模块提供了两个方法,一个是 dump( ) 一个是 load( ) ,前者用于将数据对象保存到文件中,后者用于将保存到文件中的数据读取到内存中。要注意的一点是:这种形式保存的数据将会是二进制的形式,也就是说并非保存为普通的文本文件而是一个二进制文件。

下面使用一个实际的例子来简单的演示一下dump方法的应用方式,代码示例:

# 导入pickle模块
import pickle

# 这是一个列表数据对象
listData=[["test","file"],("dump",78),{"name":"lisi"},"zero",12.5,100]

# 以二进制的模式打开文件
with open("E:/test.txt","wb") as file_str :
    pickle.dump(listData,file_str)  # 将数据对象写入到文件中

运行结果:

因为是二进制形式的数据,所以用文本打开就会是一片乱码。

然后再使用load方法,就可以将数据再读取回来,并且数据类型依旧是列表,代码示例:

# 导入pickle模块
import pickle

# 以二进制的模式打开文件
with open("E:/test.txt", "rb") as file_str:
    listData = pickle.load(file_str)  # 读取文件中的二进制数据
    print("读取出来的数据:", listData)
    print("该数据的类型是:", type(listData))

运行结果:

 读取出来的数据: [[‘test’, ‘file’], (‘dump’, 78), {‘name’: ‘lisi’}, ‘zero’, 12.5, 100]
 该数据的类型是:

pickle模块主要就是像以上示例一样,用于将某个数据对象保存到文件中,这样就可以永久存储,然后还可以再次将这些数据再读取到内存中。


File对象方法:

file 对象使用 open 函数来创建,下表列出了 file 对象常用的函数: