1. Python入门到实践基础知识

1.配置等信息

安装省略

  1. 查看python安装路径 type -a python输出:python3 is /usr/local/bin/python3
  2. 配置Sublime Text,选择菜单Tools=>Build System=>New Build System会打开一个新的配置文件,输入(cmd为python的安装路径)
{
    "cmd":["/usr/local/bin/python3","-u","$file"],
}

配置文件命名为“Python3.sublime-build”,直接保存到默认目录

2.变量和简单数据类型

  1. 字符串既可以使用单引号括起来,又可以使用双引号括起来,这样在字符串中可以输入单引号和双引号
  2. 字符串单词首字母变大写

    name = "ada lovelace"

    name.title() 输出 Ada Lovelace

    字符串全部大些 name.upper()

    字符串全部小写 name.lower()
  3. 合并字符串(相加)
  4. 打印空白 \t 打印换行 \n

    删除空白 rstrip()方法(删除末尾的空白),这种方法没有彻底删除,要彻底删除,需要重新赋值 name = name.rstrip()

    lstrip()删除字符串
  5. 数字 乘* 指数** 3**2 = 9
  6. 浮点数 ,相加结果包含的小数位数可能是不确定的

    0.2+0.1 = 0.30000...0004(所有语言都会又这种情况,暂时忽略多余的小数位数即可)
  7. str(),字符串和数字相连,使用str(数字)将数字转换成字符串
    8.注释

    使用#号标示
    9.Python之禅

    在解释器中执行命令import this,会打印出编写的几条原则
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

3.列表 []

例:bicycles=['trek','cannondale','redline']

  1. 访问列表元素
    下标,bicycles[index]
  2. 修改、添加和删除元素

    修改 bicycles[0] = 'ducati';

    添加(末尾追加)bicycles.qppend('ducati')

    插入元素 bicycles.insert(0,'ducati')

    删除 del bicycles[0]

    使用pop()删除元素,删除列表末尾的元素(从栈顶取出来)get_last = bicycles.pop()

    弹出列表中任何位置的元素,pop(index) 弹出后元素就不再列表中了

    根据值删除元素bicycles.remove('ducati')(如果该值在列表中存在多个,只删除第一个值)
  3. 组织列表

    使用方法sort()对列表进行永久性排序,按照字母顺序排序,传如参数reverse=True,按照与字母顺序相反的顺序排列bicycles.sort(reverse=True)

    使用函数sorted对列表进行临时排序,直接打印new_bycycles=sorted(bicycles,可以传reverse=True),new_bicycles排序是变化了的,但是bicycles的顺序是没有变化的

    倒着打印列表,bicycles.reverse()

    列表长度 len(cars)
  4. 列表索引

    索引-1总是返回最后一个列表元素(当列表为null时会报错)

4.操作列表

  1. 遍历整个列表
for bicycle in bicycles:
    print(bicycle)
  1. 创建数值列表

    使用函数range()生成一系列数字 for value in range(1,5):(会打印1,2,3,4不会打印5)

    将range()作为list()参数,输出一个数字列表(输出[1,2,3,4],range()直接赋值打印的还是range())

    min(digits) 取出数字列表的最小值

    max(digits) 取出数字列表的最大值

    sum(digits) 输出数字列表的和

    列表解析squares = [value**2 for value in range(1,11)],for循环的值赋值给前面的value
  2. 使用列表的一部分(切片)

    players = [], players[0:3] 输出下标0-3的值(不包含3),下标对应0,1,2

    输出第2-4个元素,使用players[1:4],输出下标1,2,3(不包含4)

    如果没有指定第一个索引,从列表开头开始players[:4]输出下标0,1,2,3

    如果提取第三个元素到列表末尾的所有元素,使用players[2:]

    提取最后单个元素 players[-3:]

    遍历切片 for player in players[:3]:(遍历前三个值)

    赋值列表new_players = players[:],不能使用new_players = players,直接等于,俩个变量指向了同一个列表,会同时变化
  3. 元组(不可变的列表被称为元组)

    定义,使用()圆括号,列表使用方括号 dimensions = (200,50),使用下标获取对应的元素dimensions0

    遍历元组中的所有值,使用for循环 for dimension in dimensions:

    修改元组变量,不能修改远足的元素,但可以给存储元组的变量赋值dimensions = (400,100),重新赋值(在生命周期中,一组值不可变,使用元组)
  4. 设置代码格式

    每级缩进四个空格

    使用空行将不同部分分开

