跳到主要内容

输入和输出

七、输入与输出

前面已学习了两种写入值的方法:表达式语句 和 print() 函数。

7.1 更复杂的输出格式

  • 有几种方式进行格式化输出
    1. 用格式化字符串字面值
    2. 字符串的str.format()方法
    3. 字符串切片和合并操作
  • 可以用repr()和str()把值转换为字符串,这两个方法之间有些区别。

7.1.1 用格式化字符串字面值

格式化字符串字面值 (简称为 f-字符串)在字符串前加前缀 f 或 F,通过 {expression} 表达式,把 Python 表达式的值添加到字符串内。具体的看官网说明

格式化字符串字面值替换字段的语法python
f_string          ::=  (literal_char | "{{" | "}}" | replacement_field)*
replacement_field ::= "{" f_expression ["="] ["!" conversion] [":" format_spec] "}"
f_expression ::= (conditional_expression | "*" or_expr)
("," conditional_expression | "," "*" or_expr)* [","]
| yield_expression
conversion ::= "s" | "r" | "a"
format_spec ::= (literal_char | NULL | replacement_field)*
literal_char ::= <any code point except "{", "}" or NULL>

双花括号 { { 或 { { 被替换为单花括号,花括号外的字符串仍按字面值处理。单左花括号 { 标记以 Python 表达式开头的替换字段。在表达式后加等于号 '=',可在求值后,同时显示表达式文本及其结果(用于调试)。 随后是用叹号 '!' 标记的转换字段。还可以在冒号 ':' 后附加格式说明符。替换字段以右花括号 { 为结尾。 上述的格式说明符具体看格式规格迷你语言

7.1.2 字符串format()方法

基本格式python
"literal values{替换字段}".format(arg1, arg2, arg3...)
  1. 字符串format()方法主要是要搞清楚**替换字段**中的内容对应的是format()方法中的哪个参数
    • 位置参数对应
    • 关键字参数对应
    • 位置和关键字结合 详细的内容看[str.format()]。
  2. 替换字段的语法和格式化字符串中的类似
替换字段的语法python
replacement_field ::=  "{" [field_name] ["!" conversion] [":" format_spec] "}"
field_name ::= arg_name ("." attribute_name | "[" element_index "]")*
arg_name ::= [identifier | digit+]
attribute_name ::= identifier
element_index ::= digit+ | index_string
index_string ::= <any source character except "]"> +
conversion ::= "r" | "s" | "a"
format_spec ::= <described in the next section>

7.1.3 手动格式化字符串

可以自己写函数来实现字符串的格式化

7.1.4 旧式字符串格式化方法

不建议使用

7.2 读写文件

7.2.1 open内置函数

  1. open() 返回一个 file object ,最常使用的是两个位置参数和一个关键字参数:open(filename, mode, encoding=None)参数详情
  2. 路径:相对路径和绝对路径,一般而言,相对路径的当前文件夹是运行程序时的当前文件夹,而在命令行中,打开命令行的文件夹就是当前的文件夹,与程序所在的文件夹不一定是同一个文件夹
# 可以用os模块中的os.getcwd()得到程序所在文件夹
import os
print(os.getcwd())
# 程序运行期间可以改变当前文件夹
os.chdir('newfolder')
  1. 通常情况下,文件是以 text mode 打开的,也就是说,你从文件中读写字符串,这些字符串是以特定的 encoding 编码的。如果没有指定 encoding ,默认的是与平台有关的。在二进制模式下打开文件时,你不能指定 encoding。
  2. 通常情况下,文本文件的编码默认是utf-8编码,为了防止文件以其他方式解码和编码,应在打开和读写的时候都指定encoding属性
  3. 在处理文件对象时,最好使用with关键字。优点是,子句体结束后,文件会正确关闭,即便触发异常也可以。若是没有使用with,就需要使用f.closewith详情
#以文本文件打开
with open('workfile', encoding="utf-8") as f:
read_data = f.read()

#在文件名前面加上'b',代表以二进制文件打开
f = open(b'workfile')
警告

调用 f.write() 时,未使用 with 关键字,或未调用 f.close(),即使程序正常退出,也可能 导致 f.write() 的参数没有完全写入磁盘。

7.2.2 文件对象方法

[详细的文件对象内容] 假设文件对象命名为f

  1. 读取文件
f.read(size)
#它会读取一些数据,并返回字符串(文本模式),或字节串对象(在二进制模式下)
#size是可选的数值参数。省略 size 或 size 为负数时,读取并返回整个文件的内容
  1. 从文件中读取单行数据
f.readline()
#字符串末尾保留换行符(\n)
  1. 用循环读取文件多行
for line in f:
print(line, end=' ')
  1. 用列表的方式读取行
list(f) 或者 f.readlines()
  1. 写文件
#写入字符串,同时返回写入的字符数
f.write(string)
#写入其他类型的对象前,要先把它们转化为字符串(文本模式)或字节对象(二进制模式)
value = ('Mike', 42) #元组对象
s = str(value)
f.write(s)
  1. 当前在文件中的位置
f.tell()
#二进制模式下时从文件开始的字节数,以及文本模式下的意义不明的数字。
  1. 改变文件对象在文件中的位置
f.seek(offset, whence)
#offset代表偏移量,whence指定参考点,whence 值为 0 时,表示从文件开头计算,1 表示使用当前文件位置,2 表示使用文件末尾作为参考点。省略 whence 时,其默认值为 0。
注意

在文本文件(模式字符串未使用 b 时打开的文件)中,只允许相对于文件开头搜索(使用 seek(0, 2) 搜索到文件末尾是个例外),唯一有效的 offset 值是能从 f.tell() 中返回的,或 0。其他 offset 值都会产生未定义的行为

7.2.3 使用Json保存结构化数据

从文件写入或读取字符串很简单,保存嵌套列表、字典等复杂数据类型时,手动解析和序列化的操作非常复杂。可以利用Json编码器和解码器来自动进行。

  1. 将复杂的数据类型序列化为字符串 需要用到json中的json.dumps函数,函数所接受参数详情
import json
person = ['Mike', 'John', 'Peter']
x = json.dumps(person, indent=4)
#'[\n "Mike",\n "John",\n "Peter"\n]'
  1. 将字符串解序列化 需要利用json中的json.loads函数,函数所接受参数详情
import json
decode_x = json.loads(x)
print(decode_x)
#['Mike', 'John', 'Peter']
  1. 将对象序列化为文件对象,或者是将文件对象解序列,分别需要用到json中的函数json.dumpjson.load函数,函数所接受参数与上面的一样。详情