Python學(xué)習(xí)記錄3

從函數(shù)到高級(jí)魔法方法

Python 是一種通用編程語(yǔ)言,其在科學(xué)計(jì)算和機(jī)器學(xué)習(xí)領(lǐng)域具有廣泛的應(yīng)用季惯。如果我們打算利用 Python 來(lái)執(zhí)行機(jī)器學(xué)習(xí)霞丧,那么對(duì) Python 有一些基本的了解就是至關(guān)重要的目锭。本 Python 入門(mén)系列體驗(yàn)就是為這樣的初學(xué)者精心準(zhǔn)備的厌秒。

函數(shù)

函數(shù)的定義

還記得 Python 里面“萬(wàn)物皆對(duì)象”么?Python 把函數(shù)也當(dāng)成對(duì)象汉形,可以從另一個(gè)函數(shù)中返回出來(lái)而去構(gòu)建高階函數(shù)纸镊,比如: 參數(shù)是函數(shù)、返回值是函數(shù)概疆。

  • 函數(shù)以def關(guān)鍵字開(kāi)頭逗威,后接函數(shù)名和圓括號(hào)()。
  • 函數(shù)執(zhí)行的代碼以冒號(hào)起始届案,并且縮進(jìn)庵楷。
  • runturn[表達(dá)式]結(jié)束函數(shù),選擇性地返回一個(gè)值給調(diào)用方楣颠。不帶表達(dá)式的return相當(dāng)于返回None尽纽。

def functionname (parameters):
“函數(shù)文檔字符串”
functionsuite
return [expression]

函數(shù)的調(diào)用
def printme(str):
    print(str)


printme("我要調(diào)用用戶自定義函數(shù)!")  # 我要調(diào)用用戶自定義函數(shù)!
printme("再次調(diào)用同一函數(shù)")  # 再次調(diào)用同一函數(shù)
temp = printme('hello') # hello
print(temp)  # None
函數(shù)文檔
def MyFirstFunction(name):
    "函數(shù)定義過(guò)程中name是形參"
    # 因?yàn)門(mén)a只是一個(gè)形式,表示占據(jù)一個(gè)參數(shù)位置
    print('傳遞進(jìn)來(lái)的{0}叫做實(shí)參童漩,因?yàn)門(mén)a是具體的參數(shù)值弄贿!'.format(name))


MyFirstFunction('老馬的程序人生')  
# 傳遞進(jìn)來(lái)的老馬的程序人生叫做實(shí)參,因?yàn)門(mén)a是具體的參數(shù)值矫膨!

print(MyFirstFunction.__doc__)  
# 函數(shù)定義過(guò)程中name是形參

help(MyFirstFunction)
# Help on function MyFirstFunction in module __main__:
# MyFirstFunction(name)
#    函數(shù)定義過(guò)程中name是形參
函數(shù)參數(shù)

Python 的函數(shù)具有非常靈活多樣的參數(shù)形態(tài)差凹,既可以實(shí)現(xiàn)簡(jiǎn)單的調(diào)用,又可以傳入非常復(fù)雜的參數(shù)侧馅。從簡(jiǎn)到繁的參數(shù)形態(tài)如下:

  • 位置參數(shù) (positional argument)
  • 默認(rèn)參數(shù) (default argument)
  • 可變參數(shù) (variable argument): *args - 可變參數(shù)危尿,可以是從零個(gè)到任意個(gè),自動(dòng)組裝成元組馁痴。
    加了星號(hào)(*)的變量名會(huì)存放所有未命名的變量參數(shù)
  • 關(guān)鍵字參數(shù) (keyword argument): **kw - 關(guān)鍵字參數(shù)谊娇,可以是從零個(gè)到任意個(gè),自動(dòng)組裝成字典罗晕。

「可變參數(shù)」和「關(guān)鍵字參數(shù)」的同異總結(jié)如下:

  • 可變參數(shù)允許傳入零個(gè)到任意個(gè)參數(shù)济欢,它們?cè)诤瘮?shù)調(diào)用時(shí)自動(dòng)組裝為一個(gè)元組 (tuple)赠堵。
  • 關(guān)鍵字參數(shù)允許傳入零個(gè)到任意個(gè)參數(shù),它們?cè)诤瘮?shù)內(nèi)部自動(dòng)組裝為一個(gè)字典 (dict)法褥。
  • 命名關(guān)鍵字參數(shù) (name keyword argument)
  • *, nkw - 命名關(guān)鍵字參數(shù)茫叭,用戶想要輸入的關(guān)鍵字參數(shù),定義方式是在nkw 前面加個(gè)分隔符 *半等。
  • 如果要限制關(guān)鍵字參數(shù)的名字揍愁,就可以用「命名關(guān)鍵字參數(shù)」
  • 使用命名關(guān)鍵字參數(shù)時(shí),要特別注意不能缺少參數(shù)名酱鸭。
def printinfo(arg1, *, nkw, **kwargs):
    print(arg1)
    print(nkw)
    print(kwargs)


printinfo(70, nkw=10, a=1, b=2)
# 70
# 10
# {'a': 1, 'b': 2}

printinfo(70, 10, a=1, b=2)
# TypeError: printinfo() takes 1 positional argument but 2 were given

沒(méi)有寫(xiě)參數(shù)名nwk吗垮,因此 10 被當(dāng)成「位置參數(shù)」垛吗,而原函數(shù)只有 1 個(gè)位置函數(shù)凹髓,現(xiàn)在調(diào)用了 2 個(gè),因此程序會(huì)報(bào)錯(cuò)怯屉。

  • 參數(shù)組合

在 Python 中定義函數(shù)蔚舀,可以用位置參數(shù)、默認(rèn)參數(shù)锨络、可變參數(shù)赌躺、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù),這 5 種參數(shù)中的 4 個(gè)都可以一起使用羡儿,但是注意礼患,參數(shù)定義的順序必須是:

  • 位置參數(shù)、默認(rèn)參數(shù)掠归、可變參數(shù)和關(guān)鍵字參數(shù)缅叠。
  • 位置參數(shù)、默認(rèn)參數(shù)虏冻、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù)肤粱。