5. if语句

例:

for car in cars:
   if car == 'bmw':


检查不想等 !=

  1. 检查多个条件

    使用and age_0 >=21 and age_1>=21

    使用or age_0>=21 or age_1 >=21

    检查特定值是否包含在列表中 if 'bw' in cars:

    检查特定值不包含在列表中 if 'bw' not in cars:
  2. if-else语句(if-elif-else)
if age >= 18:

else:

  1. 确定列表不是空的
cars = []
if cars:
#不为空
else:
#为空

6.字典(键-值对)

  1. 简单的字典 alien_ = {'color':green,'points':5} alien_0['color']输出green
  2. 添加键-值对 alien_0['x_position'] = 0,alien_0['y_position']=25
  3. 创建一个空字典 alien_0 ={},再添加键-值对,alien_0['color'] = 'green',alien_0['points'] = 5
  4. 修改字典中的值 alien_0['color'] = 'yellow'
  5. 删除键-值对(永远删除) del alien_0['points']
  6. 遍历字典 for key,value in user_0.items()
  7. 遍历字典中所有键 for key in user_0.keys():
  8. 判断字典是否包含某个键 if 'color' in user_0.keys()
  9. 按顺序遍历字典中所有键(获取字典的元素时,获取顺序时不可预测的),按顺序使用sorted()函数,for key in sorted(user_0.keys())
  10. 遍历字典中所有值(不考虑是否有重复)for value in user_0.values():

    获取不重复的值,for value in set(user_0.values())(获取到的接口时一个不重复的列表)
  11. 嵌套(将一系列字典存储在列表中,或将列表作为值存储在字典中)

    例字典列表
alien_0={'color':'green','point':5}
alien_1={'color':'yellow','point':10}
alien_2={'color':'red','point':15}
aliens = [alien_0,alien_1,alien_2]


列表存储在字典中

pizza = {
    'crust':'thick',
    'topings':['mushrooms','extra cheese'],
}


字典中存储字典

users = {
    'aeinstein': {
        'first': 'albert', 
        'last': 'einstein', 
        'location': 'princeton', 
    },
    'mcurie': {
        'first': 'marie', 
        'last': 'curie',
        'location': 'paris', 
    }, 
}

遍历:for username,user_info in users.items():

7.用户输入和while循环

  1. input()函数工作原理
    等待用户输入一些文本,获取用户输入后,将其存入到一个变量中

    message = input("这里是让用户输入的提示语:")

    提示语换行操作
prompt = "If you tell us who you are, we can personalize the messages you see." prompt += "\nWhat is your first name? "
name = input(prompt)
  1. 用int()来获取数值输入(input是获取字符串输入)(函数int(),让python将输入视为数值,函数int()将数字的字符串转换为数值表示)
>>> age = input("How old are you? ")
How old are you? 21 >>> age = int(age)
>>> age >= 18 
True
  1. 求模运算符(%)返回余数
  2. while循环
current_number = 1
while current_number <= 5:
    current_number+=1


输入退出

message = ""
while message !='quit':
    message = intput("请输入:")


使用break退出循环(在任何Python循环中都可使用break语句。例如,可使用break语句来退出遍历列表或字典 的for循环。)

while True:
    message = input("请输入")
    if message == 'quit':
        break


在循环中使用continue(根据条件测试结果决定是否继续执行循环)

current_number = 0
while current_number < 10:
    current_number +=1
    if current_number % 2 == 0:
        #让python忽略余下代码,并返回到循环的开头
        continue
    print(current_number)

最终打印1,3,5,7,9

进入无限循环,终端使用command(ctrl)+c,或关闭窗口,编辑器直接关闭窗口

  1. 使用while循环来处理列表和字典

    例验证用户
