当前位置:   article > 正文

Python_pythoncsdn

pythoncsdn

目录

一、Python基础

语言分类

一些小知识


在cmd中运行python代码

快捷键

Debug

打断点+Debug运行

常用设置

更改字体

文件操作

单行注释和多行注释


Python中的3种波浪线和PEP8


变量(内存地址的别名)


命名规范


建议性命名

Python中变量的定义使用的是下划线连接

变量的数据类型

数字类型

非数字类型

type()函数——可以获取变量的数据类型

# 整型
age = 11
print(type(age))
# 浮点型
height = 3.14
print(type(height))
# 布尔型
isGirl = True
print(type(isGirl))
# 字符型
name = "ann"
print(type(name))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
'
运行

输入

使用input()函数——最终保存到变量中的数据类型一定是str

类型转换

age = input("请输入年龄:")
print(type(age), age)
# 进行类型转换
age1 = int(age)
print(type(age), age)
print(type(age1), age1)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
'
运行

格式化输出


%.2f保留两位小数
%3d整数一共占3位
%d%%显示为90%

name = '小米'
age = 12
height = 157.3
Id = 1
num = 90
print("我的名字是%s" % name)
print("我的年龄是%d" % age)
print("我的身高是%f" % height)
print("我的名字是%s,我的年龄是%d,我的身高是%.2f" % (name, age, height))  # %.2f保留两位小数
print("我的id是%03d" % Id)  # %3d整数一共占3位
print("及格率是%d%%" % num)  # %d%%显示为90%
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
'
运行

f-字符串的格式化方法

name = '小米'
age = 12
height = 157.3
Id = 1
num = 90
print(f'我的名字是{name},我的年龄是{age},我的身高是{height},我的id是{Id},\n及格率是{num}')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
'
运行

字符串.format()模式

name = '小米'
age = 12
height = 157.3
Id = 1
num = 90
print('我的名字是{},我的年龄是{},我的身高是{}cm,我的id是{},\n及格率是{}%'.format(name, age, height, Id, num))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
'
运行

运算符

算术运算符

比较运算符

逻辑运算符

二、流程控制结构

判断语句(if elif else)

if-else结构

user = input("输入用户名:")
psw = input("请输入密码:")
if user == 'admin' and psw == '123456':  # 一定要注意input获取的是str
    print(f'欢迎{user}登录')
else:
    print('登录信息错误')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

if-elif-else结构

score = int(input("输入你的成绩:"))
if score >= 90:
    print('优')
elif score >= 80:
    print('良')
elif score >= 70:
    print('中')
elif score >= 60:
    print('差')
else:
    print('不及格')

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
'
运行


如果只使用if-else

score = int(input("输入你的成绩:"))
if score >= 90:
    print('优')
if 80 <= score < 90:
    print('良')
if score >= 70 and score < 80:
    print('中')
if 60 <= score < 70:
    print('差')
else:
    print('不及格')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
'
运行

if嵌套

pwd = 123456
num = 1000
pwduser = int(input("请输入密码:"))
if pwduser == pwd:
    get_num = int(input("请输入取款金额:"))
    if get_num <= num:
        print(f'取款成功!账户余额为{num-get_num}')
    else:
        print('余额不足!')
else:
    print("密码错误!")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
'
运行

案例(出拳游戏)

import random
num = random.randint(1, 3)  # 电脑出拳
# 1-剪刀 2-石头 3-布
numuser = int(input('请输入你要出(1-剪刀 2-石头 3-布):'))
print(f'对方出的是{num}')
if (numuser == 1 and num == 3) or (numuser == 2 and num == 1) or (numuser == 3 and num == 2):
    print("你赢了!")
elif numuser == num:
    print('平局')
else:
    print('你输了')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
'
运行

循环

死循环和无限循环

案例(计算100以内偶数的和)

i = 0
sum = 0
while i < 101:
    sum += i
    i += 2
print(sum)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
'
运行

for 变量 in 容器