要注意定義可變參數(shù)和關(guān)鍵字參數(shù)的語(yǔ)法:

  • *args 是可變參數(shù),args 接收的是一個(gè) tuple
  • **kw 是關(guān)鍵字參數(shù)厨相,kw 接收的是一個(gè) dict

命名關(guān)鍵字參數(shù)是為了限制調(diào)用者可以傳入的參數(shù)名领曼,同時(shí)可以提供默認(rèn)值。定義命名關(guān)鍵字參數(shù)不要忘了寫(xiě)分隔符 *蛮穿,否則定義的是位置參數(shù)庶骄。
警告:雖然可以組合多達(dá) 5 種參數(shù),但不要同時(shí)使用太多的組合践磅,否則函數(shù)很難懂单刁。

函數(shù)的返回值
def add(a, b):
    return a + b


print(add(1, 2))  # 3
print(add([1, 2, 3], [4, 5, 6]))  # [1, 2, 3, 4, 5, 6]

def back():
    return [1, '小馬的程序人生', 3.14]


print(back())  # [1, '小馬的程序人生', 3.14]

def back():
    return 1, '小馬的程序人生', 3.14


print(back())  # (1, '小馬的程序人生', 3.14)

def printme(str):
    print(str)

temp = printme('hello') # hello
print(temp) # None
print(type(temp))  # <class 'NoneType'>
變量作用域
  • Python 中,程序的變量并不是在哪個(gè)位置都可以訪問(wèn)的音诈,訪問(wèn)權(quán)限決定于這個(gè)變量是在哪里賦值的幻碱。
  • 定義在函數(shù)內(nèi)部的變量擁有局部作用域绎狭,該變量稱(chēng)為局部變量。
  • 定義在函數(shù)外部的變量擁有全局作用域褥傍,該變量稱(chēng)為全局變量儡嘶。
  • 局部變量只能在其被聲明的函數(shù)內(nèi)部訪問(wèn),而全局變量可以在整個(gè)程序范圍內(nèi)訪問(wèn)恍风。
def discounts(price, rate):
    final_price = price * rate
    return final_price


old_price = float(input('請(qǐng)輸入原價(jià):'))  # 98
rate = float(input('請(qǐng)輸入折扣率:'))  # 0.9
new_price = discounts(old_price, rate)
print('打折后價(jià)格是:%.2f' % new_price)  # 88.20
  • 當(dāng)內(nèi)部作用域想修改外部作用域的變量時(shí)蹦狂,就要用到global和nonlocal關(guān)鍵字了。
num = 1


def fun1():
    global num  # 需要使用 global 關(guān)鍵字聲明
    print(num)  # 1
    num = 123
    print(num)  # 123


fun1()
print(num)  # 123
內(nèi)嵌函數(shù)
def outer():
    print('outer函數(shù)在這被調(diào)用')

    def inner():
        print('inner函數(shù)在這被調(diào)用')

    inner()  # 該函數(shù)只能在outer函數(shù)內(nèi)部被調(diào)用


outer()
# outer函數(shù)在這被調(diào)用
# inner函數(shù)在這被調(diào)用
閉包
  • 是函數(shù)式編程的一個(gè)重要的語(yǔ)法結(jié)構(gòu)朋贬,是一種特殊的內(nèi)嵌函數(shù)凯楔。
  • 如果在一個(gè)內(nèi)部函數(shù)里對(duì)外層非全局作用域的變量進(jìn)行引用,那么內(nèi)部函數(shù)就被認(rèn)為是閉包锦募。
  • 通過(guò)閉包可以訪問(wèn)外層非全局作用域的變量摆屯,這個(gè)作用域稱(chēng)為 閉包作用域。
def make_counter(init):
    counter = [init]

    def inc(): counter[0] += 1

    def dec(): counter[0] -= 1

    def get(): return counter[0]

    def reset(): counter[0] = init

    return inc, dec, get, reset


inc, dec, get, reset = make_counter(0)
inc()
inc()
inc()
print(get())  # 3
dec()
print(get())  # 2
reset()
print(get())  # 0

如果要修改閉包作用域中的變量則需要 nonlocal 關(guān)鍵字

def outer():
    num = 10

    def inner():
        nonlocal num  # nonlocal關(guān)鍵字聲明
        num = 100
        print(num)

    inner()
    print(num)


outer()

# 100
# 100
遞歸
  • 如果一個(gè)函數(shù)在內(nèi)部調(diào)用自身本身糠亩,這個(gè)函數(shù)就是遞歸函數(shù)虐骑。
# 利用循環(huán)
i = 0
j = 1
lst = list([i, j])
for k in range(2, 11):
    k = i + j
    lst.append(k)
    i = j
    j = k
print(lst)  
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

# 利用遞歸
def recur_fibo(n):
    if n <= 1:
        return n
    return recur_fibo(n - 1) + recur_fibo(n - 2)


lst = list()
for k in range(11):
    lst.append(recur_fibo(k))
print(lst)  
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

Lambda表達(dá)式

匿名函數(shù)的定義

在 Python 里有兩類(lèi)函數(shù):

  • 第一類(lèi):用 def 關(guān)鍵詞定義的正規(guī)函數(shù)
  • 第二類(lèi):用 lambda 關(guān)鍵詞定義的匿名函數(shù)

Python 使用 lambda 關(guān)鍵詞來(lái)創(chuàng)建匿名函數(shù),而非def關(guān)鍵詞赎线,它沒(méi)有函數(shù)名廷没,其語(yǔ)法結(jié)構(gòu)如下:

lambda argument_list: expression

  • lambda - 定義匿名函數(shù)的關(guān)鍵詞。
  • argument_list - 函數(shù)參數(shù)垂寥,它們可以是位置參數(shù)颠黎、默認(rèn)參數(shù)、關(guān)鍵字參數(shù)滞项,和正規(guī)函數(shù)里的參數(shù)類(lèi)型一樣狭归。
  • :- 冒號(hào),在函數(shù)參數(shù)和表達(dá)式中間要加個(gè)冒號(hào)蓖扑。
  • expression - 只是一個(gè)表達(dá)式唉铜,輸入函數(shù)參數(shù),輸出一些值律杠。

