(三)python进阶

一、封装的概念

封装

  • 隐藏:属性和实现细节,不允许外部直接访问
  • 暴露:公开方法,实现对内部信息的操作与访问

封装的作用

  • 限制安全的访问和操作,提高数据安全性
  • 可进行数据检查,从而有利于保证对象信息的完整性

二、封装的实现

  • 保护属性:_属性名,仅供类体内部使用
  • 私有属性:__属性名
    • 被视作类名_属性名
class Account:
    """账户"""

    # 普通属性
    bank = 'BOC'

    # 保护属性(内部属性)
    _username = 'zhizhi'

    # 私有属性
    __password = '888'


# 通过类名访问属性
print(Account.bank)  # 打印BOC
print(Account._username)  # 打印zhizhi
print(Account.__password)  # 报错AttributeError

print(Account.__dict__)
print(Account._Account__password)  # 打印888

封装的实现:暴露

  • 提供数据访问功能(getter)
    • 计算属性,该属性并不真正的存储任何状态,值是通过某种算法计算得到的,当程序对该属性进行赋值时,被赋的值通常存储到实例变量中
    • 语法:使用@property装饰器
    • 调用:实例.方法名
class Account:
    """账户"""

    # 普通属性
    bank = 'BOC'

    # 保护属性(内部属性)
    _username = 'zhizhi'

    # 私有属性
    __password = '888'

    @property
    def password(self):
        return self.__password

# 实例化
obj = Account()


# 访问实例的私有属性
print(obj.password)

修改

  • 提供数据操作功能(setter)
    • 语法:使用@计算属性名.setter装饰器
    • 调用:实例.方法名
class Account:
    """账户"""

    # 普通属性
    bank = 'BOC'

    # 保护属性(内部属性)
    _username = 'zhizhi'

    # 私有属性
    __password = '888'

    @property
    def password(self):
        return self.__password

    @password.setter
    def password(self, value):
        # 增加数据的校验
        if len(value) >= 8:
            self.__password = value
        else:
            print("密码长度最少有8位!")
# 实例化
obj = Account()


# 访问实例的私有属性
print(obj.password) # 888

# 修改私有属性(满足校验条件)
obj.password = 'zhizhi666'
print(obj.password) # zhizhi666

# 修改私有属性(不满足校验条件)
obj.password = '1123'
print(obj.password) #密码长度最少有8位!
# zhizhi666

三、python继承

1、继承的概念

继承(Inheritance)

  • 复用父类的公开属性和方法
  • 拓展出新的属性和方法

2、继承的实现

  • 语法:class类名(父类列表)
  • 默认父类是object
  • python支持多继承
class Human:
    """人类"""


    # 类属性
    message = '这是Human类的属性'

    # 构造方法
    def __init__(self, name, age):
        # 实例属性
        self.name = name
        self.age = age

    # 实例方法
    def live(self):
        print('住在地球上')


class Student(Human):

    # 子类实例方法
    def study(self):
        print('正在学习')


# 实例化子类对象
stu = Student('zhizhi', 18)


# 访问属性,获得父类的类属性
print(stu.message)  # 这是Human类的属性
print(stu.name, stu.age)

# 访问实例方法
stu.live()
stu.study()

3、类型检查

  • isinstance(实例, 类名)
    • 检查对象是否是某个类及其派生类的实例
  • issubclass(类名1,类名2)
    • 检查类名1是否是类名2的子类
class Human:
    pass


class Student(Human):
    pass


class Teacher(Human):
    pass


# 检查实例和类
stu = Student()
print(isinstance(stu, Human)) # True

# 检查子类和父类
print(issubclass(Student, Human)) # True
print(issubclass(Student, Teacher)) # False

四、多态

1、多态的概念

python是弱类型语言,对于弱类型语言来说,变量没有声明类型,因此,同一个变量可以在不同的时间代表不同的对象,当同一个变量调用同一个方法时,可以呈现出多种行为

  • 多态(Polymorphism)
    • 同名方法呈现多种行为

