00-3 Python核心知识点

第一章 程序设计与Python语言3

一、Python语言的基本语法

1. Python程序元素

(1) 缩进

· 1个TAB键或4个空格

· 表示代码的层次关系

·  是Python语言中表示程序框架的唯一手段

(2) 注释

· 开发者加入的说明信息, 不被执行

· 单行注释以#开头

· 多行注释以三引号(""")开始和结束

(3) 常量与变量

· 常量:

o 程序执行过程中,值不发生改变的元素;

o 程序中多次使用的值可作为常量,便于更改及维护。

· 变量:

o 程序执行过程中,值发生改变或需要改变的元素。

(4) 命名

· 为程序元素关联一个名称,要保证唯一性

·  Python标识符

o 在Python里,标识符由字母、数字、下划线组成;但不能以数字开头。

o 在Python中,所有标识符区分大小写

o 以下划线开头的标识符是有特殊意义的。以单下划线开头_foo的代表不能直接访问的类属性,需要通过类提供的接口进行访问,不能以from … import *而导入

o 以双下划线开头的__foo代表类的私有成员;以双下划线开头和结尾的__foo__代表Python里特殊方法专用的标识符,如,__init__()代表类的构造函数。

o 不能与保留字相同

#=============查看系统(Python 3.x)保留字=============

# 导入模块

import keyword

# keyword帮助文档

help(keyword)

# Python 关键字列表

print(keyword.kwlist)

keyword.kwlist

# 判断字符串是否是 Python 关键字

keyword.iskeyword('and')

keyword.iskeyword('has')

保留字:['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']

(5) 表达式

· 程序中产生新数据值或执行操作的一行代码

· 运算符

o ** 指数

o // 相除取整(商)

o % 取余

o != 不相等

(6) 输入

· input() #获得用户的输入并以字符串的形式保存

(7) 输出

· print() #输出信息

二、数据结构

1. 数值型

Python中常用的数值类型

(1) 整数类型,与数学中的整数概念一致;如:100,-250

(2) 浮点数类型,带有小数点及小数的数值;如:0.0,-3.14,3.4e-3(科学计数法)

(3) 类型转换:

· 整数→浮点数,float(4)→4.0

· 浮点数→整数,int(3.14)→3,只会保留整数部分

· 字符串→整数,int('3')→3

· 字符串→浮点数,float('3.14')→3.14

(4) 判断类型:type()函数

2.  字符串

(1) 文本在程序中通过字符串(string)类型表示

(2) 两个双引号或单引号括起来表示

(3) 索引/访问方式

· 正向索引:0,1,2,……

· 反向索引:……,-3,-2,-1;[:-3] #字符串不取后3位;[-3:] #取字符串后3位

· 区间索引 [A:B:C]:从位置A到B的部分字符串,不包含位置B,步长为C

(4) 字符串分割:str.split() https://docs.python.org/3/library/stdtypes.html#str.split

(5) 字符串格式化输出,使用{}占位:str.format()

如,

'{}公斤,{}厘米'.format(70,175)

重复输出时可以使用数字标记顺序:'{0}公斤,{1}厘米,{0}公斤'.format(70,175)

(6) 字符串乘以一个数字n,结果为由n个该字符串组成的字符串,即字符串的复制

(7) Python字符串操作

str.isnumeric()  # 检测字符串是否只由数字组成

str.isalpha()  # 检测字符串是否只由字母组成

str.islower()  # 检测字符串中所有字母是否都为小写

str.isupper()  # 检测字符串中所有字母是否都为大写

更多isxxx()方法参考:https://docs.python.org/3/library/stdtypes.html#string-methods

(8) 代码示例

# ======字符串操作========#

input_str = '性别 体重(Kg) 身高(Cm) 年龄'

input_str.find(' ')  # 字符串查找

input_str.split(' ')  # 字符串分割

type(input_str.split(' '))  # 查看类型,为list类型(容器)

input_str.split(' ')[1]  # 字符串分割后,取第2个元素

# 字符串的格式化: {}占位;str.split()

'{1},{0}'.format(70,100)  # 对应位置输出100,70

# ============= 索引练习 =============

s = 'Python'

print(s)

print(s[2])  # 正向位置索引

print(s[-4])  # 反向位置索引

print(s[2:4])  # 正向区间索引,前闭后开

print(s[:3])

print(s[0:3])

print(s[-3:])  # 反向区间索引,获取后3位

print(s[:-3])  # 去除最后3个字符

# 列表list的所引

# var[A:B:C] # A索引初始位置,B索引索引结束为止,C:步长;前闭后开

n = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

print(n[2:8:3])

a="Hi"

a*2

a*7

# ===== 字符串操作练习 =====

password = 'abc123def'

len(password)   # 字符串长度

password.isnumeric()  # 字符串是否只含有数字

password.isalpha()   # 字符串是否只含有字母

password.islower()  # 字符串是否均为小写

password.isupper()  #字符串是否均为大写

for X in password:

print(X)

3. 列表

(1) 列表(list)是有序的元素集合

(2) 可通过索引访问单个元素,如l[2],l[-1]

(3) 可通过区间索引访问子列表内容,如l[2:5],l[-3:],依然是前闭后开

(4) 列表中每个元素类型可以不同

注:列表排序

· list.sort(func)  # func指定了排序的方法

· func可以通过匿名函数lambda实现

# ======列表操作练习=======

l1 = [1, 3, 5, 7, 9]

l1

l2 = [2, 4, 6.5, 8, 'abc']

print(l2)

l1 + l2  # 连接两个list中的内容

l1 * 3   # 将列表l1重复3次

len(l1)  # 返回列表长度

1 in l1  # 判断元素1时是否在列表l1中,返回逻辑值

l1.append(11)  # 在列表l1后追加元素11

l1

l1 = [1, 3, 7, 5, 9, 9]

l1.sort()  # list中元素排序

l1

l1.reverse()  # list中元素逆序

l1

l1.index(5)  # 返回list中元素5的位置

l1.insert(2, 10)  # 在索引为2的位置插入元素10

l1.count(9)  # 返回list中元素9的个数

l1.remove(10)  #删除元素10

l1.pop(2)  # 取出列表中i元素所在的位置,并将其删除

l1

4. 元组(tuple)

(1) 元组是特殊的序列类型

(2) 一旦被创建就不能修改,使代码更安全

(3) 使用逗号和圆括号来表示,如,(1, "green", "True"),(1, 2, 3)

(4) 访问方式和列表相同

(5) 一般用于表达固定数据项、函数多返回值等情况

(6) 特点:

o 元组中的元素可以是不同类型的

o 元组中各元素存在先后关系,可通过索引访问元组中的元素

(7) 元组与列表

o 元组是不可变的,列表是可变的

o 元组通常由不同的数据组成,列表通常是由相同类型的数据组成

o 元组表示的是结构,列表表示的是顺序

# # ======数据容器:元组(tuple) 练习======

# # 元组中的元素不能进行增删改

# # 元组和列表都能包含不同的数据类型,但是一般列表放同一类型的数据元素

l=[1, 2, 3, 4, 5]

type(l)

l[1] = 5  # 修改元素

del l[1]  # 删除第二个元素

l.append(6)  # 末尾追加一个元素

t=(1, 2, 3, 4, 5)

type(t)

t[1]=5

a=()  # 空元组

type(a)

a=(123) # 返回int型

type(a)

a=(1,"ni",'TRUE')

a

b=[1,"ni",'TRUE']

b

(1) zip()函数

zip()函数用于将对应的元素打包成一个个元组

注意:元组中的元素是不可修改的,若要修改需要转换成字典或其他数据容器类型,如dict(zip(l1,l2))

5. 集合(set)

(1) Python中的集合(set)类型同数学中的集合概念一致,即包含0或多个数据项的无序组合

(2) 集合中的元素不可重复

(3) 集合是无序组合,没有索引和位置的概念

(4) set()函数用于集合的生成,返回结果是一个无重复且排序任意的集合

(5) 集合通常用于表示成员间的关系、元素去重等

(6) 集合操作

# # ======数据容器:集合(set) 练习======

l = [1, 2, 3, 4, 5, 3, 5]   # 列表

l

t = set(l)

t

s = {1, 3, 5, 7, 9}

s - t  # 返回差集

s & t  # 返回交集

s | t  # 返回并集

s ^ t  # 返回并集,去掉交集

6. 字典(dict)

(1) 字典类型(dict)是“键-值”数据项的组合,每个元素是一个键值对

· 如:身份证号(键)-个人信息(值)

(2) 字典类型数据通过映射查找数据项

· 映射:通过任意键查找集合中的值的过程

(3) 字典类型以键为索引,一个键对应于一个值

(4) 字典类型的数据是无序的

(5) 基本操作

a) d[key] = value  # 增加一项

b) d[key]  # 访问

c) del d[key]  # 删除某项

d) key in d  # 判断key是否在字典里

(6) 字典的遍历

a) 遍历所有的key

for key in d.keys():

print(key)

b) 遍历所有的value

for value in d.values()

print(value)

c) 遍历所有的数据项

for item in d.items():

print(item)

# ======数据容器:字典(key - value) 练习======

# 字典间的值是无序的

d = dict()  # 创建空字典

d['eggs'] = 2.59  # 添加数据项,键值对

d['milk'] = 3.19

d['cheese'] = 4.8

d['eggs'] = 3.59  # 修改数据项,键值对

del d['cheese']  # 删除数据项

'eggs' in d  # 查看数据项是否在字典中

d.keys()  # 遍历keys

d.values() # 遍历values

d.items()  # 变量键值对

list(d.values())

list(d.values())[1]

7. 补充:解析式

(1) 列表

(2) 字典

三. Python的语句结构

1. 分支结构 if

(1) 控制程序的语句

(2) 根据判断条件选择程序的执行路径

(3) 使用方法

if <条件1>:

<语句块>

elif <条件2>:

<语句块>

else:

<语句块N>

(4) pass语句

1) pass语句不会执行任何操作

2) pass语句可作为占位符

3) pass语句可以用来创建占位程序

2. 循环语句

(1) while循环

1) 控制程序的语句

2) 根据判断条件确定一段程序是否再次执行一次或者多次

3) 使用方法

while(<条件1>):

<语句块1>

<语句块2>

4) 当条件为真(TRUE)时,执行语句块1;为假(FASLE)时,退出循环。

(2) for循环

1) 使用for语句可以循环遍历整个序列的内容

for <x> in <list1>:

<body>

2) 循环变量x在每次循环时,被赋值成对应的元素内容

3) 与while循环的区别

a) for循环次数固定,即遍历的序列长度

b) while为无限循环

4) range(n) 返回一个可迭代的对象

a) list(range(n)) 将迭代类型转换为列表类型

b) range(n)  # 返回从0到n-1的值

c) range(1,n)  # 返回1到n-1的值

5) 循环的终止

  • break语句  # 终止整个循环

  • continue语句  # 只终止本次循环,而不终止整个循环的执行

# ===== 终止循环操作练习 =====

for i in range(100):

if i % 2 == 0:

break   # 终止整个循环,之后所有 的语句都不执行

print(i)   # 无输出

for i in range(100):

if i % 2 == 0:

continue   # 终止本次循环,继续下一次循环

print(i)   # 输出奇数

(3) enumerate() 函数

enumerate()函数用于将可遍历的组合转换为一个序列索引

一般用于for循环中,同时列出元素和元素的索引号

四、Python函数

1. 函数

· 将特定功能代码编写在一个函数里

· 便于阅读和复用

· 对一组表达特定功能表达式的封装

· 使程序模块化

· Python内置函数    input(), print(), eval()

(1) 函数的定义

def <函数名>(<参数列表>):

<函数体>

return <返回值列表>

(2) 函数的调用过程

· 调用程序在调用函数处暂停执行

· 调用时将参数(实参)赋值给函数的参数(形参)

· 执行函数体

· 返回函数结果,回到调用处继续执行

2. 匿名函数lambda

· 特殊函数 - 匿名函数

· 使用方法:

<函数名> = lambda <形参列表>:<表达式>

· 用于简单的、能够在一行内表示的函数,计算结果为返回值

3. 函数的参数传递

(1) 函数通过参数与调用程序传递信息

(2) 变量的作用范围

a) 局部,函数内的变量作用范围只在函数内

b) 全局,函数外的变量,在所有函数中都能使用,global

(3) 函数的形参只接受实参的值,给形参赋值并不影响实参

# =====变量作用范围=====

# 示例1:局部变量

def num_value(num1):

num1 = 2

num1 = 1

num_value(num1)

print(num1)  # 1

# 示例2:全局变量

def num_value():

global num1

num1 = 2

num1 = 1

num_value()

print(num1)  # 2

五. 面向对象编程

1. 基本介绍

(1) 面向过程(Procedure Oriented Programming,POP):以程序执行过程为设计流程的编程思想

(2) 面向对象(Object Oriented Programming,OOP):以事物为中心的编程思想

(3) 什么是对象(Object)?

a) 现实世界中的对象:① 属性;②行为

(4) 对象的例子:

a) 波斯猫   属性:品种、颜色、大小;行为:叫、捉老鼠

b) 吉普车   属性:类型、用途;行为:发动、停车

(5) 类(class):某种类型集合的描述

(6) 属性:类本身的一些特性

(7) 方法:类所能实现的行为

(8) 类的定义:

class ClassName:

__init__(self)   # 构造函数:初始化对象的各属性

# self代表类的实例

# __init__(self)中self参数,不需要开发者传递,python解释器会自动把当前对象引用传递进去

2. 面向对象的特点

(1) 封装

· 将数据及相关操作打包在一起

· 支持代码复用

(2) 继承

· 子类(subclass)借用父类(superclass)的行为

· 避免重复操作,提升代码复用程度

· 定义class ClassName(SuperClassName)

(3) 多态

· 在不同情况下用一个函数名启用不同方法

· 灵活性

六. 异常处理机制

引入异常处理机制可以用来解决程序运行时的错误

语法:

七、 文件

(1) 文件的基础

1) 文件:存储在外部介质(如:硬盘)上的数据或信息的集合

2) 文本文件:一般指只有字符编码存储的文件,能够被简单的文本编辑器直接读取

3) 编码:信息从一种形式转换成另一种形式的过程

4) 常用的编码:ASCII、Unicode、UTF-8等

5) 多行文本,用 表示换行

(2) 文件的操作

步骤IPO:打开文件→操作文件(读写等)→关闭文件

1) 打开文件:建立文件与程序的关联

open(filename,mode)  # filename:文件名(包括路径);mode:打开模式

2) 操作文件:写入、读取等

· 写入操作:从计算机内存向文件写入数据

  • write()  #将文本数据写入文件中

  • writelines()  # 将字符串列表写入文件中

· 读取操作:从文件中读取数据到计算机内存中

o read()  # 返回值为包含整个文件内容的一个字符串

o readline()  # 返回值为文件下一行内容的字符串

o readlines()  # 返回值为整个文件内容的列表,每项是以换行符为结尾的一行字符串

# 1. read()

content = f.read()   # 文本整体当成字符串

f.close()

print(content)

# 2. readline()

line = f.readline()  # 每次只读1行数据

print(line)

# 3. readlines()

lines = f.readlines()  # 读取文件的所有行存入列表中,每一行是一个元素

print(lines)

o 文件的遍历

# 按行输出1:

for line in f.readlines():

print('read:{}'.format(line))   # 处理一行数据

f.close()

# 按行输出2:

for line in f:

print('read:{}'.format(line))

f.close()

3) 关闭文件:终止程序与文件的关联

close()

4) 使用with语句操作文件对象

with open('file_name') as somefile:

for line in somefile:

print(line)

使用with语句,不管在处理文件过程是否发生异常,都能保证with语句执行完毕后关闭文件。不需要close()语句。

八、库/模块

调用:① 库.函数();② 对象.属性

(1). keyword库

#=============查看系统(Python 3.x)保留字=============

# 导入模块

import keyword

# keyword帮助文档

help(keyword)

# Python 关键字列表

print(keyword.kwlist)

keyword.kwlist

# 判断字符串是否是 Python 关键字

keyword.iskeyword('and')

keyword.iskeyword('has')

(2). math库

https://docs.python.org/3/library/math.html

# ====Python库操作练习=====

import math

math.fsum(l1)

math.pi

math.floor(2.2)

(3). datetime库

1) 处理时间的标准函数库datetime

2) datetime.now()  # 获取当前日期和时间

3) 字符串→datetime:datetime.strptime()  # 解析parse时间字符串

4) datetime→字符串:datetime.strftime()  # 格式化format为字符串显示

a) 日期时间格式参考:https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior

5) isocalender():返回年,周数,及周几

a) 更多操作参考:https://docs.python.org/3/library/datetime.html#module-datetime

# ======时间函数模块=======

import datetime

now = datetime.datetime.now()   # 模块.函数()

now

type(datetime.datetime.now())

now.day   # 对象.元素

# strptime 解析时间字符串为日期类型parse

# Y 大写的为4位格式,y 小写的为2位格式

datetime.datetime.strptime('2019/07/05',format('%Y/%m/%d'))

datetime.datetime.strptime('19-07-05',format('%y-%m-%d'))

datetime.datetime.strptime('2019-07-05',format('%Y-%m-%d'))

now.isocalendar()  # 输出年份和周数 (2019, 29, 2),2019年第29周的周二

# strftime 将时间类型类型转换为字符串类型format

datetime.datetime.strftime(now, '%d/%m/%Y')

(4). random模块

random模块用于生成随机数

常用函数

更多random模块的方法参考:https://docs.python.org/3/library/random.html

# ======随机数模块练习========

import random

random.random()  # 生成一个[0,1)间的随机浮点数

random.uniform(1, 10)  # 生成一个[a,b]间的随机浮点数

random.randint(1, 10)  # 生成一个[a,b]间的随机整数

l = list(range(10))  # 生成一个[0,10)的列表

random.choice(l)   # 从列表l中随机返回一个元素

random.shuffle(l)  # 将列表中的元素随机打乱

l

random.sample(l, 4)  # 从指定列表中随机获取4个元素

random.sample(list(range(1, 7)), 2)

(5). matplotlib模块

matplotlib是一个数据可视化函数库
pip/conda install matplotlib  # 终端安装

matplotlib的子模块pyplot提供了了2D图表制作的基本函数

例子:https://matplotlib.org/gallery.html

1) matplotlib绘制散点图:

import matplotlib.pyplot as plt  # x,y分别是x坐标和y坐标的列表

plt.scatter(x,y)

plt.show()

2) matplotlib绘制直方图

import matplotlib.pyplot as plt  # x,y分别是x坐标和y坐标的列表

plt. hist(data, bins)  # data:数据列表;bins:分组边界

plt.xticks()  # 设置x坐标的坐标点位置及标签

plt.title()  # 设置绘图标题

plt.xlabel(),plt.ylabel()  # 设置坐标轴的标签

(6). NumPy模块

1) NumPy(Numeric Python):用Python实现的科学计算库

包括:

· 强大的N维数组对象

· 成熟的科学计算库

· 实用的线性代数、随机数生成函数等

2) NumPy的操作对象是多维数组ndarray

·  ndarray.shape数组的维度

3) 创建数组:np.array(<list>), np.arange()

4) 改变数组形状reshape()

5) NumPy创建随机数组

· np.random.randint(a, b, size)  # 创建[a,b)间形状为size的数组

例如,

6) NumPy基本运算

以数组为对象进行基本运算,即向量化操作

例如,

· np.histogram()  # 输出直方图的统计结果

(7). JSON模块

1) JSON格式

· JSON(JavaScript Object Notation)是一种轻量级数据交换格式

· 可以对复杂数据进行表达和存储,易于阅读和理解

· 规则:

① 数据保存在键值对中

② 键值对之间由逗号分隔

③ 花括号(字典)用于保存键值对数据组成的对象

④ 方括号(列表)用于保存键值对数据组成的数组

· 采用对象、数组方式组织起来的键值对可以表示任何结构的数据

· json格式是互联网上主要使用的复杂数据格式之一

2) JSON库

· JSON库是处理JSON格式的Python标准库

· 两个过程:

o 编码(encoding),将Python数据类型转换成JSON格式的过程

o 解码(decoding),从JSON格式中解析数据对应到Python数据类型的过程

(8). CSV模块

1) CSV格式

· csv(Comma-Separated Values) 是一种通用的、相对简单的文件格式

· 在商业和科学领域上广泛使用

· 规则

① 以行为单位

② 每行表示一条记录

③ 以英文逗号分隔每列数据(如果数据为空,逗号也要保留)

④ 列名通常放置在文件第一行

2) CSV库

CSV文件读取

import csv

csv.writerow(list)  #将列表中的元素写入文件的一行中

(9). os模块

os模块提供了与系统、目录操作相关的功能,不受平台的限制

# ======os模块中的join()方法练习======

import os

l = [1, 2, 3, 4, 5]

l

l = ['1', '2', '3', '4', '5']

l

'+'.join(l)

eval('+'.join(l))

(9). requests模块

· requests模块是一个简洁且简单的处理HTTP请求的工具

· 支持非常丰富的链接访问功能,包括URL获取,HTTP会话,Cookie记录等

· requests网页请求

· requests对象属性

更多方法参考:https://2.python-requests.org/en/master/

(10). BeautifulSoup模块
1) 网页解析

· 结构化解析

· DOM(Document Object Model),树形结构

2) BeautifulSoup解析网页

a) BeautifulSoup用于解析HTML或XML

b) 安装 pip install beautifulsoup4

c) 导入 from bs4 import BeautifulSoup

d) 使用步骤

· 创建BeautifulSoup对象

bs=BeautifulSoup(url,

html_parser,   # 指定解析器

encoding     # 指定编码格式(确保和网页编码格式一致)

)

· 查询节点

o find  #找到第一个满足条件的节点

o find_all,找到所有满足条件的节点

例:<a href='a.html' class='a_link'>next page</a>

可按节点类型、属性或者内容访问

① 按类型查找节点

bs.find_all('a')

② 按属性查找节点

bs.find_all('a',href='a.html')

bs.find_all('a',href='a.html',string='next page')

bs.find_all('a',class_='a_link')    #注意:是class_

或者:bs.find_all('a',{'class':'a_link'})

(11). Pandas模块

1) 什么是Pandas

· Pandas是一个强大的分析结构化数据的工具集

· 基础是Numpy,提供了高性能矩阵的运算

· 应用:数据挖掘、数据分析

o 如,学生成绩分析、股票数据分析等

· 提供数据清洗功能

2) Pandas的数据结构

· Series:类似一维数组的对象

o 通过list构建Series:ser_obj = pd.Series(range(1,10))

o 由数据和索引组成:① 索引在左,数据在右;② 索引时自动创建的

o 获取数据和索引:ser_obj.index, ser_obj.values

o 预览数据:ser_obj.head(n), ser_obj.tail(n)

o 通过索引获取数据:ser_obj[idx]

o 索引与数据的对应关系仍保持在数组运算的结果中

o 通过dict构建Series

o name属性:ser_obj.name, ser_obj.index.name

· DataFrame:类似多维数组/表格数据(如,excel和R中的data.frame)

o 每列数据可以是不同的类型

o 索引包括列索引和行索引

o 通过ndarray构建DataFrame

o 通过列索引获取列数据(Series类型):df_obj[col_idx]或df_obj.col_idx

o 增加列数据,类似dict添加key-value:df_obj[new_col_idx]=data

o 删除列:del df_obj[col_idx]

3) Pandas的数据操作

· DataFrame索引操作

o 列索引:df_obj['label']

o 不连续索引:df_obj[['label1','label2']]

· 排序

o sort_index,索引排序:对DataFrame操作时注意轴方向

o 按值排序:sort_value(by='label')

4) Pandas统计计算和描述

· 常用的统计计算

o sum, mean, max, min……

o axis=0按列统计,axis=1按行统计

o skipna # 排除缺失值,默认为True

o idmax, idmin, cumsum

· 统计描述

o describe  #产生多个统计数据

5) Pandas数据清洗

· 处理缺失数据

o dropna()  #丢弃缺失数据

o fillna()  #填充缺失数据

· 数据过滤

o df[filter_condition]  #依据filter_condition对数据进行过滤

6) Pandas数据可视化

· Pandas提供了内建的绘图功能(基于matplotlib)

o plot(kind,x,y,title,figsize)  # x,y横纵坐标对应的数据列;title图像名称;figsize图像尺寸

· 保存图片:plt.savefig()

· 更多例子参考:https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html

九、总结

(0)

相关推荐