注意:

  • expression 中沒(méi)有 return 語(yǔ)句潭流,因?yàn)?lambda 不需要它來(lái)返回,表達(dá)式本身結(jié)果就是返回值柜去。
  • 匿名函數(shù)擁有自己的命名空間灰嫉,且不能訪問(wèn)自己參數(shù)列表之外或全局命名空間里的參數(shù)。
def sqr(x):
    return x ** 2


print(sqr)
# <function sqr at 0x000000BABD3A4400>

y = [sqr(x) for x in range(10)]
print(y)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

lbd_sqr = lambda x: x ** 2
print(lbd_sqr)
# <function <lambda> at 0x000000BABB6AC1E0>

y = [lbd_sqr(x) for x in range(10)]
print(y)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]


sumary = lambda arg1, arg2: arg1 + arg2
print(sumary(10, 20))  # 30

func = lambda *args: sum(args)
print(func(1, 2, 3, 4, 5))  # 15
匿名函數(shù)的應(yīng)用

函數(shù)式編程 是指代碼中每一塊都是不可變的嗓奢,都由純函數(shù)的形式組成讼撒。這里的純函數(shù),是指函數(shù)本身相互獨(dú)立、互不影響根盒,對(duì)于相同的輸入钳幅,總會(huì)有相同的輸出,沒(méi)有任何副作用炎滞。
非函數(shù)式編程

def f(x):
    for i in range(0, len(x)):
         x[i] += 10
    return x

x = [1, 2, 3]
f(x)
print(x)
# [11, 12, 13]

函數(shù)式編程

def f(x):
    y = []
    for item in x:
        y.append(item + 10)
    return y

x = [1, 2, 3]
f(x)
print(x)
# [1, 2, 3]

匿名函數(shù) 常常應(yīng)用于函數(shù)式編程的高階函數(shù) (high-order function)中敢艰,主要有兩種形式:

  • 參數(shù)是函數(shù)(filter, map)
  • 返回值是函數(shù)(closure)

如,在 filter和map函數(shù)中的應(yīng)用:

  • filter(function, iterable) 過(guò)濾序列册赛,過(guò)濾掉不符合條件的元素钠导,返回一個(gè)迭代器對(duì)象,如果要轉(zhuǎn)換為列表森瘪,可以使用 list() 來(lái)轉(zhuǎn)換牡属。
odd = lambda x: x % 2 == 1
templist = filter(odd, [1, 2, 3, 4, 5, 6, 7, 8, 9])
print(list(templist))  # [1, 3, 5, 7, 9]
  • map(function, *iterables) 根據(jù)提供的函數(shù)對(duì)指定序列做映射。
m1 = map(lambda x: x ** 2, [1, 2, 3, 4, 5])
print(list(m1))  
# [1, 4, 9, 16, 25]

m2 = map(lambda x, y: x + y, [1, 3, 5, 7, 9], [2, 4, 6, 8, 10])
print(list(m2))  
# [3, 7, 11, 15, 19]

除了 Python 這些內(nèi)置函數(shù)扼睬,我們也可以自己定義高階函數(shù)逮栅。

def apply_to_list(fun, some_list):
    return fun(some_list)

lst = [1, 2, 3, 4, 5]
print(apply_to_list(sum, lst))
# 15

print(apply_to_list(len, lst))
# 5

print(apply_to_list(lambda x: sum(x) / len(x), lst))
# 3.0

類(lèi)與對(duì)象

對(duì)象=屬性+方法

對(duì)象是類(lèi)的實(shí)例。換句話說(shuō)痰驱,類(lèi)主要定義對(duì)象的結(jié)構(gòu)证芭,然后我們以類(lèi)為模板創(chuàng)建對(duì)象。類(lèi)不但包含方法定義担映,而且還包含所有實(shí)例共享的數(shù)據(jù)。

  • 封裝:信息封閉技術(shù)
class Turtle:  # Python中的類(lèi)名約定以大寫(xiě)字母開(kāi)頭
    """關(guān)于類(lèi)的一個(gè)簡(jiǎn)單例子"""
    # 屬性
    color = 'green'
    weight = 10
    legs = 4
    shell = True
    mouth = '大嘴'

    # 方法
    def climb(self):
        print('我正在很努力的向前爬...')

    def run(self):
        print('我正在飛快的向前跑...')

    def bite(self):
        print('咬死你咬死你!!')

    def eat(self):
        print('有得吃叫潦,真滿足...')

    def sleep(self):
        print('困了蝇完,睡了,晚安矗蕊,zzz')


tt = Turtle()
print(tt)
# <__main__.Turtle object at 0x0000007C32D67F98>

print(type(tt))
# <class '__main__.Turtle'>

print(tt.__class__)
# <class '__main__.Turtle'>

print(tt.__class__.__name__)
# Turtle

tt.climb()
# 我正在很努力的向前爬...

tt.run()
# 我正在飛快的向前跑...

tt.bite()
# 咬死你咬死你!!

# Python類(lèi)也是對(duì)象短蜕。它們是type的實(shí)例
print(type(Turtle))
# <class 'type'>
  • 繼承:子類(lèi)自動(dòng)共享父類(lèi)之間數(shù)據(jù)和方法的機(jī)制
class MyList(list):
    pass


lst = MyList([1, 5, 2, 7, 8])
lst.append(9)
lst.sort()
print(lst)

# [1, 2, 5, 7, 8, 9]
  • 多態(tài):不同對(duì)象對(duì)同一方法響應(yīng)不同的行動(dòng)
class Animal:
    def run(self):
        raise AttributeError('子類(lèi)必須實(shí)現(xiàn)這個(gè)方法')


class People(Animal):
    def run(self):
        print('人正在走')


class Pig(Animal):
    def run(self):
        print('pig is walking')


class Dog(Animal):
    def run(self):
        print('dog is running')


def func(animal):
    animal.run()


func(Pig())
# pig is walking
self是什么

Python 的 self 相當(dāng)于 C++ 的 this 指針。

class Test:
    def prt(self):
        print(self)
        print(self.__class__)


t = Test()
t.prt()
# <__main__.Test object at 0x000000BC5A351208>
# <class '__main__.Test'>

類(lèi)的方法與普通的函數(shù)只有一個(gè)特別的區(qū)別 —— 它們必須有一個(gè)額外的第一個(gè)參數(shù)名稱(chēng)(對(duì)應(yīng)于該實(shí)例傻咖,即該對(duì)象本身)朋魔,按照慣例它的名稱(chēng)是 self。在調(diào)用方法時(shí)卿操,我們無(wú)需明確提供與參數(shù) self 相對(duì)應(yīng)的參數(shù)警检。