2、多态的表现

运算符的多态表现

  • +号
    • 加法:数字+数字
    • 拼接:字符串+字符串
    • 合并:列表+列表
print(1+1) # 2
print("hello"+"world") # hello world
print([1,2]+[3])      # [1, 2,3]

函数的多态表现

  • len()函数
    • 可以接收字符串
    • 可以接收列表
print(len("zhizhi"))
print(len([1,2,3]))

方法的多态表现

  • 同名变量调用同名方法呈现多种行为
class China:
    def speak(self):
        print('汉语')
        
class Usa:
    def speak(self):
        print('English')
        

# 实例化对象
cn = China()
us = Usa()

# 遍历
for x in (cn, us):
    x.speak() 
# 汉语
# English

3、多态与继承

  • 方法重写(override):子类的方法名称与父类的相同,子类优先级更高
  • 重写构造方法
    • super().init()
    • 父类名.init(self)
class Human:
    """人类"""


    # 类属性
    message = '这是Human类的属性'

    # 构造方法
    def __init__(self, name, age):
        # 实例属性
        self.name = name
        self.age = age

    # 实例方法
    def live(self):
        print('住在地球上')


class Student(Human):

    # 重写父类构造方法
    def __init__(self, name, age, school):
        # 访问父类的构造方法
        # super().__init__(name, age)
        # super(Student, self).__init__(name, age)
        Human.__init__(self, name, age)
        self.school = school

    # 重写父类实例方法
    def live(self):
        print(f'住在{self.school}')


# 实例化子类对象
stu = Student('zhizhi', 12, 'gelanfenduo')
print(stu.school)

stu.live()

四、模块与包

(一)模块

1、项目目录结构

程序结构

  • 组成:
    • package包
    • module模块
    • function方法

2、模块定义

  • 包含python定义和语句的文件
  • .py文件
  • 作为脚本运行

3、文件引用

模块导入:模块是在代码量变得相当⼤了之后,为了将需要重复使⽤的有组织的代码放在
⼀起,这部分代码可以被其他程序引⽤,从⽽使⽤该模块⾥的函数等功能,引
⽤的过程叫做导⼊(import)

  • 在python中,⼀个⽂件(以“.py”为后缀名的⽂件)就叫做⼀个模块
  • 导⼊模块的写法:
  • ⽅法⼀:import modul1[,module2…[,moduleN]]
  • ⽅法⼆:from module import <name[,name2,….[,nameN]]>
  • import模块名
  • from <模块名> import <方法名|变量|类>
  • from <模块名> import *
    • 注意:
      • 同一个模块写多次,只被导入一次
      • import应该放在代码的顶端
      • 使⽤关键词“import + 模块名称” 导⼊某⼀个模块

模块分类

  • 系统内置模块
  • sys、time、json模块等等;
  • 第三⽅的开源模块
  • 通过pip install进⾏安装,有开源的代码
  • ⾃定义模块
  • ⾃⼰写的模块,对某段逻辑或某些函数进⾏封装后供其他函数调⽤。

如何使用模块

1、系统内置模块

  • Python安装好之后⾃带的⼀些⾮常有⽤的模块 (sys,os,time,json模块
    等)
 import sys
 print("调⽤了sys模块")
 for i in sys.argv:
 print(i)

2、第三⽅开源模块

  • 是通过包管理⼯具pip完成的。必须先知道该库的名称,可以在官⽹或者pypi
    上搜索,⽐如MySQL驱动程序,Web框架Flask,科学计算Numpy等
  • NumPy(Numerical Python) 是 Python 语⾔的⼀个扩展程序库,⽀持⼤量的维
    度数组与矩阵运算,此外也针对数组运算提供⼤量的数学函数库
  • pip install numpy

