Python面向?qū)ο缶幊?/h1>

本節(jié)課綱

  • 類和對象
  • 類的定義
  • self參數(shù)
  • 初始化方法init()
  • _str_()方法
  • 面向?qū)ο髒s面向過程
  • 私有屬性-封裝
  • 將實(shí)例用作屬性-對象組合
  • 類屬性 類方法 靜態(tài)方法
  • 繼承
  • _new_()方法
  • object
  • 單例模式
  • 函數(shù)參數(shù)注解

1)類和對象

1.1 萬物皆對象


分類是人們認(rèn)識世界的一個(gè)很自然的過程救欧,在日常生活中會不自覺地將對象進(jìn)行進(jìn)行分類

對象歸類

  • 類是抽象的概念,僅僅是模板 比如說:“人”
  • 對象是一個(gè)你能夠看得到钝计、摸得著的具體實(shí)體: 趙本山飞醉,劉德華削解,趙麗穎

舉例

user1 = 'zhangsan'
print(type(user1))
user2 = 'lisi'
print(type(user2))

輸出

<class 'str'>
<class 'str'>

以上str是類(python中的字符串類型)何陆,user1和user2是對象(以前我們叫變量)

研究對象


顧客類型

屬性:
姓名—張浩
年齡—20
體重—60kg
行為:
購買商品

收銀員類型

屬性:
員工號—10001
姓名—王淑華
部門—財(cái)務(wù)部
行為:
收款
打印賬單

1.2 對象的特征——屬性

  • 屬性——對象具有的各種特征。 每個(gè)對象的每個(gè)屬性都擁有特定值戈二。 例如:顧客張浩和李明的年齡预柒、姓名不一樣队塘。

1.3 對象的特征——方法(操作,行為)
方法——對象執(zhí)行的操作(通常會改變屬性的值)宜鸯。 顧客對象的方法---購買商品憔古。 收銀員對象的方法----收款。

對象:用來描述客觀事物的一個(gè)實(shí)體顾翼,由一組屬性和方法構(gòu)成


舉例:

類型:狗
對象名:doudou
屬性:
顏色:白色
方法:
叫投放,跑奈泪,吃

對象同時(shí)具有屬性和方法兩項(xiàng)特性适贸。 對象的屬性和方法通常被封裝在一起,共同體現(xiàn)事物的特性涝桅, 二者相輔相承拜姿,不能分割。

課上練習(xí) 說一說教室里的對象冯遂,描述他們的屬性和方法

1.4 從對象抽象出類
抽取出下列對象的共同特征(屬性和方法)


類是模子蕊肥,定義對象將會擁有的特征(屬性)和行為(方法)。

再次強(qiáng)調(diào)

  • 類是抽象的概念蛤肌,僅僅是模板壁却。 比如說:“人”, 類定義了人這種類型屬性(name裸准,age...)和方法(study,work...)展东。
  • 對象是一個(gè)你能夠看得到、摸得著的具體實(shí)體: 趙本山炒俱,劉德華盐肃,趙麗穎,這些具體的人都具有人類型中定義的屬性和方法权悟,不同的是他們各自的屬性不同砸王。

根據(jù)類來創(chuàng)建對象被稱為實(shí)例化

2)類的定義

2.1 定義只包含方法的類
在 Python 中要定義一個(gè)只包含方法的類峦阁,語法格式如下:

class 類名:

    def 方法1(self, 參數(shù)列表):
        pass

    def 方法2(self, 參數(shù)列表):
        pass

方法 的定義格式和之前學(xué)習(xí)過的函數(shù) 幾乎一樣谦铃。 區(qū)別在于第一個(gè)參數(shù)必須是 self,大家暫時(shí)先記住榔昔,稍后介紹 self驹闰。

2.2 創(chuàng)建對象
當(dāng)一個(gè)類定義完成之后凿跳,要使用這個(gè)類來創(chuàng)建對象,語法格式如下:

對象變量 = 類名()

第一個(gè)面向?qū)ο蟪绦?/p>

需求

  • 小貓 愛 吃 魚疮方,小貓 要 喝 水控嗜。

分析

  • 定義一個(gè)貓類 Cat。
  • 定義兩個(gè)方法 eat 和 drink骡显。
class Cat:
    """這是一個(gè)貓類"""

    def eat(self):
        print("小貓愛吃魚")

    def drink(self):
        print("小貓?jiān)诤人?)

tom = Cat()
tom.drink()
tom.eat()

使用 Cat 類再創(chuàng)建一個(gè)對象

lazy_cat = Cat()
lazy_cat.eat()
lazy_cat.drink()

3)self參數(shù)

和我們以往的經(jīng)驗(yàn)不同疆栏,我們在調(diào)用對象的方法是不需要傳遞self參數(shù),這個(gè)self參數(shù)是系統(tǒng)自動傳遞到方法里的惫谤。我們需要知道這個(gè)self到底是什么壁顶?
3.1 給對象增加屬性

在 Python 中,要 給對象設(shè)置屬性溜歪,非常的容易若专,但是不推薦使用。 因?yàn)椋簩ο髮傩缘姆庋b應(yīng)該封裝在類的內(nèi)部蝴猪。 要 給對象設(shè)置屬性调衰,只需要在 類的外部的代碼 中直接通過.設(shè)置一個(gè)屬性即可

tom.name = "Tom"
lazy_cat.name = "大懶貓"

3.2 理解self到底是什么

class Cat:
    """這是一個(gè)貓類"""

    def eat(self):
        print(f"小貓愛吃魚,我是{self.name},self的地址是{id(self)}")

    def drink(self):
        print("小貓?jiān)诤人?)

tom = Cat()
print(f'tom對象的id是{id(tom)}')
tom.name = "Tom"
tom.eat()
print('-'*60)
lazy_cat = Cat()
print(f'lazy_cat對象的id是{id(lazy_cat)}')
lazy_cat.name = "大懶貓"
lazy_cat.eat()

輸出

tom對象的id是36120000
小貓愛吃魚,我是Tom,self的地址是36120000
------------------------------------------------------------
lazy_cat對象的id是36120056
小貓愛吃魚,我是大懶貓,self的地址是36120056

由輸出可見,當(dāng)我們使用

x對象.x方法()

的時(shí)候自阱,python會自動將x對象做為實(shí)參傳給x方法的self參數(shù)嚎莉。 也可以這樣記憶,誰點(diǎn)(.)的方法沛豌,self就是誰趋箩。

類中的每個(gè)實(shí)例方法的第一個(gè)參數(shù)都是self

4)初始化方法init()