class Ball:
    def setName(self, name):
        self.name = name

    def kick(self):
        print("我叫%s,該死的,誰(shuí)踢我..." % self.name)


a = Ball()
a.setName("球A")
b = Ball()
b.setName("球B")
c = Ball()
c.setName("球C")
a.kick()
# 我叫球A,該死的害淤,誰(shuí)踢我...
b.kick()
# 我叫球B,該死的扇雕,誰(shuí)踢我...
Python的魔法方法

據(jù)說(shuō),Python 的對(duì)象天生擁有一些神奇的方法窥摄,它們是面向?qū)ο蟮?Python 的一切...

它們是可以給你的類(lèi)增加魔力的特殊方法...

如果你的對(duì)象實(shí)現(xiàn)了這些方法中的某一個(gè)镶奉,那么這個(gè)方法就會(huì)在特殊的情況下被 Python 所調(diào)用,而這一切都是自動(dòng)發(fā)生的...

類(lèi)有一個(gè)名為init(self[, param1, param2...])的魔法方法,該方法在類(lèi)實(shí)例化時(shí)會(huì)自動(dòng)調(diào)用哨苛。

class Ball:
    def __init__(self, name):
        self.name = name

    def kick(self):
        print("我叫%s,該死的鸽凶,誰(shuí)踢我..." % self.name)


a = Ball("球A")
b = Ball("球B")
c = Ball("球C")
a.kick()
# 我叫球A,該死的,誰(shuí)踢我...
b.kick()
# 我叫球B,該死的建峭,誰(shuí)踢我...
公有和私有

在 Python 中定義私有變量只需要在變量名或函數(shù)名前加上“__”兩個(gè)下劃線吱瘩,那么這個(gè)函數(shù)或變量就會(huì)為私有的了。

類(lèi)的私有屬性實(shí)例

class JustCounter:
    __secretCount = 0  # 私有變量
    publicCount = 0  # 公開(kāi)變量

    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print(self.__secretCount)


counter = JustCounter()
counter.count()  # 1
counter.count()  # 2
print(counter.publicCount)  # 2

# Python的私有為偽私有
print(counter._JustCounter__secretCount)  # 2 
print(counter.__secretCount)  
# AttributeError: 'JustCounter' object has no attribute '__secretCount'

類(lèi)的私有方法實(shí)例

class Site:
    def __init__(self, name, url):
        self.name = name  # public
        self.__url = url  # private

    def who(self):
        print('name  : ', self.name)
        print('url : ', self.__url)

    def __foo(self):  # 私有方法
        print('這是私有方法')

    def foo(self):  # 公共方法
        print('這是公共方法')
        self.__foo()


x = Site('老馬的程序人生', 'https://blog.csdn.net/LSGO_MYP')
x.who()
# name  :  老馬的程序人生
# url :  https://blog.csdn.net/LSGO_MYP

x.foo()
# 這是公共方法
# 這是私有方法

x.__foo()
# AttributeError: 'Site' object has no attribute '__foo'
繼承

Python 同樣支持類(lèi)的繼承迹缀,派生類(lèi)的定義如下所示:

class DerivedClassName(BaseClassName):
statement-1 ... statement-N

BaseClassName(基類(lèi)名)必須與派生類(lèi)定義在一個(gè)作用域內(nèi)使碾。除了類(lèi),還可以用表達(dá)式祝懂,基類(lèi)定義在另一個(gè)模塊中時(shí)這一點(diǎn)非常有用:

class DerivedClassName(modname.BaseClassName):
statement-1 ... statement-N

Python 雖然支持多繼承的形式票摇,但我們一般不使用多繼承,因?yàn)槿菀滓鸹靵y砚蓬。

# 類(lèi)定義
class People:
    # 定義基本屬性
    name = ''
    age = 0
    # 定義私有屬性,私有屬性在類(lèi)外部無(wú)法直接進(jìn)行訪問(wèn)
    __weight = 0

    # 定義構(gòu)造方法
    def __init__(self, n, a, w):
        self.name = n
        self.age = a
        self.__weight = w

    def speak(self):
        print("%s 說(shuō): 我 %d 歲矢门。" % (self.name, self.age))


# 單繼承示例
class Student(People):
    grade = ''

    def __init__(self, n, a, w, g):
        # 調(diào)用父類(lèi)的構(gòu)函
        People.__init__(self, n, a, w)
        self.grade = g

    # 覆寫(xiě)父類(lèi)的方法
    def speak(self):
        print("%s 說(shuō): 我 %d 歲了,我在讀 %d 年級(jí)" % (self.name, self.age, self.grade))


# 另一個(gè)類(lèi)灰蛙,多重繼承之前的準(zhǔn)備
class Speaker:
    topic = ''
    name = ''

    def __init__(self, n, t):
        self.name = n
        self.topic = t

    def speak(self):
        print("我叫 %s祟剔,我是一個(gè)演說(shuō)家,我演講的主題是 %s" % (self.name, self.topic))


# 多重繼承
class Sample01(Speaker, Student):
    a = ''

    def __init__(self, n, a, w, g, t):
        Student.__init__(self, n, a, w, g)
        Speaker.__init__(self, n, t)

# 方法名同摩梧,默認(rèn)調(diào)用的是在括號(hào)中排前地父類(lèi)的方法
test = Sample01("Tim", 25, 80, 4, "Python")
test.speak()  
# 我叫 Tim物延,我是一個(gè)演說(shuō)家,我演講的主題是 Python

class Sample02(Student, Speaker):
    a = ''

    def __init__(self, n, a, w, g, t):
        Student.__init__(self, n, a, w, g)
        Speaker.__init__(self, n, t)

# 方法名同仅父,默認(rèn)調(diào)用的是在括號(hào)中排前地父類(lèi)的方法
test = Sample02("Tim", 25, 80, 4, "Python")
test.speak()  
# Tim 說(shuō): 我 25 歲了叛薯,我在讀 4 年級(jí)
組合
class Turtle:
    def __init__(self, x):
        self.num = x