3、⾃定义模块

  • ⾃定义模块是⾃⼰写的模块,对某段逻辑或某些函数进⾏封装后供其他函数调⽤。
  • 模块由变量,函数,或类组成
    举例:
  • 创建⼀个模块 baidu.py
  • 创建⼀个调⽤模块 index.py
  • 注意:⾃定义模块的名字⼀定不能和系统内置的模块重名,否则将不能再导⼊系统的内置模块。
  • 例如,⾃定义了⼀个sys.py模块后,那系统的sys模块就不能使⽤

4、导⼊模块

  • import 模块名 引⼊⼀个完整的模块
  • from <模块名> import <⽅法 | 变量 | 类> 引⼊模块中的⼀个或多个指定部分
  • from <模块名> import * 导⼊模块⾥⾯的所有的函数,变量
    区别:
  • import 导⼊模块,每次使⽤模块中的函数,都要是定是哪个模块
  • from…import * 导⼊模块,每次使⽤模块中的函数,直接使⽤函数就可以了(因为已经知道该函数是那
    个模块中的了)

5、常用方法

  • dir() 找出当前模块定义的对象
  • dir(sys). 找出参数模块定义的对象

作用域

  • 搜索路径(print(sys.path())
  • 当你导⼊⼀个模块,Python 解析器对模块位置的搜索顺序是:
  • 1、当前⽬录
  • 2、如果不在当前⽬录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个⽬录
  • 3、如果都找不到,Python会察看默认路径。UNIX下,默认路径⼀般为/usr/local/lib/python/
  • 模块搜索路径存储在 system 模块的 sys.path 变量中。变量⾥包含当前⽬录,PYTHONPATH和
    由安装过程决定的默认⽬录。

使⽤模块的好处

  • 提⾼代码的可维护性
  • ⼀个模块编写完毕之后,其他模块直接调⽤,不⽤再从零开始写代码了,节约
    了⼯作时间;
  • 避免函数名称和变量名称重复,在不同的模块中可以存在相同名字的函数名和
    变量名(不要和系统内置的模块名称重复)

五、错误与异常

什么是异常

错误 与 异常的区别?

  • 错误与异常都是在程序编译和运⾏时出现的错误
  • 异常可以被开发⼈员捕捉和处理
  • 错误⼀般是系统错误,⼀般不需要开发⼈员处理(也⽆法处理),⽐如内存溢出

什么是异常?

  • 异常即是⼀个事件,该事件会在程序执⾏过程中发⽣,影响了程序的正常执⾏。
  • 有些是由于拼写、配置、选项等等各种引起的程序错误,有些是由于程序功能处理逻辑不完善引起的漏洞,这些统称为程序中的异常

常见的异常类型

  • 除零异常、名称异常、索引异常、键异常、值异常、属性异常等等

语法错误与定位

异常处理流程:

  • 检测到错误->引发异常->捕获异常操作

异常解决⽅案

  • 如果是拼写、配置等引起的错误,根据出错信息进⾏排查错误出现的位置进⾏解决
  • 如果是程序设计不完善引起的漏洞,根据漏洞的情况进⾏设计处理漏洞的逻辑

异常捕获、异常处理

流程1

流程2

流程3
# 相除
# def div(a, b):
#     if b != 0:
#         return a / b
#     else:
#         print('分母不能为0')
#         return 0
def div(a, b):
    return a / b

f = open('data.txt')
try:
    print(div(1, 1))
    list1 = [1, 2, 3]
    print(list1[3])

    f.readlines()
except Exception as e:
    print(e)
    print('这里有个异常')

finally: # finally最终都会被执行,无论有异常还是没有异常的情况
    print('finally')
    f.close()
image.png
def set_age(num):
    if num <= 0 or num > 200:
        raise ValueError(f'值错误:{num}')
    else:
        print(f'设置的年龄为:{num}')
        
set_age(-1)

⾃定义异常

语法

raise [Exception [, args [, traceback]]]
class MyError(Exception):
 def __init__(self, value):
 self.value = value
 def __str__(self):
 return repr(self.value)
class MyException(Exception):
    def __init__(self, msg):
        print(f'这是一个异常:{msg}')


def set_age(num):
    if num <= 0 or num > 200:
        raise MyException(f'值错误:{num}')
    else:
        print(f'设置的年龄为:{num}')

set_age(-10)

六、debug调试与分析

调试的概念与技术体系

  • 程序调试是将编制的程序投⼊实际运⾏前,⽤⼿⼯或编译程序等⽅法进⾏测
    试,修正【语法错误和逻辑错误】的过程。
  • 语法错误:编写的python语法不正确,程序编译失败。
  • 逻辑错误:代码本⾝能够正常执⾏,但是执⾏完成的结果不符合预期结果。
  • 什么是bug:bug是计算机领域专业术语(⼩昆⾍; ⾍⼦),计算机⾥叫漏洞,隐藏在程序中的⼀些未被发现的缺陷或问题统称为bug(漏洞)

程序调试

  • 1、语法错误
    • 类型错误,语法错误,缩进错误,索引错误,键错误
  • 2、逻辑错误
    • 业务逻辑错误,并不会报错

调试方法

  • 1、对应位置使⽤print 或者 logging打印⽇志信息
  • 2、启动断点模式debug调试

程序运⾏时堆栈分析

七、类型注解

用法

https://docs.python.org/zh-cn/3/library/typing.html
def greeting(name: str) -> str:
    return 'Hello ' + name.split(',')[1]
print(greeting('python,java'))

类型提示的好处

  • 1、增强代码可读性
  • 2、ide 中代码提示
  • 3、静态代码检查

IDE 中代码中提示功能

为类型起别名

from typing import List

Vector = List[float]

def scale(scalar: float, vector: Vector) -> Vector:
    return [scalar * num for num in vector]
print(scale(1.1, [1.2, -4.2, 5.4]))

设置提示类型

自定义类型

class Student:
    name: str
    age: int

def get_stu(name: str)->Student:
    return Student()
get_stu().  --> 有相应的提示

静态代码检查功能

安装 mypy

pip install mypy

实例

from typing import List
a: List[int] = []
a= [1,2,'1']

运行

mypy demo.py

类型注解总结

  • 1、增强代码可读性
  • 2、ide 中代码提示
  • 3、静态代码检查

八、数据类 dataclass

dataclass 介绍

  • dataclass 优势

    • 可读性强
    • 操作灵活
    • 轻量
  • 应用场景

    • 创建对象
    • 完美融合平台开发 ORM 框架
  • 场景:如果创建一只猫,信息包括猫的名字、体重、颜色。同时打印这个对象的时候,希望能打印出一个字符串(包含猫的各种信息)应该如何编写代码
  • 问题:
    • 数据修改不方便
    • 代码冗余
    • 解决方案:
    • 使用自定义类实现数据类
class Cat:
    name: str
    weight: int
    color: str

    def __init__(self, name, weight, color):
        self.name = name
        self.weight = weight
        self.color = color

    def __str__(self):
        return f'猫猫姓名{self.name},体重{self.weight},颜色{self.color}'

    def __repr__(self):
        return f'===>>>猫猫姓名{self.name},体重{self.weight},颜色{self.color}'


if __name__ == '__main__':
    cat = Cat("原味鸡", 20, '黑色')
    print(cat)

数据类更优雅的实现方案

  • 使用 dataclass 创建数据类
  • 实例化的时候自动生成构造函数
from dataclasses import dataclass

@dataclass
class Cat:
    name: str
    color: str
    weight: int


if __name__ == '__main__':
    cat = Cat('原味鸡', '黑色', 20)
    print(cat)

field 的使用

# 错误写法,执行报错
@dataclass
class Cat:
    name: str
    color: str
    weight: int
    children: list=[1,2,3]

# 正确写法,可变类型必须使用field
from dataclasses import dataclass, field


@dataclass
class Cat:
    name: str
    color: str = field(default='black')
    # weight: int =2
    weight: int = field(default=2)
    # 可变参数list,dict,需要通过default_factory来指定类型或者默认值
    children: list = field(default_factory=list)


if __name__ == '__main__':
    cat = Cat('原味鸡')
    print(cat)

field 常用参数

参数名 参数功能
default 字段的默认值
default_factory 定义可变量参数的默认值,default 和 default_factory 不能同时存在
init 如果为 true(默认值),该字段作为参数包含在生成的 init() 方法中。
repr 如果为 true(默认值),该字段包含在生成的 repr() 方法返回的字符串中。

field default 参数

  • 字段的默认值

field init 参数

  • 如果为 True(默认值),该字段作为参数包含在生成的 init() 方法中。
  • 如果为 False,该字段不会包含 init() 方法参数中。
@dataclass
class Cat:
    name: str
    color: str = field(default='black')
    # init=False 在实例化对象的时候,不需要设置这个值,需要给一个默认值
    weight: int = field(default=5, init=False)
    # 可变参数list,dict,需要通过default_factory来指定类型或者默认值
    children: list = field(default_factory=list)

"""
如果为 True(默认值),该字段作为参数包含在生成的 init() 方法中。
如果为 False,该字段不会包含 init() 方法参数中。

体现在:在实例化的时候,是否需要传递这个参数
"""
if __name__ == '__main__':
    cat = Cat(name='原味鸡', color='black', children=[1, 2, 3])
    print(cat)

field repr 参数

  • 如果为 True(默认值),该字段包含在生成的 repr() 方法返回的字符串中。
  • 如果为 False,该字段不会包含在生成的 repr() 方法返回的字符串中。
@dataclass
class Cat:
    name: str
    color: str = field(default='black')
    # repr=False 打印的时候,就不会包括这个字段
    weight: int = field(default=5, repr=False)
    children: list = field(default_factory=list)


if __name__ == '__main__':
    cat = Cat('原味鸡', 'black', 10, children=[1, 2, 3])
    print(cat)

常用的方法

  • asdict() 转化实例对象为字典格式
from dataclasses import dataclass, field, asdict

@dataclass
class Cat:
    name: str
    color: str = field(default='black')
    # repr=False 打印的时候,就不会包括这个字段
    weight: int = field(default=5, repr=False)
    children: list = field(default_factory=list)

# asdict() 直接将实例对象转成 字典格式


if __name__ == '__main__':
    cat = Cat('原味鸡', '黑色', 20, [1, 2, 3])
    print(asdict(cat))

总结

  • 可读性强
  • 操作灵活
  • 轻量

九、内置装饰器

内置类装饰器

  • 不用实例化、直接调用
  • 提升代码的可读性
    内置装饰器 含义
    classmethod 类方法
    staticmethod 静态方法

普通方法

定义:

  • 第一个参数为self,代表 实例本身

调用:

  • 要有实例化的过程,通过 实例对象.方法名 调用
# 1、定义
class MethodsDemo:
    param_a = 0  # 类变量
    def normal_demo(self):  # 定义一个类方法,第一个参数必须为self
        """
        普通方法
        :return:
        """
        print('这是一个普通方法', self.param_a)


# 2、调用
md = MethodsDemo()
md.normal_demo()

类方法

定义:

  • 使用 @classmethod 装饰器,第一个参数为类本身,所以通常使用cls命名做区分(非强制)
  • 在类内可以直接使用类方法或类变量,无法直接使用实例变量或方法
    调用:
  • 无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用
class MethodsDemo:
    param_a = 0  # 类变量

    # 定义一个类方法,第一个参数必须为self
    @classmethod
    def classmethod_demo(cls):  
        """
        类方法,第一个参数需要改为cls
        :return:
        """
        print('这是一个类方法', cls.param_a)


# 2、类的调用,无需实例化,直接调用
MethodsDemo.classmethod_demo()

静态方法

定义:

  • 使用 @staticmethod 装饰器,没有和类本身有关的参数
  • 无法直接使用任何类变量、类方法或者实例方法、实例变量

调用:

  • 无需实例化,直接通过 类.方法名 调用,也可以通过 实例.方法名 调用
"""静态方法"""
class StaticMethod:

    @classmethod
    def class_method(cls):
        print('这是一个类方法')

    def demo_method(self):
        print("这是一个普通方法")

    # 定义: 1、要使用staticmethod装饰器 2、这个方法是没有self、cls
    @staticmethod
    def static_demo(param1):

        print('这是一个静态方法')

# 2、调用:类.方法名
StaticMethod.static_demo('zhizhi')
demo = StaticMethod()
demo.static_demo('zhizhi')

普通方法、类方法、静态方法

名称 定义 调用 关键字 使用场景
普通方法 至少需要一个参数self 实例名.方法名() 方法内部涉及到实例对象属性的操作
类方法 至少需要一个cls参数 类名.方法名() 或者实例名.方法名() @classmethod 如果需要对类属性,即静态变量进行限制性操作
静态方法 无默认参数 类名.方法名() 或者实例名.方法名() @staticmethod 无需类或实例参与

实际案例

  • 右边的代码实现的需求是格式化输出时间
  • 如果现在需求变更,输入 年、月、日 没法保证格式统一,可能是json,可能是其他格式的字符串,在不修改构造函数的前提下,如何更改代码
class DateFormat:
    def __init__(self, year= 0, month=0, day=0):
        self.year = year
        self.month = month
        self.day = day

    def out_date(self):
        return f'输入的时间为{self.year}年,{self.month}月,{self.day}日'

    @classmethod
    def json_format(cls, json_data):
        """
        输入一个字典格式的数据信息,返回(2023, 6, 3)
        :param json_data:
        :return:
        """
        year, month, day = json_data["year"], json_data["month"], json_data["day"]
        return cls(year, month, day)


# def json_format(json_data):
#     year, month, day = json_data["year"], json_data["month"], json_data["day"]
#     return year, month, day


json_data = {"year": 2023, "month": 6, "day": 27}
# 使用json格式化,生成想要的的日期格式,返回DateFormat实例
# year, month, day = 2023, 6, 27


demo = DateFormat.json_format(json_data)
print(demo.out_date())

静态方法实际案例

  • 此方法没有任何和实例、类相关的部分,可以作为一个独立函数使用
  • 某些场景下,从业务逻辑来说又属于类的一部分
class Game:
    """
    staticmethod使用场景
    方法所有涉及到的逻辑都没有使用实例方法或者实例变量的时候
    """
    def __init__(self, first_hero, second_hero):
        self.first_hero = first_hero
        self.second_hero = second_hero

    # fight有和实例变量交互的部分,所以需要定义一个普通方法
    def fight(self):
        print(f'本轮比赛开始,由{self.first_hero}VS{self.second_hero}')

    # start没有和类或实例交互的部分,那么可以使用staticmethod
    @staticmethod
    def start():
        print('游戏开始')


Game.start()
game1 = Game('Bob', 'Tom')
game2 = Game('Mike', 'Herry')
game1.fight()
game2.fight()
  • 例子:简单工厂方法
# staic使用场景
class HeroFactory:
    """
    staticmethod使用场景
    方法所有涉及到的逻辑都没有使用实例方法或者实例变量的时候
    伪代码
    """
    @staticmethod
    def create_hero(hero):
        if hero == 'ez':
            return EZ()
        elif hero == 'jinx':
            return JINX()
        elif hero == 'timo':
            return TIMO()
        else:
            raise Exception('此英雄不在此工厂')
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容