# 首先,创建一个待验证用户列表
# 和一个用于存储已验证用户的空列表 
unconfirmed_users = ['alice', 'brian', 'candace']
confirmed_users = []
# 验证每个用户,直到没有未验证用户为止
# 将每个经过验证的列表都移到已验证用户列表中 
while unconfirmed_users:
    current_user = unconfirmed_users.pop() 
    print("Verifying user: " + current_user.title())
    confirmed_users.append(current_user)
# 显示所有已验证的用户
print("\nThe following users have been confirmed:") 
for confirmed_user in confirmed_users:
    print(confirmed_user.title())


删除包含特定值的所有列表元素(前面提到的remove()只能删除第一个,不能删除所有)

pets = ['dog', 'cat', 'dog', 'goldfish', 'cat', 'rabbit', 'cat']
print(pets)
while 'cat' in pets: 
    pets.remove('cat')
print(pets)


使用用户输入来填充字典

responses = {}
# 设置一个标志,指出调查是否继续 
polling_active = True
    while polling_active:
    # 提示输入被调查者的名字和回答
        name = input("\nWhat is your name? ")
        response = input("Which mountain would you like to climb someday? ")
        # 将答卷存储在字典中
        responses[name] = response
        # 看看是否还有人要参与调查
        repeat = input("Would you like to let another person respond? (yes/ no) ")
        if repeat == 'no': 
            polling_active = False
        # 调查结束,显示结果
        print("\n--- Poll Results ---")
        for name, response in responses.items():
            print(name + " would like to climb " + response + ".")

8.函数

  1. 定义函数

    例打印问候语的简单函数
def greet_user():
    print("hello")

greet_user()


向函数传递信息(带参函数)

def greet_user(username):
    print("hello"+username.title())
    
greet_user('jesse')


实参和形参,上面username是形参,'jesse'是形参

  1. 传递实参

    位置实参,多个参数,位置相对应(保证实参的顺序对应且正确)

    关键字实参greet_user(username='ydx',work='it')

    默认值(使用默认值时,在形参列表中必须先列出没有默认值的形参,再列出有默认值的形参)
# 指定宠物类型默认是dog
def describe_pet(pet_name, animal_type='dog'):


等效的函数调用,对于上面创建的宠物类型是dog的默认方法,举一下例子

# 一条名为Willie的小狗 
describe_pet('willie') 
describe_pet(pet_name='willie')
# 一只名为Harry的仓鼠
describe_pet('harry', 'hamster') 
describe_pet(pet_name='harry', animal_type='hamster') 
describe_pet(animal_type='hamster', pet_name='harry')
  1. 返回值

def get_formatted_name(first_name, last_name): 
"""返回整洁的姓名"""
    full_name = first_name + ' ' + last_name
        return full_name.title()
musician = get_formatted_name('jimi', 'hendrix') 
print(musician)


让实参变成可选的(给实参指定默认值空字符串)

def get_formatted_name(first_name, last_name, middle_name=''): """返回整洁的姓名"""
    if middle_name:
        full_name = first_name + ' ' + middle_name + ' ' + last_name
    else:
        full_name = first_name + ' ' + last_name
    return full_name.title()
musician = get_formatted_name('jimi', 'hendrix') 
print(musician)
musician = get_formatted_name('john', 'hooker', 'lee') 
print(musician)


返回字典

def build_person(first_name, last_name): """返回一个字典,其中包含有关一个人的信息"""
    person = {'first': first_name, 'last': last_name} 
        return person
musician = build_person('jimi', 'hendrix')
print(musician)
  1. 传递列表(参数是列表)

    在函数中修改列表,在函数中对列表所做的任何修改都是永久性的

    禁止函数修改列表(不影响原件,将列表的副本传递给函数)function_name(list_name[:]),这样不会对原列表,list_name产生影响
  2. 传递任意数量的实参
def make_pizza(*toppings)
    for topping in toppings:
        print()
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')


结合使用位置实参和任意数量实参

def make_pizza(size,*toppings):


使用任意数量的关键字实参(**表示参数为字典形式,采用arg1=value1,arg2=value2这样的形式)