class Fish:
    def __init__(self, x):
        self.num = x


class Pool:
    def __init__(self, x, y):
        self.turtle = Turtle(x)
        self.fish = Fish(y)

    def print_num(self):
        print("水池里面有烏龜%s只,小魚(yú)%s條" % (self.turtle.num, self.fish.num))


p = Pool(2, 3)
p.print_num()
# 水池里面有烏龜2只笙纤,小魚(yú)3條
類(lèi)耗溜、類(lèi)對(duì)象和實(shí)例對(duì)象

類(lèi)對(duì)象:創(chuàng)建一個(gè)類(lèi),其實(shí)也是一個(gè)對(duì)象也在內(nèi)存開(kāi)辟了一塊空間省容,稱(chēng)為類(lèi)對(duì)象抖拴,類(lèi)對(duì)象只有一個(gè)。

實(shí)例對(duì)象:就是通過(guò)實(shí)例化類(lèi)創(chuàng)建的對(duì)象腥椒,稱(chēng)為實(shí)例對(duì)象阿宅,實(shí)例對(duì)象可以有多個(gè)

類(lèi)屬性:類(lèi)里面方法外面定義的變量稱(chēng)為類(lèi)屬性。類(lèi)屬性所屬于類(lèi)對(duì)象并且多個(gè)實(shí)例對(duì)象之間共享同一個(gè)類(lèi)屬性寞酿,說(shuō)白了就是類(lèi)屬性所有的通過(guò)該類(lèi)實(shí)例化的對(duì)象都能共享家夺。

實(shí)例屬性:實(shí)例屬性和具體的某個(gè)實(shí)例對(duì)象有關(guān)系,并且一個(gè)實(shí)例對(duì)象和另外一個(gè)實(shí)例對(duì)象是不共享屬性的伐弹,說(shuō)白了實(shí)例屬性只能在自己的對(duì)象里面使用拉馋,其他的對(duì)象不能直接使用榨为,因?yàn)閟elf是誰(shuí)調(diào)用,它的值就屬于該對(duì)象煌茴。

注意:屬性與方法名相同随闺,屬性會(huì)覆蓋方法。

什么是綁定蔓腐?

Python 嚴(yán)格要求方法需要有實(shí)例才能被調(diào)用矩乐,這種限制其實(shí)就是 Python 所謂的綁定概念。

Python 對(duì)象的數(shù)據(jù)屬性通常存儲(chǔ)在名為.__ dict__的字典中回论,我們可以直接訪問(wèn)dict散罕,或利用 Python 的內(nèi)置函數(shù)vars()獲取.__ dict__。

class CC:
    def setXY(self, x, y):
        self.x = x
        self.y = y

    def printXY(self):
        print(self.x, self.y)


dd = CC()
print(dd.__dict__)
# {}

print(vars(dd))
# {}

print(CC.__dict__)
# {'__module__': '__main__', 'setXY': <function CC.setXY at 0x000000C3473DA048>, 'printXY': <function CC.printXY at 0x000000C3473C4F28>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}

dd.setXY(4, 5)
print(dd.__dict__)
# {'x': 4, 'y': 5}

print(vars(CC))
# {'__module__': '__main__', 'setXY': <function CC.setXY at 0x000000632CA9B048>, 'printXY': <function CC.printXY at 0x000000632CA83048>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}

print(CC.__dict__)
# {'__module__': '__main__', 'setXY': <function CC.setXY at 0x000000632CA9B048>, 'printXY': <function CC.printXY at 0x000000632CA83048>, '__dict__': <attribute '__dict__' of 'CC' objects>, '__weakref__': <attribute '__weakref__' of 'CC' objects>, '__doc__': None}
一些相關(guān)的內(nèi)置函數(shù)(BIF)
  • issubclass(class, classinfo) 方法用于判斷參數(shù) class 是否是類(lèi)型參數(shù) classinfo 的子類(lèi)傀蓉。
  • 一個(gè)類(lèi)被認(rèn)為是其自身的子類(lèi)欧漱。
  • classinfo可以是類(lèi)對(duì)象的元組,只要class是其中任何一個(gè)候選類(lèi)的子類(lèi)葬燎,則返回True误甚。
  • isinstance(object, classinfo) 方法用于判斷一個(gè)對(duì)象是否是一個(gè)已知的類(lèi)型,類(lèi)似type()谱净。
  • type()不會(huì)認(rèn)為子類(lèi)是一種父類(lèi)類(lèi)型窑邦,不考慮繼承關(guān)系。
  • isinstance()會(huì)認(rèn)為子類(lèi)是一種父類(lèi)類(lèi)型壕探,考慮繼承關(guān)系冈钦。
  • 如果第一個(gè)參數(shù)不是對(duì)象,則永遠(yuǎn)返回False浩蓉。
  • 如果第二個(gè)參數(shù)不是類(lèi)或者由類(lèi)對(duì)象組成的元組派继,會(huì)拋出一個(gè)TypeError異常。
  • hasattr(object, name)用于判斷對(duì)象是否包含對(duì)應(yīng)的屬性捻艳。
  • getattr(object, name[, default])用于返回一個(gè)對(duì)象屬性值。
  • setattr(object, name, value)對(duì)應(yīng)函數(shù) getattr()庆猫,用于設(shè)置屬性值认轨,該屬性不一定是存在的。
  • delattr(object, name)用于刪除屬性月培。
  • class property([fget[, fset[, fdel[, doc]]]])用于在新式類(lèi)中返回屬性值嘁字。

fget -- 獲取屬性值的函數(shù)
fset -- 設(shè)置屬性值的函數(shù)
fdel -- 刪除屬性值函數(shù)
doc -- 屬性描述信息


魔法方法

魔法方法總是被雙下劃線包圍,例如init杉畜。

魔法方法是面向?qū)ο蟮?Python 的一切纪蜒,如果你不知道魔法方法,說(shuō)明你還沒(méi)能意識(shí)到面向?qū)ο蟮?Python 的強(qiáng)大此叠。

魔法方法的“魔力”體現(xiàn)在它們總能夠在適當(dāng)?shù)臅r(shí)候被自動(dòng)調(diào)用纯续。