之前代碼存在的問題 —— 在類的外部給對象增加屬性

  • 將案例代碼進(jìn)行調(diào)整,先調(diào)用方法 再設(shè)置屬性加派,觀察一下執(zhí)行效果
tom = Cat()
tom.drink()
tom.eat()
tom.name = "Tom"
print(tom)
  • 程序執(zhí)行報(bào)錯如下:
AttributeError: 'Cat' object has no attribute 'name'
屬性錯誤:'Cat' 對象沒有 'name' 屬性

提示

  • 在日常開發(fā)中叫确,不推薦在 類的外部 給對象增加屬性。
  • 如果在運(yùn)行時(shí)芍锦,沒有找到屬性竹勉,程序會報(bào)錯。
  • 對象應(yīng)該包含有哪些屬性醉旦,應(yīng)該 封裝在類的內(nèi)部饶米。

初始化方法

  • 當(dāng)使用 類名() 創(chuàng)建對象時(shí),會 自動 執(zhí)行以下操作:
    1)為對象在內(nèi)存中 分配空間 —— 創(chuàng)建對象(調(diào)用new车胡,以后說)
    2)為對象的屬性 設(shè)置初始值 —— 初始化方法(調(diào)用init并且將第一步創(chuàng)建的對象檬输,通過self參數(shù)傳給init)
  • 這個(gè) 初始化方法 就是 init 方法,init 是對象的內(nèi)置方法(有的書也叫魔法方法匈棘,特殊方法)

init 方法是 專門 用來定義一個(gè)類 具有哪些屬性并且給出這些屬性的初始值的方法丧慈!

在 Cat 中增加 init 方法,驗(yàn)證該方法在創(chuàng)建對象時(shí)會被自動調(diào)用

class Cat:
    """這是一個(gè)貓類"""

    def __init__(self):
        print("初始化方法")

在初始化方法內(nèi)部定義屬性

  • init 方法內(nèi)部使用 self.屬性名 = 屬性的初始值 就可以 定義屬性
  • 定義屬性之后,再使用 Cat 類創(chuàng)建的對象逃默,都會擁有該屬性
class Cat:

    def __init__(self):

        print("這是一個(gè)初始化方法")

        # 定義用 Cat 類創(chuàng)建的貓對象都有一個(gè) name 的屬性
        self.name = "Tom"

    def eat(self):
        print("%s 愛吃魚" % self.name)

# 使用類名()創(chuàng)建對象的時(shí)候鹃愤,會自動調(diào)用初始化方法 __init__
tom = Cat()

tom.eat()

改造初始化方法 —— 初始化的同時(shí)設(shè)置初始值

  • 在開發(fā)中,如果希望在 創(chuàng)建對象的同時(shí)完域,就設(shè)置對象的屬性软吐,可以對 init 方法進(jìn)行 改造
    1). 把希望設(shè)置的屬性值,定義成 init 方法的參數(shù)
    2). 在方法內(nèi)部使用 self.屬性 = 形參 接收外部傳遞的參數(shù)
    3). 在創(chuàng)建對象時(shí)吟税,使用 類名(屬性1, 屬性2...) 調(diào)用
class Cat:

    def __init__(self, name):
        print("初始化方法 %s" % name)
        self.name = name
    ...

tom = Cat("Tom")
...

lazy_cat = Cat("大懶貓")
...

5)_str_()方法

在 Python 中凹耙,使用 print 輸出 對象變量,默認(rèn)情況下肠仪,會輸出這個(gè)變量的類型肖抱,以及 在內(nèi)存中的地址(十六進(jìn)制表示)

class Cat:

    def __init__(self, new_name):

        self.name = new_name

        print("%s 來了" % self.name)


    def __str__(self):
        return "我是小貓:%s" % self.name

tom = Cat("Tom")
print(tom)

輸出

Tom 來了
<__main__.Cat object at 0x0000000002852278>

如果在開發(fā)中,希望使用 print 輸出 對象變量 時(shí)异旧,能夠打印 自定義的內(nèi)容意述,就可以利用 str 這個(gè)內(nèi)置方法了

注意:str 方法必須返回一個(gè)字符串

class Cat:

    def __init__(self, new_name):

        self.name = new_name

        print("%s 來了" % self.name)


    def __str__(self):
        return "我是小貓:%s" % self.name

tom = Cat("Tom")
print(tom)
Tom 來了
我是小貓:Tom

6)面向?qū)ο髒s面向過程

def CarInfo(type,price):
    print ("the car's type %s,price:%d"%(type,price))

print('函數(shù)方式(面向過程)')
CarInfo('passat',250000)
CarInfo('ford',280000)


class Car:
    def __init__(self,type,price):
        self.type = type
        self.price = price

    def printCarInfo(self):
        print ("the car's Info in class:type %s,price:%d"%(self.type,self.price))
print('面向?qū)ο?)
carOne = Car('passat',250000)
carTwo = Car('ford',250000)
carOne.printCarInfo()
carTwo.printCarInfo()

輸出

函數(shù)方式(面向過程)
the car's type passat,price:250000
the car's type ford,price:280000
面向?qū)ο?the car's Info in class:type passat,price:250000
the car's Info in class:type ford,price:250000

類能實(shí)現(xiàn)的功能,用函數(shù)也可以實(shí)現(xiàn)吮蛹,那么類的存在還有什么特殊的意義呢荤崇? 新需求---加一個(gè)行駛里程的功能 面向過程實(shí)現(xiàn)

def CarInfo(type,price):
    print ("the car's type %s,price:%d"%(type,price))

def driveDistance(oldDistance,distance):
        newDistance = oldDistance + distance
        return newDistance

print('函數(shù)方式(面向過程)')
CarInfo('passat',250000)
distance = 0
distance = driveDistance(distance,100)
distance = driveDistance(distance,200)
print(f'passat已經(jīng)行駛了{(lán)distance}公里')

輸出

函數(shù)方式(面向過程)
the car's type passat,price:250000
passat已經(jīng)行駛了300公里

面向?qū)ο髮?shí)現(xiàn)