for 变量 in range(n)–做指定次数的循环



range()变形



continue和break

user_string = 'goodgirl'
for n in user_string:
    if n == 'i':
        continue
    print(n)
  • 1
  • 2
  • 3
  • 4
  • 5
'
运行

三、数据序列(容器)

字符串



在这里插入图片描述

下标(支持从右开始的负数标号)



切片

str1 = 'abcdefg'
# 获取abc
print(str1[0:3:1])
print(str1[0:3])  # 步长为1可以不写,最后一个冒号也不写
print(str1[:3])  # 开始为0,可以不写,但冒号必须有
# 获取efg
print(str1[4:7])
print(str1[4:])
print(str1[-3:7])
# 获取aceg
print(str1[0:7:2])
print(str1[::2])
# 获取全部字符串
print(str1[:])
# 获取全部字符串的逆序
print(str1[::-1])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
'
运行

字符串的查找方法——find

str_1 = "hello w
# 查找第一个to的位置    
num = str_1.find
print(num)      
# 查找第二个to的位置,从上一
num1 = str_1.fin
print(num1)     
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

字符串的替换方法——replace

注意:原来字符串没有发生变化

str1 = "hello world hello"
# 将第二个hell替换为HELLO
# 1.先将所有都替换为HELLO
str2 = str1.replace('hello', 'HELLO')
# 2.再将第一个的HEEL换回hello
str3 = str2.replace('HELLO', 'hello', 1)
print('str1:', str1)
print('str2:', str2)
print('str3:', str3)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
'
运行

字符串的拆分——split