魔法方法的第一個(gè)參數(shù)應(yīng)為cls(類(lèi)方法) 或者self(實(shí)例方法)。

  • clc:代表一個(gè)類(lèi)的名稱(chēng)
  • self: 代表一個(gè)實(shí)例對(duì)象的名稱(chēng)
基本的魔法方法
  • init(self[, ...]) 構(gòu)造器,當(dāng)一個(gè)實(shí)例被創(chuàng)建的時(shí)候調(diào)用的初始化方法猬错。
  • new(cls[, ...]) 在一個(gè)對(duì)象實(shí)例化的時(shí)候所調(diào)用的第一個(gè)方法窗看,在調(diào)用init初始化前,先調(diào)用new倦炒。

new至少要有一個(gè)參數(shù)cls显沈,代表要實(shí)例化的類(lèi),此參數(shù)在實(shí)例化時(shí)由 Python 解釋器自動(dòng)提供逢唤,后面的參數(shù)直接傳遞給init拉讯。
new對(duì)當(dāng)前類(lèi)進(jìn)行了實(shí)例化,并將實(shí)例返回鳖藕,傳給init的self魔慷。但是,執(zhí)行了new吊奢,并不一定會(huì)進(jìn)入init盖彭,只有new返回了,當(dāng)前類(lèi)cls的實(shí)例页滚,當(dāng)前類(lèi)的init才會(huì)進(jìn)入召边。

class A(object):
    def __init__(self, value):
        print("into A __init__")
        self.value = value

    def __new__(cls, *args, **kwargs):
        print("into A __new__")
        print(cls)
        return object.__new__(cls)


class B(A):
    def __init__(self, value):
        print("into B __init__")
        self.value = value

    def __new__(cls, *args, **kwargs):
        print("into B __new__")
        print(cls)
        return super().__new__(cls, *args, **kwargs)


b = B(10)

# 結(jié)果:
# into B __new__
# <class '__main__.B'>
# into A __new__
# <class '__main__.B'>
# into B __init__

class A(object):
    def __init__(self, value):
        print("into A __init__")
        self.value = value

    def __new__(cls, *args, **kwargs):
        print("into A __new__")
        print(cls)
        return object.__new__(cls)


class B(A):
    def __init__(self, value):
        print("into B __init__")
        self.value = value

    def __new__(cls, *args, **kwargs):
        print("into B __new__")
        print(cls)
        return super().__new__(A, *args, **kwargs)  # 改動(dòng)了cls變?yōu)锳


b = B(10)

# 結(jié)果:
# into B __new__
# <class '__main__.B'>
# into A __new__
# <class '__main__.A'>
  • new沒(méi)有正確返回當(dāng)前類(lèi)cls的實(shí)例,那init是不會(huì)被調(diào)用的裹驰,即使是父類(lèi)的實(shí)例也不行隧熙,將沒(méi)有init被調(diào)用。
  • 利用new實(shí)現(xiàn)單例模式幻林。
class Earth:
    pass


a = Earth()
print(id(a))  # 260728291456
b = Earth()
print(id(b))  # 260728291624

class Earth:
    __instance = None  # 定義一個(gè)類(lèi)屬性做判斷

    def __new__(cls):
        if cls.__instance is None:
            cls.__instance = object.__new__(cls)
            return cls.__instance
        else:
            return cls.__instance


a = Earth()
print(id(a))  # 512320401648
b = Earth()
print(id(b))  # 512320401648
  • del(self) 析構(gòu)器贞盯,當(dāng)一個(gè)對(duì)象將要被系統(tǒng)回收之時(shí)調(diào)用的方法。

Python 采用自動(dòng)引用計(jì)數(shù)(ARC)方式來(lái)回收對(duì)象所占用的空間沪饺,當(dāng)程序中有一個(gè)變量引用該 Python 對(duì)象時(shí)躏敢,Python 會(huì)自動(dòng)保證該對(duì)象引用計(jì)數(shù)為 1;當(dāng)程序中有兩個(gè)變量引用該 Python 對(duì)象時(shí)整葡,Python 會(huì)自動(dòng)保證該對(duì)象引用計(jì)數(shù)為 2件余,依此類(lèi)推,如果一個(gè)對(duì)象的引用計(jì)數(shù)變成了 0遭居,則說(shuō)明程序中不再有變量引用該對(duì)象啼器,表明程序不再需要該對(duì)象,因此 Python 就會(huì)回收該對(duì)象俱萍。

大部分時(shí)候端壳,Python 的 ARC 都能準(zhǔn)確、高效地回收系統(tǒng)中的每個(gè)對(duì)象枪蘑。但如果系統(tǒng)中出現(xiàn)循環(huán)引用的情況损谦,比如對(duì)象 a 持有一個(gè)實(shí)例變量引用對(duì)象 b岖免,而對(duì)象 b 又持有一個(gè)實(shí)例變量引用對(duì)象 a,此時(shí)兩個(gè)對(duì)象的引用計(jì)數(shù)都是 1成翩,而實(shí)際上程序已經(jīng)不再有變量引用它們觅捆,系統(tǒng)應(yīng)該回收它們,此時(shí) Python 的垃圾回收器就可能沒(méi)那么快麻敌,要等專(zhuān)門(mén)的循環(huán)垃圾回收器(Cyclic Garbage Collector)來(lái)檢測(cè)并回收這種引用循環(huán)栅炒。