class Car:
    def __init__(self,type,price):
        self.type = type
        self.price = price
        self.distance = 0 #新車

    def printCarInfo(self):
        print ("the car's Info in class:type %s,price:%d"%(self.type,self.price))

    def driveDistance(self,distance):
        self.distance += distance

print(f'面向?qū)ο?)
carOne = Car('passat',250000)
carOne.printCarInfo()
carOne.driveDistance(100)
carOne.driveDistance(200)
print(f'passat已經(jīng)行駛了{(lán)carOne.distance}公里')
print(f'passat的價(jià)格是{carOne.price}')

輸出

the car's Info in class:type passat,price:250000
passat已經(jīng)行駛了300公里
passat的價(jià)格是250000

通過對比我們可以發(fā)現(xiàn):

面向?qū)ο蟮膶?shí)現(xiàn)方式封裝性更好,已經(jīng)行駛的公里數(shù)是對象內(nèi)部的屬性匹涮,對象自身負(fù)責(zé)管理天试,外部調(diào)用代碼無需管理槐壳。我們隨時(shí)可以調(diào)用對象的方法和屬性得知對象當(dāng)前的各種信息然低。而面向過程的方式而言,外部調(diào)用代碼會“手忙腳亂”

再加一個(gè)需求: 車每行駛1公里务唐,車的價(jià)值貶值10元 面向?qū)ο蟮膶?shí)現(xiàn)方式雳攘,只需添加一行代碼:

    def driveDistance(self,distance):
        self.distance += distance
        self.price -= distance*10

全部代碼

class Car:
    def __init__(self,type,price):
        self.type = type
        self.price = price
        self.distance = 0 #新車

    def printCarInfo(self):
        print ("the car's Info in class:type %s,price:%d"%(self.type,self.price))

    def driveDistance(self,distance):
        self.distance += distance
        self.price -= distance*10

print(f'面向?qū)ο?)
carOne = Car('passat',250000)
carOne.printCarInfo()
carOne.driveDistance(100)
carOne.driveDistance(200)
print(f'passat已經(jīng)行駛了{(lán)carOne.distance}公里')
print(f'passat的價(jià)格是{carOne.price}')

輸出

面向?qū)ο?the car's Info in class:type passat,price:250000
passat已經(jīng)行駛了300公里
passat的價(jià)格是247000

面向過程的方式,請自行實(shí)現(xiàn)(比較麻煩) 小結(jié) 可以拿公司運(yùn)營作為比喻來說明面向?qū)ο箝_發(fā)方式的優(yōu)點(diǎn)

外部調(diào)用代碼好比老板 面向過程中函數(shù)好比員工枫笛,讓員工完成一個(gè)任務(wù)吨灭,需要老板不斷的干涉,大大影響了老板的工作效率刑巧。 面向?qū)ο笾袑ο蠛帽葐T工喧兄,讓員工完成一個(gè)任務(wù),老板只要下命令即可啊楚,員工可以獨(dú)擋一面吠冤,大大節(jié)省了老板的時(shí)間。

還有一種說法

世界上本沒有類恭理,代碼寫多了拯辙,也就有了類

面向?qū)ο箝_發(fā)方式是晚于面向過程方式出現(xiàn)的,幾十年前颜价,面向?qū)ο筮€沒有出現(xiàn)以前涯保,很多軟件系統(tǒng)的代碼量就已經(jīng)達(dá)到幾十上百萬行诉濒,科學(xué)家為了組織這些代碼,將各種關(guān)系密切的數(shù)據(jù)夕春,和相關(guān)的方法分門別類未荒,放到一起管理,就形成了面向?qū)ο蟮拈_發(fā)思想和編程語言語法及志。

7)私有屬性-封裝

在實(shí)際開發(fā)中茄猫,對象 的 某些屬性或方法 可能只希望 在對象的內(nèi)部被使用,而 不希望在外部被訪問到

定義方式

在 定義屬性或方法時(shí)困肩,在 屬性名或者方法名前 增加 兩個(gè)下劃線__ 實(shí)際開發(fā)中私有屬性也不是一層不變的划纽。所以要給私有屬性提供外部能夠操作的方法。

7.1) 通過自定義getset方法提供私有屬性的訪問

class Person:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    #定義對私有屬性的get方法锌畸,獲取私有屬性
    def getAge(self):
        return self.__age

    #定義對私有屬性的重新賦值的set方法勇劣,重置私有屬性
    def setAge(self,age):
        self.__age = age

person1 = Person("tom",19)
person1.setAge(20)
print(person1.name,person1.getAge())  #tom 20

7.2) 調(diào)用property方法提供私有屬性的訪問

class Student:
    def __init__(self, name, age):
        self.name = name
        self.__age = age

    #定義對私有屬性的get方法,獲取私有屬性
    def getAge(self):
        return self.__age

    #定義對私有屬性的重新賦值的set方法潭枣,重置私有屬性
    def setAge(self,age):
        self.__age = age

    p = property(getAge,setAge) #注意里面getAge,setAge不能帶()

s1 = Student("jack",22)
s1.p = 23 #如果使用=,則會判斷為賦值比默,調(diào)用setAge方法。
print(s1.name,s1.p)  #jack 23   盆犁,直接使用s1.p會自動判斷會取值命咐,調(diào)用getAge
print(s1.name,s1.getAge()) #jack 23,這個(gè)時(shí)候set,get方法可以單獨(dú)使用。

7.3) 使用property標(biāo)注提供私有屬性的訪問

class Teacher:
    def __init__(self, name, age,speak):
        self.name = name
        self.__age = age
        self.__speak = speak


    @property      #注意1.@proterty下面默認(rèn)跟的是get方法谐岁,如果設(shè)置成set會報(bào)錯醋奠。
    def age(self):
        return self.__age

    @age.setter    #注意2.這里是使用的上面函數(shù)名.setter,不是property.setter.
    def age(self,age):
        if age > 150 and age <=0:  #還可以在setter方法里增加判斷條件
            print("年齡輸入有誤")
        else:
            self.__age = age

    @property
    def for_speak(self):  #注意2.這個(gè)同名函數(shù)名可以自定義名稱伊佃,一般都是默認(rèn)使用屬性名窜司。
        return self.__speak

    @for_speak.setter
    def for_speak(self, speak):
        self.__speak = speak

t1 = Teacher("herry",45,"Chinese")
t1.age = 38    #注意4.有了property后,直接使用t1.age,而不是t1.age()方法了航揉。
t1.for_speak = "English"  