def build_profile(first,last,**user_info):
    for key, value in user_info.items():

user_profile = build_profile('albert','einstein',location='princeton',field='physics')
  1. 将函数存储在模块中(代码与主程序分离,将函数存储在被称为模块的独立文件中,使用import导入到当前的程序文件中)

    导入整个模块,pizza.py中创建make_pizza函数,在pizza.py所在目录中创建另一个名为makeing_pizzas.py的文件,在making_pizzas.py文件中,使用import pizza导入,使用pizza.make_pizza(16,'pepperoni')调用方法

    导入特定的函数(使用的时候直接使用方法名,不需要函数名.方法名) from module_name import function_name:

    导入多个函数,使用逗号分割 from module_name import function_0,function_1,function2

    使用as给函数指定别名 from pizza import make_pizza as mp:(将make_pizza()重命名mp())

    使用as给模块指定别名 import pizza as p 使用p.make_pizza

    导入模块所有函数 from pizza import *

9.类

  1. 创建和使用类
    例:创建Dog类
class Dog():
    #init俩边俩个_,相当于构造方法,形参self必不可少,必须位于其他形参前面
    def __init__(self,name,age):
        """初始化属性那么和age"""(参数关联到创建的实例当中)
        self.name = name
        self.age = age
        
    def sit(self):
        """模拟小狗被命令时蹲下"""
        print(self.name.title() + " is now sitting.")
        
    def roll_over(self):
        """模拟小狗被命令时打滚"""
        print(self.name.title()+"rolled over!")


根据类创建实例(创建多个实例)

my_dog = Dog('willie',6)#创建实例
print("My dog's name is " + my_dog.name.title() + ".")#访问属性
print("My dog is " + str(my_dog.age) + " years old.")
my_dog.sit()#调用方法
  1. 使用类和实例
class Car():
    """一次模拟汽车的简单尝试""" 5
    def __init__(self, make, model, year): 
        """初始化描述汽车的属性"""
        self.make = make 
        self.model = model 
        self.year = year
        self.odometer_reading = 0#给属性指定默认值
    def get_descriptive_name(self): 
        """返回整洁的描述性信息"""
        long_name = str(self.year) + ' ' + self.make + ' ' +self.model
        return long_name.title() 9
 my_new_car = Car('audi', 'a4', 2016) print(my_new_car.get_descriptive_name())


修改属性的值

直接修改my_new_car.odometer_reading = 23

通过方法修改,创建修改方法

def update_odometer(self, mileage): 
    """将里程表读数设置为指定的值"""
    self.odometer_reading = mileage


通过方法对属性的值进行递增

def increment_odometer(self, miles):
    """将里程表读数增加指定的量""" 
    self.odometer_reading += miles
  1. 继承

    创建子类的实例时,Python首先需要完成的时给父类的所有属性赋值
# ElectricCar 是Card的子类
class ElectricCar(Car): 
    """电动汽车的独特之处"""
    def __init__(self, make, model, year): 
        """初始化父类的属性"""
        super().__init__(make, model, year) 
my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())


创建子类时,父类必须包含在当前文件中,且位于子类前面

在子类中,可添加区分子类和父类所需的新属性和方法

class ElectricCar(Car):
    """Represent aspects of a car, specific to electric vehicles."""
    def __init__(self, make, model, year):
        """电动汽车的独特之处 初始化父类的属性,再初始化电动汽车特有的属性 """
        super().__init__(make, model, year) 
        self.battery_size = 70
    
    def describe_battery(self): 
        """打印一条描述电瓶容量的消息"""
        print("This car has a " + str(self.battery_size) + "-kWh battery.")


重写父类方法(假设Car类有一个名为fill_gas_tank()的方法,它对全电动汽车来说毫无意义)

def fill_gas_tank():
    """电动汽车没有油箱"""
    print("This car doesn't need a gas tank!")


将实例用做属性(将Battery类作为参数)

class ElectricCar(Car): 
    """电动汽车的独特之处"""
    def __init__(self, make, model, year):
        """ 初始化父类的属性,再初始化电动汽车特有的属性 """
        super().__init__(make, model, year)
        self.battery = Battery()

