《python编程从入门到实践》读书实践笔记(一)

时间:2022-12-04 21:03:26

本文是《python编程从入门到实践》读书实践笔记1~10章的内容,主要包含安装、基础类型、函数、类、文件读写及异常的内容。

1 起步

1.1 搭建环境

1.1.1 Python 版本选择

建议选3.6以上,python2的编码非常混乱

1.1.2 安装包下载

建议直接在官网下载,比如,2021/11/27最新的版本是3.10.0, https://www.python.org/downloads/release/python-3100/ 网页下的 Windows installer (64-bit) 链接

特别说明的,有很多管理python和其依赖库的平台,如anaconda,不过对于初学者,其实不需要一步到位,很多时候用一个稳定的官方版本足够应付大多数情况。

1.1.3 一些可能用的上的相关软件

1.1.4 安装后的检查

  • 打开cmd,输入python,如果安装成功,会进入 ">>>" 的命令行
  • 打开sublime Text,编辑一段代码,如
print("hello world")

ctrl+b 编译可正常运行

2 变量和简单数据类型

2.1 运行

2.2 变量

2.2.1 变量的命名和使用

2.3字符串

2.3.1 str的方法来改变大小写

str = "YU tAntAn"
print(str.title()) # 首字符大写, 其余字符小写
print(str.upper()) # 全部字符大写
print(str.lower()) # 全部字符小写

2.3.2 字符串中加入变量

first_name = "YU"
last_name = "tantan"
birth_year = 2021
msg = f"{first_name.title()} {last_name.title()} was born in {birth_year}." # 形式1,比较好用
print(msg)
msg = "{} {} was born in {}.".format(first_name.title(), last_name.title(), birth_year) # 形式2
print(msg)
msg = "%s %s was born in %s." % (first_name.title(), last_name.title(), birth_year) #格式3,类C语言
print(msg)

2.3.3 制表符

最好把编辑器设置为 用 N个空格替代制表符

2.3.4 删除空白

str.lstrip()
str.rstrip()
str.strip()

2.4 数

x = 2 ** 5 # 乘方为**
x = 1000_0000 # 可以通过下划线将数字分组, 等价于x = 10000000
x, y, z = 0, 0, 0 #可以同时给多个变量赋值比如

2.5 注释

注释是个好习惯,真的。

2.5 python之禅

值得看看 https://www.cnblogs.com/huangbiquan/p/7881913.html

但实践上需要努力

3 列表

3.1 列表是什么

有一些类似可变数组,但是丰富的多。

索引从0开始, -1代表逆序第一个

3.2 列表元素的增删改

3.2.1 修改

list[idx] = new_value

3.2.2 增加

list.append(value)  # 末尾增加一个value
list.insert(idx, value) 在索引idx处增加value,新value的索引为idx,原>=idx的value,idx++
list.expend(list) # 增加列表

3.2.3 删除

del list[idx]
last_value = list.pop() # 一般用于取并删除最后一个元素
idx_value = list.pop(idx) # 取并删除索引为idx的元素
list.remove(value) # 删除特定值的元素,注意,这只会删除第一个该值的元素

3.3 组织列表

3.3.1 永久排序

list.sort(reverse=False)  # list将被永久排序

3.3.2 临时排序

list_sorted = sorted(list)

3.3.3 逆序

list.reverse()

3.3.4 列表长度

len(list)

4 操作列表

4.1遍历和for循环

for item in item_list:
print(item)

4.2 缩进

4.3 创建数值列表

4.3.1 range

for i in range(1,6):  # range的右侧是<,而非<=, 本例中不包含6
print(i)

4.3.2 用range产生list

start = 1
end = 11
step = 2
lst = list(range(start, end, step)) # 等价于for(i=start; i<end; i+=step)
print(lst)

4.3.3 列表统计

lst = [0, 1, 2, 3, 5, 5, 5, 9, 9]
max_num = max(lst) # 列表中的最大值
min_num = min(lst) # 列表中的最小值
sum_num = sum(lst) # 列表求和
value_count = lst.count(5) # 列表中数字5出现的次数,返回3
value_idx = lst.index(5) # 列表中数字5第一次出现的位置,返回4
value_count = lst.count(7) # 列表中数字7出现的次数,返回0
value_idx = lst.index(7) # 列表中数字7第一次出现的位置,报错

4.4 使用列表的一部分

4.4.1 切片