print(t1.name,t1.age,t1.for_speak)  #herry 38 English

8)將實(shí)例用作屬性-對象組合

使用代碼模擬實(shí)物時(shí)塞祈,你可能會發(fā)現(xiàn)自己給類添加的細(xì)節(jié)越來越多:屬性和方法清單以及文件都越來越長。在這種情況下帅涂,可能需要將類的一部分屬性和方法作為一個(gè)獨(dú)立的類提取出來议薪。你可以將大型類拆分成多個(gè)協(xié)同工作的小類。

8.1 實(shí)例1擺放家具

需求

  1. 房子(House) 有 戶型媳友、總面積 和 家具名稱列表
    新房子沒有任何的家具
  2. 家具(HouseItem) 有 名字 和 占地面積斯议,其中
    席夢思(bed) 占地 4 平米
    衣柜(chest) 占地 2 平米
    餐桌(table) 占地 1.5 平米
  3. 將以上三件 家具 添加 到 房子 中
  4. 打印房子時(shí),要求輸出:戶型庆锦、總面積捅位、剩余面積、家具名稱列表

剩余面積

  1. 在創(chuàng)建房子對象時(shí),定義一個(gè) 剩余面積的屬性艇搀,初始值和總面積相等
  2. 當(dāng)調(diào)用 add_item 方法尿扯,向房間 添加家具 時(shí),讓 剩余面積 -= 家具面積

思考:應(yīng)該先開發(fā)哪一個(gè)類焰雕?

答案 —— 家具類
1.家具簡單
2.房子要使用到家具衷笋,被使用的類,通常應(yīng)該先開發(fā)

創(chuàng)建家具

class HouseItem:

    def __init__(self, name, area):
        """

        :param name: 家具名稱
        :param area: 占地面積
        """
        self.name = name
        self.area = area

    def __str__(self):
        return "[%s] 占地面積 %.2f" % (self.name, self.area)

# 1\. 創(chuàng)建家具
bed = HouseItem("席夢思", 4)
chest = HouseItem("衣柜", 2)
table = HouseItem("餐桌", 1.5)

print(bed)
print(chest)
print(table)

小結(jié)
1.創(chuàng)建了一個(gè) 家具類矩屁,使用到 initstr 兩個(gè)內(nèi)置方法
2.使用 家具類 創(chuàng)建了 三個(gè)家具對象辟宗,并且 輸出家具信息
創(chuàng)建房間

class House:

    def __init__(self, house_type, area):
        """

        :param house_type: 戶型
        :param area: 總面積
        """
        self.house_type = house_type
        self.area = area

        # 剩余面積默認(rèn)和總面積一致
        self.free_area = area
        # 默認(rèn)沒有任何的家具
        self.item_list = []

    def __str__(self):

        # Python 能夠自動的將一對括號內(nèi)部的代碼連接在一起
        return ("戶型:%s\n總面積:%.2f[剩余:%.2f]\n家具:%s"
                % (self.house_type, self.area,
                   self.free_area, self.item_list))

    def add_item(self, item):

        print("要添加 %s" % item)

# 2\. 創(chuàng)建房子對象

my_home = House("兩室一廳", 60)

my_home.add_item(bed)
my_home.add_item(chest)
my_home.add_item(table)

print(my_home)

小結(jié)

1.創(chuàng)建了一個(gè) 房子類,使用到 initstr 兩個(gè)內(nèi)置方法
2.準(zhǔn)備了一個(gè) add_item 方法 準(zhǔn)備添加家具
3.使用 房子類 創(chuàng)建了 一個(gè)房子對象
4.讓 房子對象 調(diào)用了三次 add_item 方法吝秕,將 三件家具 以實(shí)參傳遞到 add_item 內(nèi)部
添加家具

需求

1> 判斷 家具的面積 是否 超過剩余面積泊脐,如果超過,提示不能添加這件家具
2> 將 家具的名稱 追加到 家具名稱列表 中
3> 用 房子的剩余面積 - 家具面積

 def add_item(self, item):

        print("要添加 %s" % item)
        # 1\. 判斷家具面積是否大于剩余面積
        if item.area > self.free_area:
            print("%s 的面積太大烁峭,不能添加到房子中" % item.name)

            return

        # 2\. 將家具的名稱追加到名稱列表中
        self.item_list.append(item.name)

        # 3\. 計(jì)算剩余面積
        self.free_area -= item.area

小結(jié)

  • 主程序只負(fù)責(zé)創(chuàng)建 房子 對象和 家具 對象
  • 讓 房子 對象調(diào)用 add_item 方法 將家具添加到房子中
  • 面積計(jì)算容客、剩余面積、家具列表 等處理都被 封裝 到 房子類的內(nèi)部

8.2 實(shí)例2英雄pk怪物

hero.py

from random import randint


class Hero:
    def __init__(self, name,flood,strength):
        self.name = name
        self.flood = flood
        self.strength = strength

    def calc_health(self):
        return self.flood

    def take_damage(self, monster):
        dmage = randint(monster.strength - 5, monster.strength + 5)
        self.flood -= dmage
        print(f"{self.name}你被{monster.name}攻擊约郁,受到了{(lán)str(dmage)}點(diǎn)傷害!還剩{str(self.flood)}滴血")
        if self.calc_health() <= 0:
            print(f"{self.name}你被殺死了!勝敗乃兵家常事 請重新來過缩挑。")
            return True
        else:
            return False

monster.py

from random import randint


class Monster:
    def __init__(self, name,flood,strength):
        self.name = name
        self.flood = flood
        self.strength = strength

    def calc_health(self):
        return self.flood

    def take_damage(self, hero):
        dmage = randint(hero.strength - 5, hero.strength + 5)
        self.flood -= dmage
        print(f"{self.name}你被{hero.name}攻擊,受到了{(lán)str(dmage)}點(diǎn)傷害!還剩{str(self.flood)}滴血")
        if self.calc_health() <= 0:
            print(f"{self.name}你被殺死了!勝敗乃兵家常事 請重新來過鬓梅。")
            return True
        else:
            return False

pkgame.py

from hero import Hero
from monsters import Monster

hero = Hero('張三',100, 10)
monster = Monster('小強(qiáng)',60,20)