str1 = "hello world and hello everyone"
# 按照空白字符,分割两次
list1 = str1.split(maxsplit=2)
# 按照hello分割
list2 = str1.split('hello')
print(list1)
print(list2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
'
运行

字符串的链接——join



列表list

定义

  1. 类实例化(不经常用)

  2. 类型转换(将其他容器转换为list)

  3. 直接使用[ ](经常使用)

下标和切片

列表查找方法——index()

容器中是否存在——in

列表统计出现次数——count()

my_list = [1, 2, 2, 3, 5, 6]
# 直接my_list.index(4)会因为不存在报错
if my_list.count(4) > 0:
    num = my_list.index(4)
    print(num)
else:
    print("不存在")

if 4 in my_list:
    num1 = my_list.index(4)
    print(num1)
else:
    print("不存在!")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
'
运行

添加数据的方法

my_list = ['可乐']
print(my_list)
# 在列表后添加
my_list.append('雪碧')
print(my_list)
# 在指定位置添加
my_list.insert(1, 2)
print(my_list)
# 合并两个列表
list1 = ['芬达', '百事']
my_list.extend(list1)
print(my_list)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
'
运行

列表修改操作——列表[下标] = 数据

在这里插入图片描述

列表删除操作

my_list = [1, 3, 3, 4, 6, 8]
print(my_list)
# 删除最后一个数据
num = my_list.pop()
print(my_list)
print("删除的数据为:", num)
# 删除下标为1
my_list.pop(2)
print(my_list)
# 删除数据为4的数据
my_list.remove(6)
print(my_list)
# 清空
my_list.clear()
print(my_list)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
'
运行

列表逆置和复制——reverse() and copy()

逆置

my_list = [1, 3, 3, 4, 6, 8]
# 使用切片
my_list1 = my_list[::-1]
print(my_list)
print(my_list1)
# 使用reverse()
my_list.reverse()
print(my_list)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
'
运行

复制


列表排序——sort()

my_list = [1, 3, 3, 2, 16, 1]
my_list.sort()
print(my_list)
my_list.sort(reverse=True)
print(my_list)
  • 1
  • 2
  • 3
  • 4
  • 5
'
运行

列表嵌套

my_list = [[1, 3, 3, 2, 16, 1], ['李四', '12']]
print(len(my_list))
print(my_list[0])
print(my_list[0][0])
print(my_list[1][0][1])

# 给李四添加性别
my_list[1].append('女')
print(my_list[1])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
'
运行

列表去重(面试)

# 列表去重
my_list1 = [1, 2, 2, 1, 3]
my_list2 = []
for i in my_list1:
    if i in my_list2:   # my_list2.count(i) > 0
        continue    # pass
    else:
        my_list2.append(i)
print('去重前:', my_list1)
print('去重后:', my_list2)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
'
运行


2.

元组——tuple

定义

  1. 使用类实例化方法
  2. 直接定义

注意


字典——dict


添加和修改数据


删除数据——del


获得对应的数据——get

my_dict = {'name': '小红', 'age': 12, 'isMen': False, 'hobby': ['学习', '画画']}
# 获取'sex'
print(my_dict.get('sex'))
# 获取第二个爱好
print(my_dict.get('hobby')[1])
print(my_dict['hobby'][1])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
'
运行

字典的遍历

my_dict = {'name': '小红', 'age': 12, 'isMen': False, 'hobby': ['学习', '画画']}
# 遍历字典的键
for a in my_dict:
    print(a)
print('~~~~~~~~~~~~~')
for b in my_dict.keys():
    print(b)
print('~~~~~~~~~~~~~')
# 遍历字典的值
for c in my_dict.values():
    print(c)
print('~~~~~~~~~~~~~')
# 遍历键值对
for d,e in my_dict.items():
    print(d, e)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
'
运行

容器部分补充总结

四、函数

函数基础

函数的定义和调用——def

函数文档注释

函数参数

函数返回值



变量进阶

引用介绍



可变类型和不可变类型

面试题


交换两个变量的值和拆包

交换两个变量
  1. 常规方法引入第三个变量
  2. python独有
组包和拆包

# 组包
c = a, b
print(type(c), c)
# 拆包
c = a, b
print(a, b)
my_list = [1, 3, 4]
a, b, c = my_list
print(a, b, c)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

局部变量和全局变量

局部变量

全局变量

函数进阶

函数返回多个数据值(接收为元组)

def fun1(a, b):
    sum1 = a + b
    sum2 = a - b
    return sum1, sum2


result = fun1(1, 2)
print(result)
print(result[0], result[1])
# 拆包
x, y = result
print(x, y)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
'
运行

函数传参方式


缺省参数(默认参数)


多值参数(可变参数/不定长参数)


print函数



匿名函数(lambda很少使用)




# 定义一个匿名函数求两个数的乘积
fun1=lambda a,b: a*b
print(fun1(2,3))

# 定义一个匿名函数,参数为字典,返回字典中键为age的值
dict2 = {'name':'ann', 'age':'1'}
fun2=lambda dict1:dict1.get('age')  # dict['age']
print(fun2(dict2))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
'
运行


匿名函数作为函数参数——列表中的字典排序

列表的排序,默认是对列表中的数据进行比大小的,可以对数字类型字符串进行比大小,但是对于字典来说,就不知道该怎么比大小,此时,我们需要使用sort 函数中的key这个参数,来指定字典比大小的方法key这个参数,需要传递—个函数,一般是匿名函数

五、面向对象(OOP)

类和对象

类的组成

类的抽象(类的设计)

面向对象基础语法

面向代码的步骤


案例:小猫爱吃鱼

需求:小猫爱吃鱼,小猫爱喝水

# 需求小猫爱吃鱼,小猫爱喝水
# 创建类
class Cat:
    def eat(self):
        print('小猫爱吃鱼!')
    def drink(self):
        print('小猫爱喝水!')
# 创建对象
blank_cat = Cat()
# 通过创建的对象调用类中的方法
blank_cat.eat()
blank_cat.drink()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
'
运行

self说明

属性的操作


魔法方法_init_方法的使用

魔法方法_str_方法的使用



魔法方法_del_方法的使用


案例

class People:
    def __init__(self, name, weight):
        self.name = name
        self.weight = weight

    def __str__(self):
        return f'{self.name}体重为{self.weight}公斤'

    def run(self):
        print('跑步')
        self.weight -= 0.5

    def eat(self):
        print('吃饭')
        self.weight += 1
xiaoming = People('小明',75.0)
print(xiaoming)
xiaoming.eat()
print(xiaoming)
xiaoming.run()
print(xiaoming)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
'
运行

封装案例——存放家具

class HouseItem:    # 家具类
    def __init__(self,name,area):
        self.name = name
        self.area = area

    def __str__(self):
        return f'{self.name}家具,占地{self.area}平方米'

class House:
    def __init__(self,name,area):
        self.name = name
        self.total_area = area
        self.free_area = area
        self.item_list = []
    def __str__(self):
        return f'{self.name}户型,总面积为{self.total_area},剩余面积为{self.free_area},家具有{self.item_list}'
    def add_item(self,item):
        if self.free_area >= item.area:
            self.item_list.append(item.name)
            self.free_area -= item.area
            print(f'{item.name}家具添加成功!!')
        else:
            print('剩余面积不足,需要换房子了!!')
# 创建家具对象
bed = HouseItem('席梦思',4)
chest = HouseItem('衣柜',2)
table = HouseItem('餐桌',1.5)
print(bed)
print(chest)
print(table)
# 创建房子对象
house = House('三室一厅',127)
house.add_item(bed)
print(house)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
'
运行

在这里插入图片描述

私有属性和私有方法

封装、继承、多态

面向对象三大特性

继承

案例


重写——覆盖和扩展

覆盖

扩展


多态

属性和方法

对象的划分

  1. 实例对象(实例)
  2. 类对象(类)

属性的划分

  1. 实例属性
  2. 类属性

练习

class Dog:
    # 定义类属性
    count = 0
    # 定义实例属性
    def __init__(self,name):
        self.name = name
        Dog.count += 1


print(Dog.count)
dog1 = Dog('coco')
dog2 = Dog('豆豆')
print(Dog.count)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
'
运行

方法的划分

  1. 实例方法(最常用)

  2. 类方法(会用)


  3. 静态方法(基本不用)

练习

六、文件操作

文件的介绍

文件操作(open,read,close)

1.打开文件

2.读或写文件

# 1.打开文件
f = open("a.text",mode="r",encoding="utf-8")
# 2.写文件
# f.write('这次是什么!')
print(f.read())
# 3.关闭文件
f.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.关闭文件

使用with open 打开文件

with open("a.text","r",encoding="utf-8") as f:
    # f.write('这次是with open!')
    print(f.read())
  • 1
  • 2
  • 3

按行读取内容(readline)



json文件的处理

json 也是一个文本文件,可以使用read()和 write()方法,只是使用这两个方法,不方便,所以对 json 文件有自己独特的读取和写入的方法
常用在做测试的时候,将测试数据定义为 json 文件格式,使用代码读取json 文件,即读取测试数据,进行传参(参数化)

json文件介绍


json文件的语法介绍

{
  "name": "小鸣",
  "age": 18,
  "sex": "man",
  "hobby": ["listening","游戏","睡觉"],
  "address": {
    "country": "china",
    "city": "上海"
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

# 1.导入json
import json
# 2.读打开文件
with open("a.json",encoding="utf-8") as f:
    # 3.读取文件
    result = json.load(f)
    print("类型为:{}".format(type(result)))
    print(result.get("name"))
    print(result.get("address").get("city"))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

json案例

[
  {"desc": "正确的用户名密码","username": "admin","password":"123456",",expect":"登录成功"},
  {"desc" :"错误的用户名", "username":"root","password" :"7123456","expect" : "登录失败!"},
  {"desc":"错误的密码","username":"admin","password" :"123123", "expect": "登录失败"}
]
  • 1
  • 2
  • 3
  • 4
  • 5
import json
list = []
def show_login():
     with open("a.json",encoding="utf-8") as f:
       pub = json.load(f) # 读取返回为列表
       for i in pub:
           # print(i)
           # print((i.get("username"),i.get("password"),i.get("expect")))
           # print多加一层括号结果就打印出元组形式
           list.append((i.get("username"),i.get("password"),i.get("expect")))
     return list
print(show_login())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

json的写入(json.dump())



小知识

七、异常

异常的介绍

异常捕获(重要)



捕获多个指定的异常

异常捕获的完整格式

try:
     a = input("输入数字:")
     num = int(a)
     print(num)
     c = 1/num
     print(c)
except Exception as a:
     print(f"类型信息:{a}")
else:
     print("没有异常")
finally:
     print("不管有无异常")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
'
运行

八、模块和包

模块

模块导入




模块的导入顺序

__name__使用


九、UnitTest框架

UnitTest基本使用

介绍

unitest组成

TestCase(测试用例)

'''代码目的:学习TestCase(测试用例)书写方法'''
# 1.导包
import unittest
# 2.自定义测试类,需要继承unitest模块中的TestCase类
class TestDemo(unittest.TestCase):
    # 3.书写测试方法,测试方法必须以test_开头
    def test_method1(self):
        print("method1执行!")
    def test_method2(self):
        print("method2执行!")
# 4.执行用例
# 4.1将光标放在类名后运行会执行类中所有的测试方法
# 4.2将光标放在方法名后运行只执行当前的方法
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
'
运行

常见问题

TestSuite(测试套件) & TestRunner(测试执行)

方式二(多看看)

TestLoader(测试加载)

'''代码目的:学习TestLoader(测试加载)书写方法'''
# 1.导包
import unittest
# # 2.实例化(创建对象)加载对象并添加用例
# # unittest.TestLoader().discover('用例所在的路径','用例的代码文件名')
# # 用例所在的路径,建议使用相对路径,用例的代码文件名可以使用 *(任意多个任意字符)通配符
# suite = unittest.TestLoader().discover("./case","test*.py")

# 2.使用默认加载对象并添加用例
suite = unittest.defaultTestLoader.discover("case","test*.py")
# 3.实例化执行对象并执行
unittest.TextTestRunner().run(suite)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Fixture(测试夹具)

方法级别(掌握)
类级别(掌握)
模块级别(掌握)

UnitTest断言(asert)

参数化

在这里插入图片描述

pip install parameterized

------------login,py------------

def login(username,password):
    if username == "admin" and password == "123456":
        return "登陆成功啦!"
    else:
        return "登录失败!!!"
  • 1
  • 2
  • 3
  • 4
  • 5
'
运行
# 1.导包
import unittest
from login import login
from parameterized import parameterized

# 4.组织数据
data = [("admin","123456","成功"),("ad","123456","失败"),("admin","123","失败")]
# 2.创建测试类
class TestLogin(unittest.TestCase):
    # 4.传参(@装饰器)
    @ parameterized.expand(data)
    # 3.书写测试方法(用到的测试数据用变量代替)
    def test_login(self,username,password,expect):
        self.assertIn(expect,login(username,password))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

json参数化

[
  {
    "username":"admin",
    "password":"123456",
    "expect":"成功"
  },
  {
    "username":"ad",
    "password":"123456",
    "expect":"失败"
  },
  {
    "username":"admin",
    "password":"123",
    "expect":"失败"
  }
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
# 1.导包
import json
import unittest
from login import login
from parameterized import parameterized

# 4.组织数据
def get_data():
    with open("data.json",encoding="utf-8") as f:
        list = []
        result = json.load(f)  # 返回结果为[{},{}],想要的结果为[(),()]
        for i in result:
            list.append((i.get("username"),i.get("password"),i.get("expect")))
    return list
# 2.创建测试类
class TestLogin(unittest.TestCase):
    # 4.传参(@装饰器)
    @ parameterized.expand(get_data())
    # 3.书写测试方法(用到的测试数据用变量代替)
    def test_login(self,username,password,expect):
        self.assertIn(expect,login(username,password))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

生成HML测试报告

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/930401
推荐阅读
相关标签
  

闽ICP备14008679号