stars = ['yangchaoyue', 'liuyifei', 'tongliya', 'zhouxingchi', 'wujing']
print(stars[0:3]) #同 idx = 0; idx < 3; idx++
print(stars[:3]) #同 idx = 0; idx < 3; idx++
print(stars[2:]) #同 idx = 2; idx < len(lst); idx++
print(stars[-2:]) #最后2个, idx=len(lst)-2; idx<len(lst); idx++

4.4.2 遍历切片

4.4.3 复制列表

stars = ['yangchaoyue', 'liuyifei', 'tongliya', 'zhouxingchi', 'wujing']
stars_ptr = stars # 引用
stars_copy = stars[:] # 复制
stars.append('shenteng') # 修改了stars的内容
print(stars)
print(stars_ptr) # 引用
print(stars_copy) # 复制

4.5 元组

可以理解成不可写的列表

dimensions = (720, 480, 3)
print(dimensions)
print(dimensions[2])
for dim in dimensions:
print(dim)

4.6 设置代码格式

PIP8指南

易于阅读>易于编写

缩进用空格替代

行长小于80字符,注释行小于72字符

if语句

5.1 简单示例

5.2 条件

5.2.1-5.2.3 字符比较:相等,不相等和大小写

name1 = 'ycy'
name2 = 'YcY'
print(name1 == name2)
print(name1.lower() == name2.lower())
print(name1.lower() != name2.lower())

5.2.4 数字比较 && 与或非

5.2.6 特定值是否在列表中

stars = ['yangchaoyue', 'liuyifei', 'tongliya', 'zhouxingchi', 'wujing']
print('yangchaoyue' in stars)

5.3 if语句

if-elif-else

5.4 if与列表

fstars = ['yangchaoyue', 'liuyifei', 'tongliya']
mstars = []
if mstars:
print(mstars)
else:
print('there is no mstar')

字典

6.1 一个简单的字典

字典本身是key:value的映射,其中value可以继续是复杂的结构。

需要注意的是,key是唯一的,从某种程度上与数据库类似。

6.2 使用字典

star_0 = {'name': 'yangchaoyue', 'height': 168}  # 新建一个字典
ycy_height = star_0['height'] # 取值
print(ycy_height)
star_0['weight'] = 48 # 增加新的字段
del star_0['weight'] #删除
print(star_0)
star_1 = {} # 新建空字典
star_1['name'] = 'liuyifei' #只有新建字典后才可以通过增加字段的方式增加信息
star_1['height'] = -1
print(star_1)
stars = {'ycy': star_0, 'lyf': star_1} # 嵌套的字典
print(stars) # 使用get取某个key的value,其好处在于,如果失败,可以返回特定的值,防止程序崩溃
print(stars.get('ycy', 'no info found.'))
print(stars.get('tly', 'no info found.'))

6.3 遍历字典

ytt_info = {'name': 'yutantan', 'height': 52, 'weight': 7}
for key, value in ytt_info.items(): # 同时取key和value
print(f"{key}: {value}")
for key in ytt_info.keys(): # 只取key
print(f"{key}: {ytt_info[key]}")
# 本质上,ytt_info.keys()是一个列表,列表的元素是ytt_info的所有key,因此,可以通过对这个列表排序,进行有序的访问字典
for key in sorted(ytt_info.keys()): # 排序后的key
print(f"{key}: {ytt_info[key]}")
for value in ytt_info.values(): # 返回value的列表,并遍历
print(value)

6.3.4 集合

# 集合中的元素是唯一的
lst = [1, 2, 3, 5, 5, 2, 7]
set0 = set(lst) # 可以通过set函数处理列表得到一个集合
print(set0)
set1 = {1, 2, 3, 5, 7} # 可以通过{}定义的方式得到集合,这里与新建字典的格式是有区别的
print(set1)
set2 = {1, 1, 2, 3, 5, 7} # 会自动取唯一
print(set2)

6.4 嵌套

一般是字典和列表的互相嵌套,逻辑很简单,需要通过实践进一步掌握。

7 用户输入和while

7.1 用户输入

用户输入用input函数实现

msg = "enter a number, and  I'll tell you if its even or odd:"  #双引号中的单引号不需要转义
num = input(msg)
num = int(num) #收到的输入是str, 需要转为int。这里没有进行输入的校验,如果输入的是非数字,会在int时报错。
if num % 2 ==0:
print(f"the num {num} is even.")
else:
print(f"the num {num} is odd.")
#这个脚本用sublime无法进行互动,但是用cmd可以运行