while True:
    is_monster_died = monster.take_damage(hero)
    if is_monster_died:
        break
    is_hero_died = hero.take_damage(monster)
    if is_hero_died:
        break

某次輸出:

小強(qiáng)你被張三攻擊供置,受到了6點(diǎn)傷害!還剩54滴血
張三你被小強(qiáng)攻擊,受到了25點(diǎn)傷害!還剩75滴血
小強(qiáng)你被張三攻擊绽快,受到了9點(diǎn)傷害!還剩45滴血
張三你被小強(qiáng)攻擊芥丧,受到了19點(diǎn)傷害!還剩56滴血
小強(qiáng)你被張三攻擊,受到了10點(diǎn)傷害!還剩35滴血
張三你被小強(qiáng)攻擊谎僻,受到了23點(diǎn)傷害!還剩33滴血
小強(qiáng)你被張三攻擊娄柳,受到了11點(diǎn)傷害!還剩24滴血
張三你被小強(qiáng)攻擊,受到了22點(diǎn)傷害!還剩11滴血
小強(qiáng)你被張三攻擊艘绍,受到了10點(diǎn)傷害!還剩14滴血
張三你被小強(qiáng)攻擊,受到了24點(diǎn)傷害!還剩-13滴血
張三你被殺死了!勝敗乃兵家常事 請重新來過秫筏。

9)類屬性 類方法 靜態(tài)方法

9.1 類對象诱鞠,實(shí)例對象
類對象:類名 實(shí)例對象:類創(chuàng)建的對象

類屬性就是類對象所擁有的屬性,它被所有類對象的實(shí)例對象所共有这敬,在內(nèi)存中只存在一個(gè)副本航夺,這個(gè)和C++、Java中類的靜態(tài)成員變量有點(diǎn)類似崔涂。對于公有的類屬性阳掐,在類外可以通過類對象和實(shí)例對象訪問

# 類屬性  
class people:  
    name="Tom"    #公有的類屬性  
    __age=18      #私有的類屬性  

p=people()  
print(p.name)   #實(shí)例對象  
print(people.name)  #類對象  

# print(p.__age)    #錯誤 不能在類外通過實(shí)例對象訪問私有的類屬性  
print(people.__age) #錯誤 不能在類外同過類對象訪問私有的類屬性

實(shí)例屬性

class people:  
    name="tom"  

p=people()  
p.age=18  

print(p.name)  
print(p.age)    #實(shí)例屬性是實(shí)例對象特有的,類對象不能擁有  

print(people.name)  
#print(people.age)  #錯誤:實(shí)例屬性,不能通過類對象調(diào)用

我們經(jīng)常將實(shí)例屬性放在構(gòu)造方法中

class people:  
    name="tom"  
    def  __init__(self,age):  
        self.age=age  

p=people(18)  

print(p.name)  
print(p.age)    #實(shí)例屬性是實(shí)例對象特有的缭保,類對象不能擁有  

print(people.name)  
# print(people.age)  #錯誤:實(shí)例屬性汛闸,不能通過類對象調(diào)用

類屬性和實(shí)例屬性混合

class people:  
    name="tom"      #類屬性:實(shí)例對象和類對象可以同時(shí)調(diào)用  
    def  __init__(self,age):    #實(shí)例屬性  
        self.age=age  

p=people(18)    #實(shí)例對象  
p.sex="男"       #實(shí)例屬性  

print(p.name)  
print(p.age)    #實(shí)例屬性是實(shí)例對象特有的,類對象不能擁有  
print(p.sex)  

print(people.name)  #類對象  
# print(people.age)  #錯誤:實(shí)例屬性艺骂,不能通過類對象調(diào)用  
# print(people.sex)  #錯誤:實(shí)例屬性诸老,不能通過類對象調(diào)用

如果在類外修改類屬性,必須通過類對象去引用然后進(jìn)行修改钳恕。如果通過實(shí)例對象去引用别伏,會產(chǎn)生一個(gè)同名的實(shí)例屬性,這種方式修改的是實(shí)例屬性忧额,不會影響到類屬性厘肮,并且如果通過實(shí)例對象引用該名稱的屬性,實(shí)例屬性會強(qiáng)制屏蔽掉類屬性睦番,即引用的是實(shí)例屬性轴脐,除非刪除了該實(shí)例屬性

class Animal:  
    name="Panda"  

print(Animal.name)  #類對象引用類屬性  
p=Animal()  
print(p.name)       #實(shí)例對象引用類屬性時(shí),會產(chǎn)生一個(gè)同名的實(shí)例屬性  
p.name="dog"        #修改的只是實(shí)例屬性的抡砂,不會影響到類屬性  
print(p.name)         #dog  
print(Animal.name)    #panda  

# 刪除實(shí)例屬性  
del p.name  
print(p.name)

9.2 類屬性的應(yīng)用場景

比如大咱,我們有一個(gè)班級類,創(chuàng)建班級對象的時(shí)候注益,需要按序號指定班級名稱碴巾,我們就需要知道當(dāng)前已經(jīng)創(chuàng)建了多少個(gè)班級對象,這個(gè)數(shù)量可以設(shè)計(jì)成類屬性

class NeuEduClass:
    class_num = 0

    def __init__(self):
        self.class_name = f'東軟睿道Python{NeuEduClass.class_num+1}班'
        NeuEduClass.class_num += 1


classList = [NeuEduClass() for i in range(10)]
for c in classList:
    print(c.class_name)

輸出

東軟睿道Python1班
東軟睿道Python2班
東軟睿道Python3班
東軟睿道Python4班
東軟睿道Python5班
東軟睿道Python6班
東軟睿道Python7班
東軟睿道Python8班
東軟睿道Python9班
東軟睿道Python10班

9.3 類方法

類對象所擁有的方法丑搔,需要用修飾器@classmethod來標(biāo)識其為類方法厦瓢,對于類方法,第一個(gè)參數(shù)必須是類對象啤月,一般以cls作為第一個(gè)參數(shù)(當(dāng)然可以用其他名稱的變量作為其第一個(gè)參數(shù)煮仇,但是大部分人都習(xí)慣以'cls'作為第一個(gè)參數(shù)的名字),能夠通過實(shí)例對象和類對象去訪問谎仲。

class people:  
    country="china"  

    @classmethod  
    def getCountry(cls):  
        return cls.country  