算術(shù)運(yùn)算符
  • add(self, other)定義加法的行為:+
  • sub(self, other)定義減法的行為:-
  • mul(self, other)定義乘法的行為:*
  • truediv(self, other)定義真除法的行為:/
  • floordiv(self, other)定義整數(shù)除法的行為://
  • mod(self, other) 定義取模算法的行為:%
  • divmod(self, other)定義當(dāng)被 divmod() 調(diào)用時(shí)的行為
  • divmod(a, b)把除數(shù)和余數(shù)運(yùn)算結(jié)果結(jié)合起來(lái),返回一個(gè)包含商和余數(shù)的元組(a // b, a % b)术羔。
  • pow(self, other[, module])定義當(dāng)被 power() 調(diào)用或 ** 運(yùn)算時(shí)的行為
  • lshift(self, other)定義按位左移位的行為:<<
  • rshift(self, other)定義按位右移位的行為:>>
  • and(self, other)定義按位與操作的行為:&
  • xor(self, other)定義按位異或操作的行為:^
  • or(self, other)定義按位或操作的行為:|
反算術(shù)運(yùn)算符
  • radd(self, other)定義加法的行為:+
  • rsub(self, other)定義減法的行為:-
  • rmul(self, other)定義乘法的行為:*
  • rtruediv(self, other)定義真除法的行為:/
  • rfloordiv(self, other)定義整數(shù)除法的行為://
  • rmod(self, other) 定義取模算法的行為:%
  • rdivmod(self, other)定義當(dāng)被 divmod() 調(diào)用時(shí)的行為
  • rpow(self, other[, module])定義當(dāng)被 power() 調(diào)用或 ** 運(yùn)算時(shí)的行為
  • rlshift(self, other)定義按位左移位的行為:<<
  • rrshift(self, other)定義按位右移位的行為:>>
  • rand(self, other)定義按位與操作的行為:&
  • rxor(self, other)定義按位異或操作的行為:^
  • ror(self, other)定義按位或操作的行為:|
增量賦值運(yùn)算符
  • iadd(self, other)定義賦值加法的行為:+=
  • isub(self, other)定義賦值減法的行為:-=
  • imul(self, other)定義賦值乘法的行為:*=
  • itruediv(self, other)定義賦值真除法的行為:/=
  • ifloordiv(self, other)定義賦值整數(shù)除法的行為://=
  • imod(self, other)定義賦值取模算法的行為:%=
  • ipow(self, other[, modulo])定義賦值冪運(yùn)算的行為:**=
  • ilshift(self, other)定義賦值按位左移位的行為:<<=
  • irshift(self, other)定義賦值按位右移位的行為:>>=
  • iand(self, other)定義賦值按位與操作的行為:&=
  • ixor(self, other)定義賦值按位異或操作的行為:^=
  • ior(self, other)定義賦值按位或操作的行為:|=
一元運(yùn)算符
  • neg(self)定義正號(hào)的行為:+x
  • pos(self)定義負(fù)號(hào)的行為:-x
  • abs(self)定義當(dāng)被abs()調(diào)用時(shí)的行為
  • invert(self)定義按位求反的行為:~x
屬性訪問(wèn)
  • getattr(self, name): 定義當(dāng)用戶試圖獲取一個(gè)不存在的屬性時(shí)的行為赢赊。
  • getattribute(self, name):定義當(dāng)該類(lèi)的屬性被訪問(wèn)時(shí)的行為(先調(diào)用該方法,查看是否存在該屬性级历,若不存在释移,接著去調(diào)用getattr)。
  • setattr(self, name, value):定義當(dāng)一個(gè)屬性被設(shè)置時(shí)的行為寥殖。
  • delattr(self, name):定義當(dāng)一個(gè)屬性被刪除時(shí)的行為玩讳。
class C:
    def __getattribute__(self, item):
        print('__getattribute__')
        return super().__getattribute__(item)

    def __getattr__(self, item):
        print('__getattr__')

    def __setattr__(self, key, value):
        print('__setattr__')
        super().__setattr__(key, value)

    def __delattr__(self, item):
        print('__delattr__')
        super().__delattr__(item)


c = C()
c.x
# __getattribute__
# __getattr__

c.x = 1
# __setattr__

del c.x
# __delattr__
描述符

描述符就是將某種特殊類(lèi)型的類(lèi)的實(shí)例指派給另一個(gè)類(lèi)的屬性。

  • get(self, instance, owner)用于訪問(wèn)屬性嚼贡,它返回屬性的值熏纯。
  • set(self, instance, value)將在屬性分配操作中調(diào)用,不返回任何內(nèi)容粤策。
  • del(self, instance)控制刪除操作樟澜,不返回任何內(nèi)容。
class MyDecriptor:
    def __get__(self, instance, owner):
        print('__get__', self, instance, owner)

    def __set__(self, instance, value):
        print('__set__', self, instance, value)

    def __delete__(self, instance):
        print('__delete__', self, instance)


class Test:
    x = MyDecriptor()


t = Test()
t.x
# __get__ <__main__.MyDecriptor object at 0x000000CEAAEB6B00> <__main__.Test object at 0x000000CEABDC0898> <class '__main__.Test'>

t.x = 'x-man'
# __set__ <__main__.MyDecriptor object at 0x00000023687C6B00> <__main__.Test object at 0x00000023696B0940> x-man

del t.x
# __delete__ <__main__.MyDecriptor object at 0x000000EC9B160A90> <__main__.Test object at 0x000000EC9B160B38>
定制序列

協(xié)議(Protocols)與其它編程語(yǔ)言中的接口很相似叮盘,它規(guī)定你哪些方法必須要定義秩贰。然而,在 Python 中的協(xié)議就顯得不那么正式柔吼。事實(shí)上毒费,在 Python 中,協(xié)議更像是一種指南愈魏。

迭代器
  • 迭代是 Python 最強(qiáng)大的功能之一蝗罗,是訪問(wèn)集合元素的一種方式。
  • 迭代器是一個(gè)可以記住遍歷的位置的對(duì)象蝌戒。
  • 迭代器對(duì)象從集合的第一個(gè)元素開(kāi)始訪問(wèn),直到所有的元素被訪問(wèn)完結(jié)束沼琉。
  • 迭代器只能往前不會(huì)后退北苟。
  • 字符串,列表或元組對(duì)象都可用于創(chuàng)建迭代器
  • 迭代器有兩個(gè)基本的方法:iter() 和 next()打瘪。
  • iter(object) 函數(shù)用來(lái)生成迭代器友鼻。
  • next(iterator[, default]) 返回迭代器的下一個(gè)項(xiàng)目傻昙。
  • iterator -- 可迭代對(duì)象
  • default -- 可選,用于設(shè)置在沒(méi)有下一個(gè)元素時(shí)返回該默認(rèn)值彩扔,如果不設(shè)置妆档,又沒(méi)有下一個(gè)元素則會(huì)觸發(fā) StopIteration 異常。
links = {'B': '百度', 'A': '阿里', 'T': '騰訊'}

it = iter(links)
while True:
    try:
        each = next(it)
    except StopIteration:
        break
    print(each)

# B
# A
# T

it = iter(links)
print(next(it))  # B
print(next(it))  # A
print(next(it))  # T
print(next(it))  # StopIteration

把一個(gè)類(lèi)作為一個(gè)迭代器使用需要在類(lèi)中實(shí)現(xiàn)兩個(gè)魔法方法 iter() 與 next() 虫碉。

  • iter(self)定義當(dāng)?shù)萜髦械脑氐男袨榧值耄祷匾粋€(gè)特殊的迭代器對(duì)象, 這個(gè)迭代器對(duì)象實(shí)現(xiàn)了
  • next() 方法并通過(guò) StopIteration 異常標(biāo)識(shí)迭代的完成敦捧。
  • next() 返回下一個(gè)迭代器對(duì)象须板。
  • StopIteration 異常用于標(biāo)識(shí)迭代的完成,防止出現(xiàn)無(wú)限循環(huán)的情況兢卵,在 next() 方法中我們可以設(shè)置在完成指定循環(huán)次數(shù)后觸發(fā) StopIteration 異常來(lái)結(jié)束迭代习瑰。