7.2 while

7.2.1-7.2.3 常见的几种停止策略

  • 数字累加

    简单情况等价于for,一般用于复杂的累加,但是容易进入逻辑bug,尽量少用。
iter = 0
while (iter < 5):
print(f"iter: {iter}")
iter += 1
  • 匹配判断
prompt = "\nInput something. I will repeat it."
prompt += "\nEnter quit to end the program."
msg = ""
while msg != 'quit':
msg = input(prompt)
if msg != 'quit':
print(msg)
  • 使用标志(flag)控制

    标志可以更好地应对复杂的控制逻辑。
prompt = "\nInput something. I will repeat it."
prompt += "\nEnter quit to end the program."
active_flag = True
while active_flag:
msg = input(prompt)
if msg == 'quit':
active_flag = False
else:
print(msg)

7.2.4-7.2.5 break & continue

break 立刻跳出循环

continue 循环不中断,而是进入下一次新的循环

同C语言,for循环也可以用break和continue进行控制

7.2.6 避免无限循环

一点浅显的经验:

  1. 尽量少用while
  2. 如果非要用while,最好在条件中,and 一个大的计数器。比如原来的条件是 x != 999, 可以改成 x != 999 and (iter < 99999),其中,iter在进入while的第一刻就进行累加。
iter = 0
x = 0.9824
while x < 0 and iter < 99999:
iter += 1
x = x ** 2 + 0.1 # 当x在某区间导致死循环时,至少iter可以抢救一下。
  1. 如果进入了死循环,可以用ctrl+c中断程序

7.3 利用while处理list和dict

7.3.1 旧列表和新列表

比较经典的一个范式

old_list = [1, 2, 3, 4, 5, 6]
print(old_list)
new_list = []
while old_list: # 当old_list都处理完时,就跳出
cur_value = old_list.pop()
cur_value += 1 # 可以为更复杂的处理
new_list.append(cur_value)
print(new_list)

7.3.2 删除特定元素

比较经典的一个范式

lst = [1, 2, 3, 4, 5, 6, 2, 3, 3, 3]
print(lst)
del_num = 3
while del_num in lst: # 当old_list都处理完时,就跳出
lst.remove(del_num)
print(lst)

8函数

8.1 定义函数

# 一个无参数的函数
def greeting():
print("hello!") # 一个有参数的函数
def greet_user(username): # 顺便说一句,对这个定义的函数,username叫做形参(parameter)
print(f"hello, {username}!") # 调用函数
greeting()
name = 'ycy'
greet_user(name) # 顺便说一句,对于这个函数调用,name叫实参(argument)

8.2传递实参

8.2.1 基于位置的传参

def print_user_info(name, height):
print(f"{name}'s height is {height} cm.'") print_user_info('YuTantan', 52) # 通过位置匹配,依次传递参数,因此顺序不正确时将引起致命错误。复杂的函数不建议这么传参

8.2.2 基于关键字的传参

def print_user_info(name, height):
print(f"{name}'s height is {height} cm.'") print_user_info(height=168, name='YangChaoyue') # 通过形参名(关键字)匹配,因此可以打乱顺序

8.2.3 默认值

def print_user_info(name='Ytt', height=52):  # 可以在定义函数时指定默认值,设置默认值时,=左右不能有空格
print(f"{name}'s height is {height} cm.'") print_user_info(height=58) # 如果某个参数没有传,则会使用定义时的默认值,此时name参数即是一个可选参数

8.3 返回值

def my_add(a, b):
"""一个极简的加法器"""
result = a + b
return result def build_dict(a, b):
"""一个极简的字典构造器"""
result = {'key1': a, 'key2': b}
return result print(f"3 + 4 = {my_add(3,4)}") my_dict = build_dict(5, 6)
print(my_dict)

8.4传递列表

需要注意的是,函数传递列表时,本质上是传列表的指针,因此,在函数定义中如果修改了列表形参,传入函数的列表也是被改变的。

如果希望传进函数的列表不被修改,可以在调用函数的时候采传入列表的拷贝:

def my_dict_function(list_a, list_b):
list_a.append('test')
list_b.append('test') lst1 = ['x', 'y']
lst2 = [0,1,2]
print(lst1)
print(lst2)
my_dict_function(lst1[:], lst2) # lst1[:] 即 lst1的拷贝(全切片)
print(lst1)
print(lst2)