p=people()  
print(p.getCountry())   #實(shí)例對象調(diào)用類方法  
print(people.getCountry())  #類對象調(diào)用類方法

類方法還有一個(gè)用途就是可以對類屬性進(jìn)行修改:

class people:  
    country="china"  

    @classmethod  
    def getCountry(cls):  
        return cls.country  
    @classmethod  
    def setCountry(cls,country):  
        cls.country=country  


p=people()  
print(p.getCountry())   #實(shí)例對象調(diào)用類方法  
print(people.getCountry())  #類對象調(diào)用類方法  

p.setCountry("Japan")  

print(p.getCountry())  
print(people.getCountry())

9.4 靜態(tài)方法
需要通過修飾器@staticmethod來進(jìn)行修飾浙垫,靜態(tài)方法不需要定義參數(shù)

class people3:  
    country="china"  

    @staticmethod  
    def getCountry():  
        return people3.country  

p=people3()  
print(p.getCountry())   #實(shí)例對象調(diào)用類方法  
print(people3.getCountry())  #類對象調(diào)用類方法

10)繼承

繼承的概念:子類 自動擁有(繼承) 父類 的所有 方法 和 屬性 1) 繼承的語法

class 類名(父類名):
    pass
  • 子類 繼承自 父類,可以直接 享受 父類中已經(jīng)封裝好的方法郑诺,不需要再次開發(fā)
  • 子類 中應(yīng)該根據(jù) 職責(zé)夹姥,封裝 子類特有的 屬性和方法
  • 當(dāng) 父類 的方法實(shí)現(xiàn)不能滿足子類需求時(shí),可以對方法進(jìn)行 重寫(override)
    舉一個(gè)常見的例子辙诞。Circle 和 Rectangle 辙售,不同的圖形,面積(area)計(jì)算方式不同飞涂。
import math


class Circle:
    def __init__(self, color, r):
        self.r = r
        self.color = color

    def area(self):
        return math.pi * self.r * self.r

    def show_color(self):
        print(self.color)


class Rectangle:
    def __init__(self, color, a, b):
        self.color = color
        self.a, self.b = a, b

    def area(self):
        return self.a * self.b

    def show_color(self):
        print(self.color)

circle = Circle('red', 3.0)
print(circle.area())
circle.show_color()
rectangle = Rectangle('blue', 2.0, 3.0)
print(rectangle.area())
rectangle.show_color()

輸出

28.274333882308138
red
6.0
blue

我們看到Rectangle和Circle有同樣的屬性color和方法showcolor 我們可以定義一個(gè)父類Shape旦部,將Rectangle和Circle通用的部分提取到Shape類中祈搜,然后在子類的init方法中,通過 調(diào)用super()init(color). 把 color 傳給父類的 _init()

import math


class Shape:
    def __init__(self, color):
        self.color = color

    def area(self):
        return None

    def show_color(self):
        print(self.color)


class Circle(Shape):
    def __init__(self, color, r):
        super().__init__(color)
        # Shape.__init__(self,color) #這樣也行士八,但是不好(考慮父類Shape的名字改變了容燕,怎么辦)
        self.r = r

    def area(self):
        return math.pi * self.r * self.r




class Rectangle(Shape):
    def __init__(self, color, a, b):
        super().__init__(color)
        # Shape.__init__(self, color)   #這樣也行,但是不好(考慮父類Shape的名字改變了曹铃,怎么辦)
        self.a, self.b = a, b

    def area(self):
        return self.a * self.b



circle = Circle('red', 3.0)
print(circle.area())
circle.show_color()
rectangle = Rectangle('blue', 2.0, 3.0)
print(rectangle.area())
rectangle.show_color()

輸出

28.274333882308138
red
6.0
blue

子類Circle和Rectangle本身并沒有定義show_color方法缰趋, 從父類Shape繼承了show_color方法。子類Circle和Rectangle改寫(Override)了父類的area方法陕见,分別提供了自己不同的實(shí)現(xiàn)秘血。

注釋掉Circle類中init方法中super()._init_()這行代碼:

class Circle(Shape):
    def __init__(self, color, r):
        # super().__init__(color)
        # Shape.__init__(self,color) #這樣也行,但是不好(考慮父類Shape的名字改變了评甜,怎么辦)
        self.r = r

再次運(yùn)行代碼灰粮,報(bào)錯:

  File "C:/Users/Administrator/PycharmProjects/untitled16/shape.py", line 12, in show_color
    print(self.color)
AttributeError: 'Circle' object has no attribute 'color'

錯誤輸出指定的出錯位置在:print(self.color),說Circle類型對象沒有color屬性

class Shape:
    def show_color(self):
        print(self.color)
問題原因是忍坷,Circle類型重寫了父類Shape的_init_()方法粘舟,導(dǎo)致父類Shape的__init_()方法沒有被調(diào)用到,所以

一定不要忘記在子類的init方法中調(diào)用super()._init_()

10.1) 重構(gòu)英雄pk怪物

我們發(fā)現(xiàn)Hero類和Monster類中有很多代碼是重復(fù)的佩研,我們把這些重復(fù)的代碼提取到一個(gè)父類Sprite(精靈)中柑肴。 sprite.py

from random import randint


class Sprite:

    def __init__(self, flood,strength):
        self.flood = flood
        self.strength = strength

    def calc_health(self):
        return self.flood

    def take_damage(self, attack_sprite):
        damage = randint(attack_sprite.strength - 5, attack_sprite.strength + 5)
        self.flood -= damage
        print(f"{self.name}你被{attack_sprite.name}攻擊,受到了{(lán)str(damage)}點(diǎn)傷害!還剩{str(self.flood)}滴血")
        if self.calc_health() <= 0:
            print(f"{self.name}你被殺死了!勝敗乃兵家常事 請重新來過旬薯。")
            return True
        else:
            return False

hero.py

from sprite import Sprite


class Hero(Sprite):
    def __init__(self, name,flood,strength):
        self.name = name
        super().__init__(flood,strength)

monster.py

from sprite import Sprite


class Monster(Sprite):
    def __init__(self, name,flood,strength):
        self.name = name
        super().__init__(flood, strength)

pkgame.py不變

from hero import Hero
from monsters import Monster

hero = Hero('張三',100, 10)
monster = Monster('小強(qiáng)',60,20)