4.导入类(将类存储在模块中,在主程序中导入所需的模块)

Car类存储在car.py模块中,导入from car import Car

一个模块中存储多个类

从一个模块中导入多个类from car import Car,ElectricCar

导入整个模块,import car 使用car.Car()

导入模块中的所有类 from moudle_name import *

在一个模块中导入另一个模块(一个模块中的类依赖于另一个模块中的类。在这种情况 下,可在前一个模块中导入必要的类。)

  1. Python 标准库(Python的内置模块)

    collections中的类OrderedDict记录键-值对的添加顺序
from collections import OrderedDict

favorite_languages = OrderedDict()

favorite_languages['jen'] = 'python' 
favorite_languages['sarah'] = 'c' 
favorite_languages['edward'] = 'ruby' 
favorite_languages['phil'] = 'python'

for name, language in favorite_languages.items(): 
    print(name.title() + "'s favorite language is " +language.title() + ".")


按照添加的顺序打印出来

random 模块包含以各种方式生成随机数的函数

from random import randint 
    x = randint(1, 6)
  1. 编码风格

    可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。

    需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import语句,再 添加一个空行,然后编写导入你自己编写的模块的import语句。

10.文件和异常

  1. 从文件中读取数据

    读取整个文件
with open('pi_digits.txt') as file_object:#open()打开指定文件,返回代表文件的对象,赋值给file_object
    contents = file_object.read()
    print(contents)


不需要手动调用close,程序会在适当的时候自动关闭

read()到达文件末尾时会返回一个空字符串,将这个空字符串显示出来就是一个空行删除这个空行,使用contents.rstrip()

指定文件路径(可指定绝对路径或相对路径),Linus和OSX中,with open('text_files/filename.text'),在Windows中使用‘\’

逐行读取

with open(filename) as file_object:
    for line in file_object:
        print(line)


每一行后面都有空白行,使用line.rstrip()去除空白行

在with代码块外,我们依然可以使用with里面创建的变量

在读取文件时,Python将其中的所有文本都解读为字符串,如果读取的是数字,使用函数int()将其转换成正数,或使用函数float()将其转换为浮点数

判断输入是否在读取出的字符串中 if birthday in pi_string:

  1. 写入文件

    写入空文件
with open(filename,'w') as file_object:
    file_object.write("把这句话写到文件里面去")


参数2(w,以写入模式打开文件,r,读取模式,a附加模式,r+读取和写入模式,默认以只读模式打开)

如果要写入的文件不存在,函数open()将自动创建它,以写入(w)模式打开文件时,如果文件已经存在,函数将在返回文件对象前清空该文件

python只能将字符串写入文本文件,要将数值存储到文本文件中,必须先使用函数str()将其转换为字符串格式

写入多行,直接多个write不会自动换行,需要在write()语句中包含换行符(‘\n’)

附加到文件(给文件添加内容,而不是覆盖原有内容,使用附加模式打开文件,写入的行都将添加到文件末尾)with open(filename, 'a') as file_object:

  1. 异常(使用try-except代码块处理)
try:
    print(5/0)
except ZeroDivisionError:
    print("这里是发生异常后执行的操作")


else代码块(依赖于try代码块成功执行的代码都应放到else代码块中:)

try:
    answer = int(first_number) / int(second_number)
except 
    ZeroDivisionError: 
    print("You can't divide by 0!")
else: 
    print(answer)


处理FileNotFoundError异常

try:
    with open(filename) as f_obj: 
        contents = f_obj.read()
except FileNotFoundError:
    msg = "Sorry, the file " + filename + " does not exist." print(msg)
  1. 存储数据

    使用模块json来存储数据(文件是.json)
import json
numbers = [2, 3, 5, 7, 11, 13]

filename = 'numbers.json'

with open(filename, 'w') as f_obj: 
    json.dump(numbers, f_obj)

最终的存储格式和python中一样[2, 3, 5, 7, 11, 13]

使用json.load()将这个列表读取到内存中

with open(filename) as f_obj:
    numbers = json.load(f_obj)


保存和读取用户生成的数据

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容