8.5 传递任意数量的实参

可以采用如下形式的函数定义,将任意数量的实参,作为一个元组传到函数中

def print_all(*toppings):
# 本质上toppings是一个元组
print(toppings)
# 可以按元组的形式来访问toppings
for idx, top in enumerate(toppings):
print(f"the {idx+1}th param is {top}") print_all('a', 'b', 'c', 1)

8.5.1 结合位置实参和任意数量实参

def print_task_info(name, *toppings):
for idx, top in enumerate(toppings):
print(f"the {idx+1}th param in task {name.upper()} is {top}")
print_task_info('a', 'b', 'c', 1)

8.5.2 任意数量的关键字实参

def proc_infos(name, **kwargs): # kwargs 这个形参名很常见,它用于手机任意数量的关键字实参
#本质上kwargs是一个字典, 会将调用者的实参按关键字存进infos
kwargs['name'] = name # 在这个字典基础上再加一个字段
return kwargs # 调用proc_infos的时候,将task0传递给name
# 并将2个键值对(start_date='Jan.1' 和 end_date='Jan.31')传给字典infos
task_info = proc_infos('task0', start_date='Jan.1', end_date='Jan.31') print(task_info)

8.6 将函数存储在模块中

模块是扩展名为.py的所有文件,可以通过import module_name 来导入module_name.py中所有定义的函数,调用函数时,可以用下面的语法:

import module_name
module_name.function_name()

如果只需要使用function_name函数,可以单独导入,此时调用时可以直接使用函数

from module_name import function_name
function_name()

对于多个函数,可以同时导入

from module_name import function_name, function_name2, funciont_name3
function_name()
function_name2()
function_name3()

可以通过如下语法导入module_name下的所有函数

from module_name import *
function_name()
function_name2()
function_name3()

可以通过as给module或者function起别名

import module_name as m
m.function_name() from module_name import function_name as myfunc
myfunc()

8.7函数编写指南

函数名的命名

  • 命名可读性
  • 只使用小写字符a-z和下划线_
  • 应当包含注释

    参数

    -给形参指定默认值时,等号两边不要有空格

    -传关键字实参时,等号两边也同样不要有空格

    如果参数过长,可以换行

9类

面向对象编程是最常见最有效的软件编写方法之一。在面向对象编程中,需要把复杂的实物,概括成一系列抽象的类,对象是这些类的具体实现,根据类来创建对象成为实例化。

本章的内容都是模拟书中的例子,可以结合起来看。

9.1创建和使用类

9.1.1 创建star类

class Star:
"""明星类"""
def __init__(self, name, birth_year, mood_value=0):
self.name = name.title() # 姓名
self.gender = gender # 性别 def greeting(self):
"""打招呼"""
print(f"{self.name} is greeting you.") def laugh(self):
"""大笑"""
print(f"{self.name} is laughing.")

以上文件保存为Star.py,后续会import进来

9.1.2 根据类创建实例

from Star import Star

my_fav = Star('yangchaoyue', 'female')
print(f"My favorite star is {my_fav.name}") # 访问属性
my_fav.greeting() # 调用方法

9.2 使用类和实例

在Star类的基础上,增加一个心情值的概念,两个改变心情的方法,1个展示心情的方法

class Star:
"""明星类"""
def __init__(self, name, gender, mood_value=0):
self.name = name.title() # 姓名
self.gender = gender # 性别
self.mood = mood_value # 传入心情初始化值,默认为0 def greeting(self):
"""打招呼"""
print(f"{self.name} is greeting you.") def laugh(self):
"""大笑"""
print(f"{self.name} is laughing.") def silent(self):
"""沉默"""
print(f"{self.name} just keeps silence.") def get_emotion_state(self):
if self.mood >= 3:
self.laugh()
elif 0 <= self.mood <= 2:
self.greeting()
elif self.mood < 0:
self.silent() def praise(self):
self.mood += 3 def criticise(self):
self.mood -= 5

这时候可以进行一些简单操作

from Star import Star

ycy = Star('yangchaoyue', 'female')
ycy.praise()
ycy.get_emotion_state()
ycy.criticise()
ycy.get_emotion_state()

9.3继承