while True:
    is_monster_died = monster.take_damage(hero)
    if is_monster_died:
        break
    is_hero_died = hero.take_damage(monster)
    if is_hero_died:
        break

輸出

小強(qiáng)你被張三攻擊晰骑,受到了5點(diǎn)傷害!還剩55滴血
張三你被小強(qiáng)攻擊,受到了19點(diǎn)傷害!還剩81滴血
小強(qiáng)你被張三攻擊绊序,受到了9點(diǎn)傷害!還剩46滴血
張三你被小強(qiáng)攻擊硕舆,受到了25點(diǎn)傷害!還剩56滴血
小強(qiáng)你被張三攻擊,受到了12點(diǎn)傷害!還剩34滴血
張三你被小強(qiáng)攻擊骤公,受到了21點(diǎn)傷害!還剩35滴血
小強(qiáng)你被張三攻擊抚官,受到了5點(diǎn)傷害!還剩29滴血
張三你被小強(qiáng)攻擊,受到了23點(diǎn)傷害!還剩12滴血
小強(qiáng)你被張三攻擊阶捆,受到了13點(diǎn)傷害!還剩16滴血
張三你被小強(qiáng)攻擊凌节,受到了16點(diǎn)傷害!還剩-4滴血
張三你被殺死了!勝敗乃兵家常事 請重新來過。

進(jìn)一步改造 假設(shè)我們想傷害值damage的大小趁猴,不在Sprite類里統(tǒng)一處理刊咳,而由各個(gè)具體的精靈(Hero或Monster)自己來決定,代碼可以改造成如下: 在Sprite類中添加get_damage_value方法儡司,不提供實(shí)現(xiàn)

from random import randint


class Sprite:

    def __init__(self, flood,strength):
        self.flood = flood
        self.strength = strength

    def calc_health(self):
        return self.flood

    def get_damage_value(self):
        pass

    def take_damage(self, attack_sprite):
        # damage = randint(attack_sprite.strength - 5, attack_sprite.strength + 5)
        damage = attack_sprite.get_damage_value();
        self.flood -= damage
        print(f"{self.name}你被{attack_sprite.name}攻擊,受到了{(lán)str(damage)}點(diǎn)傷害!還剩{str(self.flood)}滴血")
        if self.calc_health() <= 0:
            print(f"{self.name}你被殺死了!勝敗乃兵家常事 請重新來過余指。")
            return True
        else:
            return False

hero.py提供自己get_damage_value方法的實(shí)現(xiàn)

from random import randint

from sprite import Sprite


class Hero(Sprite):
    def __init__(self, name,flood,strength):
        self.name = name
        super().__init__(flood,strength)

    def get_damage_value(self):
        return randint(self.strength - 3, self.strength + 3)

monster.py提供自己get_damage_value方法的實(shí)現(xiàn)

from random import randint

from sprite import Sprite


class Monster(Sprite):
    def __init__(self, name,flood,strength):
        self.name = name
        super().__init__(flood, strength)

    def get_damage_value(self):
        return randint(self.strength - 7, self.strength + 7)

輸出

小強(qiáng)你被張三攻擊捕犬,受到了8點(diǎn)傷害!還剩52滴血
張三你被小強(qiáng)攻擊跷坝,受到了13點(diǎn)傷害!還剩87滴血
小強(qiáng)你被張三攻擊,受到了11點(diǎn)傷害!還剩41滴血
張三你被小強(qiáng)攻擊碉碉,受到了19點(diǎn)傷害!還剩68滴血
小強(qiáng)你被張三攻擊柴钻,受到了7點(diǎn)傷害!還剩34滴血
張三你被小強(qiáng)攻擊,受到了22點(diǎn)傷害!還剩46滴血
小強(qiáng)你被張三攻擊垢粮,受到了9點(diǎn)傷害!還剩25滴血
張三你被小強(qiáng)攻擊贴届,受到了25點(diǎn)傷害!還剩21滴血
小強(qiáng)你被張三攻擊,受到了9點(diǎn)傷害!還剩16滴血
張三你被小強(qiáng)攻擊蜡吧,受到了24點(diǎn)傷害!還剩-3滴血
張三你被殺死了!勝敗乃兵家常事 請重新來過毫蚓。

11)_new_()方法

python中定義的類在創(chuàng)建實(shí)例對象的時(shí)候,會自動執(zhí)行init()方法昔善,但是在執(zhí)行init()方法之前元潘,會執(zhí)行new()方法。

new()的作用主要有兩個(gè)君仆。

1.在內(nèi)存中為對象分配空間
2.返回對象的引用翩概。(即對象的內(nèi)存地址)

python解釋器在獲得引用的時(shí)候會將其傳遞給init()方法中的self。

class A:
    def __new__(cls,*args,**kwargs):
        print('__new__')
        return super().__new__(cls)#這里一定要返回返咱,否則__init__()方法不會被執(zhí)行
    def __init__(self):#這里的self就是new方法中的return返回值
        print('__init__')

a = A()

輸出結(jié)果

__new__
__init__

我們一定要在new方法中最后調(diào)用

return super().__new__(cls)

否則init方法不會被調(diào)用

class A:
    def __new__(cls,*args,**kwargs):
        print('__new__')
        # return super().__new__(cls)#這里一定要返回钥庇,否則__init__()方法不會被執(zhí)行
    def __init__(self):#這里的self就是new方法中的return返回值
        print('__init__')


a = A()

輸出

__new__

像以前一樣,我們不寫new方法試試

class A:
    # def __new__(cls,*args,**kwargs):
    #     print('__new__')
        # return super().__new__(cls)#這里一定要返回咖摹,否則__init__()方法不會被執(zhí)行
    def __init__(self):#這里的self就是new方法中的return返回值
        print('__init__')


a = A()

輸出

__init__

12)object

在Python中评姨,所有類型有個(gè)隱式的父類(object),上面的代碼相當(dāng)于

class A(object):
    # def __new__(cls,*args,**kwargs):
    #     print('__new__')
        # return super().__new__(cls)#這里一定要返回楞艾,否則__init__()方法不會被執(zhí)行
    def __init__(self):#這里的self就是new方法中的return返回值
        print('__init__')

a = A()