class Fibs:
    def __init__(self, n=10):
        self.a = 0
        self.b = 1
        self.n = n

    def __iter__(self):
        return self

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > self.n:
            raise StopIteration
        return self.a


fibs = Fibs(100)
for each in fibs:
    print(each, end=' ')

# 1 1 2 3 5 8 13 21 34 55 89
生成器
  • 在 Python 中,使用了 yield 的函數(shù)被稱(chēng)為生成器(generator)秽荤。
  • 跟普通函數(shù)不同的是甜奄,生成器是一個(gè)返回迭代器的函數(shù),只能用于迭代操作窃款,更簡(jiǎn)單點(diǎn)理解生成器就是一個(gè)迭代器课兄。
  • 在調(diào)用生成器運(yùn)行的過(guò)程中,每次遇到 yield 時(shí)函數(shù)會(huì)暫停并保存當(dāng)前所有的運(yùn)行信息雁乡,返回 yield 的值, 并在下一次執(zhí)行 next() 方法時(shí)從當(dāng)前位置繼續(xù)運(yùn)行第喳。
  • 調(diào)用一個(gè)生成器函數(shù),返回的是一個(gè)迭代器對(duì)象踱稍。
def myGen():
    print('生成器執(zhí)行曲饱!')
    yield 1
    yield 2
    
myG = myGen()
for each in myG:
    print(each)

'''
生成器執(zhí)行信轿!
1
2
'''

myG = myGen()
print(next(myG))  
# 生成器執(zhí)行房匆!
# 1

print(next(myG))  # 2
print(next(myG))  # StopIteration

用生成器實(shí)現(xiàn)斐波那契數(shù)列蹋嵌。

def libs(n):
    a = 0
    b = 1
    while True:
        a, b = b, a + b
        if a > n:
            return
        yield a


for each in libs(100):
    print(each, end=' ')

# 1 1 2 3 5 8 13 21 34 55 89
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伏尼,一起剝皮案震驚了整個(gè)濱河市灾而,隨后出現(xiàn)的幾起案子讲竿,更是在濱河造成了極大的恐慌票罐,老刑警劉巖奈嘿,帶你破解...
    沈念sama閱讀 217,826評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件庆聘,死亡現(xiàn)場(chǎng)離奇詭異胜臊,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)伙判,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)象对,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人宴抚,你說(shuō)我怎么就攤上這事勒魔「ι罚” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,234評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵冠绢,是天一觀的道長(zhǎng)抚吠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)弟胀,這世上最難降的妖魔是什么楷力? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,562評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮邮利,結(jié)果婚禮上弥雹,老公的妹妹穿的比我還像新娘。我一直安慰自己延届,他們只是感情好剪勿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,611評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著方庭,像睡著了一般厕吉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上械念,一...
    開(kāi)封第一講書(shū)人閱讀 51,482評(píng)論 1 302
  • 那天头朱,我揣著相機(jī)與錄音,去河邊找鬼龄减。 笑死项钮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的希停。 我是一名探鬼主播烁巫,決...
    沈念sama閱讀 40,271評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼宠能!你這毒婦竟也來(lái)了亚隙?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,166評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤违崇,失蹤者是張志新(化名)和其女友劉穎阿弃,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體羞延,經(jīng)...
    沈念sama閱讀 45,608評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡渣淳,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,814評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了伴箩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片水由。...
    茶點(diǎn)故事閱讀 39,926評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出砂客,到底是詐尸還是另有隱情,我是刑警寧澤呵恢,帶...
    沈念sama閱讀 35,644評(píng)論 5 346
  • 正文 年R本政府宣布鞠值,位于F島的核電站,受9級(jí)特大地震影響渗钉,放射性物質(zhì)發(fā)生泄漏彤恶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,249評(píng)論 3 329
  • 文/蒙蒙 一鳄橘、第九天 我趴在偏房一處隱蔽的房頂上張望声离。 院中可真熱鬧,春花似錦瘫怜、人聲如沸术徊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,866評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)赠涮。三九已至,卻和暖如春暗挑,著一層夾襖步出監(jiān)牢的瞬間笋除,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,991評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工炸裆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留垃它,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,063評(píng)論 3 370
  • 正文 我出身青樓烹看,卻偏偏與公主長(zhǎng)得像国拇,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子听系,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,871評(píng)論 2 354

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

  • 16宿命:用概率思維提高你的勝算 以前的我是風(fēng)險(xiǎn)厭惡者贝奇,不喜歡去冒險(xiǎn),但是人生放棄了冒險(xiǎn)靠胜,也就放棄了無(wú)數(shù)的可能掉瞳。 ...
    yichen大刀閱讀 6,050評(píng)論 0 4
  • 公元:2019年11月28日19時(shí)42分農(nóng)歷:二零一九年 十一月 初三日 戌時(shí)干支:己亥乙亥己巳甲戌當(dāng)月節(jié)氣:立冬...
    石放閱讀 6,879評(píng)論 0 2
  • 今天上午陪老媽看病,下午健身房跑步浪漠,晚上想想今天還沒(méi)有斷舍離陕习,馬上做,衣架和旁邊的的布衣架址愿,一看亂亂该镣,又想想自己是...
    影子3623253閱讀 2,912評(píng)論 1 8