一个类继承另一个类时,可以自动获得另一个类的所有属性和方法。原有的类称为父类,新的类称为子类,子类除了继承父类的方法外,还可以有自己的属性和方法,也可以重新写父类的函数。

# FemaleStar类的声明略
class FemaleStar(Star):
"""女明星"""
def __init__(self, name, birth_year):
super().__init__(name, 'female') # 初始化父类的init
self.birth_year = birth_year def describe(self):
print(f"Her name is {self.name}.\nShe was born on {self.birth_year}.") def laugh(self):
print(f"{self.name} smiles.")

调用子类和调用父类没有太大区别。

from Star import FemaleStar

ycy = FemaleStar('yangchaoyue', 1998)
ycy.describe()
ycy.laugh()

9.3.4 将实例作为属性

本质上是类的嵌套,类的某一个属性,本身是一个实例化的对象。这里将9.2中的Star类,里关于心情的部分,抽象成一个类

class Mood:
"""关于心情"""
def __init__(self, mood_value=0):
self.mood = mood_value def praise(self):
self.mood += 3 def criticise(self):
self.mood -= 5 def get_mood_value(self):
return self.mood class Star:
"""明星类"""
def __init__(self, name, gender, mood_value=0):
self.name = name.title() # 姓名
self.gender = gender # 性别
self.mood = Mood(mood_value) # 实例化一个心情对象 def greeting(self):
"""打招呼"""
print(f"{self.name} is greeting you.") def laugh(self):
"""大笑"""
print(f"{self.name} is laughing.") def silent(self):
"""沉默"""
print(f"{self.name} just keeps silence.") def get_emotion_state(self):
mood = self.mood.get_mood_value()
if mood >= 3:
self.laugh()
elif 0 <= mood <= 2:
self.greeting()
elif mood < 0:
self.silent() class FemaleStar(Star):
"""女明星"""
def __init__(self, name, birth_year):
super().__init__(name, 'female') # 初始化父类的init
self.birth_year = birth_year def describe(self):
print(f"Her name is {self.name}.\nShe was born on {self.birth_year}.") def laugh(self):
print(f"{self.name} smiles.")

以上代码可以存在Star.py中,这个py文件可以作为模块来导入

from Star import *

ycy = FemaleStar('yangchaoyue', 1998)
ycy.describe()
ycy.laugh()

9.4 导入类

和导入函数没有太大差别。如何设计类,类的关系反而更需要花心思。

9.5 python标准库

后续会用到,比如random库。

9.6 类编码风格

类名应使用驼峰命名法,即雷鸣的每个单词首字母大写,且不使用下划线。实例名和模块名采用小写格式,并在单词之间加下划线

每个类都应紧跟在类定义后面包含一个文档字符串,用于描述类的功能,并遵循文档字符串的格式。

每个模块也都应该包含一个文档字符串,以描述其中的类。

模块中类与类的定义用两个空行分隔,类中方法与方法用一个空行分隔。

10文件和异常

10.1从文件中读取数据

先准备一个pi_digits.txt,后续实验用

3.1415926535
8979323846
2643383279
5028841971
6939937510
5820974944

10.1.1 从文件中整体读内容

读文件

with open('pi_digits.txt') as fp:
contents = fp.read()
print(contents)

也可以手动open和close,但是这样做存在fp.close()没有正常执行或提前执行的风险

fp = open('pi_digits.txt')
contents = fp.read()
print(contents)
fp.close()

10.1.2文件路径

file_path = 'd:/workspace/PythonCrashCourse/pi_digits.txt'  #采用绝对路径
with open(file_path) as fp:
contents = fp.read()
print(contents)

10.1.3 逐行读取

with open('pi_digits.txt') as fp:
for line in fp:
print(line.strip()) # 读进来的line包含换行符,如果不strip掉,加上print本身的换行,就会有换两次行

10.1.4 创建一个包含各行内容的列表

with open('pi_digits.txt') as fp:
lines = fp.readlines()
for line in lines:
print(line.strip())

10.1.5 - 10.1.7 使用读出的文件内容

10.2 写文件

with open('output.txt', 'w') as fp:
fp.write("hello world!\n")
fp.write("hello china!\n")

'w'是写入模式,会新建一个文件,如果原来就存在该文件,原文件会被覆盖。

除此之外,还有附加模式'a',如果存在原文件,会在原文件基础上继续追加内容

读写模式'r+',可读可写。