當(dāng)我們的類中沒有定義new方法時(shí)参咙,創(chuàng)建對象時(shí),Python會先調(diào)用父類(object)的new方法硫眯,在內(nèi)存中創(chuàng)建一個(gè)實(shí)例蕴侧,然后傳遞給我們的init方法。如果我們的自定義類型定義了new方法两入,就會覆蓋父類(object)的__new方法(父類的__new方法不會被自動調(diào)用)净宵,所以我們要顯式調(diào)用父類(object)的__new\方法,在內(nèi)存中創(chuàng)建一個(gè)實(shí)例裹纳。

那么new有什么作用呢择葡?我們可以改寫它,舉個(gè)例子剃氧,就比如說單例模式敏储。

13)單例模式

如果我們創(chuàng)建兩個(gè)實(shí)例:

a1 = A()
a2 = A()

那么id(a1)和id(a2)的值不一樣,也就是說python在內(nèi)容當(dāng)中創(chuàng)建了兩個(gè)實(shí)例對象朋鞍,用了兩份內(nèi)存已添。同樣的東西創(chuàng)建了兩份

如果想不管創(chuàng)建多少個(gè)實(shí)例對象妥箕,我們都讓它的id是一樣的。

也就是說更舞,先創(chuàng)建一個(gè)實(shí)例對象畦幢,之后不管創(chuàng)建多少個(gè),返回的永遠(yuǎn)都是第一個(gè)實(shí)例對象的內(nèi)存地址缆蝉∮畲校可以這樣實(shí)現(xiàn):

# 重寫new方法很固定,返回值必須是這個(gè)
# 這樣就避免了創(chuàng)建多份刊头。
# 創(chuàng)建第一個(gè)實(shí)例的時(shí)候黍瞧,_instance是None,那么會分配空間創(chuàng)建實(shí)例芽偏。
# 此時(shí)的類屬性已經(jīng)被修改雷逆,_instance不再為None
# 那么當(dāng)之后實(shí)例屬性被創(chuàng)建的時(shí)候,由于_instance不為None污尉。
# 則返回第一個(gè)實(shí)例對象的引用膀哲,即內(nèi)存地址。
# 這樣就應(yīng)用了單例模式被碗。
class A():
    _instance = None
    def __new__(cls,*args,**kwargs):
        if A._instance == None:
            A._instance = super().__new__(cls)
        return A._instance


a1 = A()
print(id(a1))
a2 = A()
print(id(a2))

14)函數(shù)參數(shù)注解

你寫好了一個(gè)函數(shù)某宪,然后想為這個(gè)函數(shù)的參數(shù)增加一些額外的信息(每個(gè)參數(shù)的類型),這樣的話其他調(diào)用者就能清楚的知道這個(gè)函數(shù)應(yīng)該怎么使用锐朴。

解決方案

使用函數(shù)參數(shù)注解是一個(gè)很好的辦法兴喂,它能提示程序員應(yīng)該怎樣正確使用這個(gè)函數(shù)。 例如焚志,下面有一個(gè)被注解了的函數(shù):

def add(x:int, y:int) -> int:
    return x + y

python解釋器不會對這些注解添加任何的語義衣迷。它們不會被類型檢查,運(yùn)行時(shí)跟沒有加注解之前的效果也沒有任何差距酱酬。 然而壶谒,對于那些閱讀源碼的人來講就很有幫助啦。第三方工具和框架可能會對這些注解添加語義膳沽。同時(shí)它們也會出現(xiàn)在文檔中汗菜。

>>> help(add)
Help on function add in module __main__:
add(x: int, y: int) -> int
>>>

盡管你可以使用任意類型的對象給函數(shù)添加注解(例如數(shù)字,字符串挑社,對象實(shí)例等等)陨界,不過通常來講使用類或者字符串會比較好點(diǎn)。

函數(shù)注解只存儲在函數(shù)的 annotations 屬性中痛阻。例如:

>>> add.__annotations__
{'y': <class 'int'>, 'return': <class 'int'>, 'x': <class 'int'>}
>>>

盡管注解的使用方法可能有很多種菌瘪,但是它們的主要用途還是文檔。 因?yàn)閜ython并沒有類型聲明阱当,通常來講僅僅通過閱讀源碼很難知道應(yīng)該傳遞什么樣的參數(shù)給這個(gè)函數(shù)麻车。 這時(shí)候使用注解就能給程序員更多的提示缀皱,讓他們可以正確的使用函數(shù)斗这。

函數(shù)參數(shù)注解還給我們帶來的好處有使得pycharm這樣的IDE可以自動提示該類型對象擁有的方法。

class A:
    def dosomething(self):
        print('hello')


def foo(a : A):
    a.dosomething()

a = A()
foo(a)

在foo函數(shù)的定義中,如果我們沒有指定a:A拥褂,當(dāng)我們輸入a.時(shí)镇匀,IDE提示不出來dosomething方法

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市免钻,隨后出現(xiàn)的幾起案子彼水,更是在濱河造成了極大的恐慌,老刑警劉巖极舔,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件凤覆,死亡現(xiàn)場離奇詭異,居然都是意外死亡拆魏,警方通過查閱死者的電腦和手機(jī)盯桦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渤刃,“玉大人拥峦,你說我怎么就攤上這事÷糇樱” “怎么了略号?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長洋闽。 經(jīng)常有香客問我玄柠,道長,這世上最難降的妖魔是什么诫舅? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任羽利,我火速辦了婚禮,結(jié)果婚禮上骚勘,老公的妹妹穿的比我還像新娘铐伴。我一直安慰自己,他們只是感情好俏讹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布当宴。 她就那樣靜靜地躺著,像睡著了一般泽疆。 火紅的嫁衣襯著肌膚如雪户矢。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天殉疼,我揣著相機(jī)與錄音梯浪,去河邊找鬼捌年。 笑死,一個(gè)胖子當(dāng)著我的面吹牛挂洛,可吹牛的內(nèi)容都是我干的礼预。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼虏劲,長吁一口氣:“原來是場噩夢啊……” “哼托酸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起柒巫,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤励堡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后堡掏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體应结,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年泉唁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鹅龄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡游两,死狀恐怖砾层,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情贱案,我是刑警寧澤肛炮,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布,位于F島的核電站宝踪,受9級特大地震影響侨糟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜瘩燥,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一秕重、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厉膀,春花似錦溶耘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至企软,卻和暖如春庐扫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工形庭, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留铅辞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓萨醒,卻偏偏與公主長得像斟珊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子验靡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

推薦閱讀更多精彩內(nèi)容