还有读取模式'r',只读,默认为读取模式。

10.3 异常

其实异常很值得大书特书,因为编码的时候,很多时间其实是在和异常互动。

python将异常作为对象进行管理,每当python发生错误时,它会创建一个对象。如果编写了处理该异常的代码,程序将继续运行,否则,程序将停止并显示"traceback",其中包含对异常的报告。

异常的处理是通过try-excep-else进行的。

10.3.1-10.3.7 异常处理

a = 10
b = 0
try:
answer = a / b #如果除0,该代码就会返回异常ZeroDivisionError
except ZeroDivisionError:
print("you can't divide by 0") # 这部分代码会处理返回异常ZeroDivisionError的情况
except:
print("other error!") # 返回其他异常
else:
print(answer) # 这部分代码会处理没有返回任何异常的情况

分别给b赋值0,'s',1,可以进入不同的代码段

10.3.8 静默失败

可以用pass做占位,代表什么都不做

a = 10
b = 0
try:
answer = a / b
except:
pass # 遇到异常时会静默
else:
print(answer) # 这部分代码会处理没有返回任何异常的情况

以下为常见的异常类型:

BaseException # 所有异常的基类

SystemExit   # 解释器请求退出

KeyboardInterrupt # 用户中断执行(通常是输入^C)

Exception # 常规错误的基类

StopIteration # 迭代器没有更多的值

GeneratorExit #生成器(generator)发生异常来通知退出

StandardError # 所有的内建标准异常的基类

ArithmeticError # 所有数值计算错误的基类

FloatingPointError # 浮点计算错误

OverflowError #数值运算超出最大限制

ZeroDivisionError # 除(或取模)零 (所有数据类型)

AssertionError #断言语句失败

AttributeError # 对象没有这个属性

EOFError #没有内建输入,到达EOF 标记

EnvironmentError # 操作系统错误的基类

IOError #输入/输出操作失败

OSError #操作系统错误

WindowsError #系统调用失败

ImportError # 导入模块/对象失败

LookupError #无效数据查询的基类

IndexError # 序列中没有此索引(index)

KeyError #映射中没有这个键

MemoryError # 内存溢出错误(对于Python 解释器不是致命的)

NameError # 未声明/初始化对象 (没有属性)

UnboundLocalError # 访问未初始化的本地变量

ReferenceError # 弱引用(Weak reference)试图访问已经垃圾回收了的对象

RuntimeError # 一般的运行时错误

NotImplementedError # 尚未实现的方法

SyntaxError # Python 语法错误

IndentationError # 缩进错误

TabError # Tab 和空格混用

SystemError # 一般的解释器系统错误

TypeError #对类型无效的操作

ValueError # 传入无效的参数

UnicodeError # Unicode 相关的错误

UnicodeDecodeError #Unicode 解码时的错误

UnicodeEncodeError #Unicode 编码时错误

UnicodeTranslateError #Unicode 转换时错误

Warning #警告的基类

DeprecationWarning #关于被弃用的特征的警告

FutureWarning # 关于构造将来语义会有改变的警告

OverflowWarning # 旧的关于自动提升为长整型(long)的警告

PendingDeprecationWarning #关于特性将会被废弃的警告

RuntimeWarning #可疑的运行时行为(runtime behavior)的警告

SyntaxWarning # 可疑的语法的警告

UserWarning #用户代码生成的警告

10.4 JSON

JSON(JavaScript Object Notation)是一种常见的格式,被包括python在内的多种语言采用。很轻便,也易于学习。

10.4.1 使用json.dump()和json.load()

import json
nums = [0, 1, 2, 5, 6, 10]
# 输出json
with open('out.json', 'w') as fp:
json.dump(nums, fp)
# 读json
with open('out.json', 'r') as fp:
loaded_num = json.load(fp)
print(loaded_num)

json.dump的其他参数

在DL学习中,json.dump将非常常用,它有一些经常使用的参数:

  • ensure_ascii

    默认为True,此时中文会输出为ascii码,如果想输出真正的中文,需要指定ensure_ascii=False
  • indent

    缩进,默认None时无缩进,不换行。=0时,无缩进,有换行。>0时,有缩进,有换行。
  • separators

    默认为元组(item分隔符, key分隔符),即(',', ': ')。如果separators=(',',':')后,则:后不会跟空格

json.dump的详细说明可以参考这里《python函数理解 json.dump()》