《Python基礎(chǔ)教程》第9章 魔方方法赵誓、屬性和迭代器

本章會(1)討論一些重要的魔法方法,(2)然后會討論兩個相關(guān)的主題:屬性和迭代器柿赊,(3)最后介紹一個相關(guān)的示例來處理一些稍微復(fù)雜的問題俩功。

魔法方法或者又稱為特殊方法(個人挺不習(xí)慣魔法方法的翻譯,叫法搞的跟拍科幻片似的碰声,因此后面統(tǒng)一叫做特殊方法)诡蜓,是指被包含下劃線的方法或者所能調(diào)用到的方法的統(tǒng)稱,這些通常會在特殊的情況下調(diào)用胰挑,并且基本沒有手動調(diào)用他們的必要蔓罚。

9.1 注備工作

Python的老版本和新版本在定義類的時候會有些差別椿肩,為了統(tǒng)一以新式類的方式來定義類,可以在文件首行添加一行代碼來來解決這個問題豺谈。個人在2.7的版本上進行學(xué)習(xí)暫時不存在這個問題郑象,跳過不深究。

9.2 構(gòu)造方法

構(gòu)造方法就是類似于init的初始化方法茬末,差別在于一個對象被構(gòu)建好以后會自動調(diào)用構(gòu)造方法厂榛。在Python中創(chuàng)建一個構(gòu)造方法如下(使用_init_):

class FooBar:
    def __init__(self):
        self.value = 42 
9.2.1 重寫一般方法和特殊的構(gòu)造方法

如果類B繼承自類A,類B的某個方法被調(diào)用的時候會首先去B中尋找該方法丽惭,如果找不到則會到父類中去尋找:

class A():
    def hello(self):
        print "Hello, I am A!"

class B(A):
    pass

a = A()
a.hello()
b = B()
b.hello()
$ python test.py
Hello, I am A!
Hello, I am A!

因為B類沒有hello方法击奶,所以當hello被調(diào)用時,原始信息就被打印出來≡鹛停現(xiàn)在類B重寫了該方法柜砾,再進行調(diào)用就能產(chǎn)生不一樣的效果:

class A():
    def hello(self):
        print "Hello, I am A!"

class B(A):
    def hello(self):
        print "Hello, I am !"

a = A()
a.hello()
b = B()
b.hello()


$ python test.py
Hello, I am A!
Hello, I am B!

重寫方法對于類很重要,尤其對構(gòu)造方法拷橘,但重寫父類的構(gòu)造方法需要調(diào)用超類的構(gòu)造方法局义,否則對象可能不能被正確的初始化∪叽看如下的例子:

class Bird():
    def __init__(self):
        self.hungry = True
    def eat(self):
        if self.hungry:
            print 'Aaaah...'
            self.hungry = False
        else:
            print 'No, thanks!'
b = Bird()
b.eat()
b.eat()
$ python test.py
Aaaah...
No, thanks!

鳥類在吃過東西以后萄唇,就不再饑餓。現(xiàn)在考慮添加SingBird术幔,它添加了唱歌的行為:

class SingBird():
    def __init__(self):
        self.sound = 'Squawk'
    def sing(self):
        print self.sound

sb  = SingBird()
sb.sing()
$ python test.py
Squawk

但是如果直接調(diào)用eat就會產(chǎn)生問題:

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    sb.eat()
AttributeError: SingBird instance has no attribute 'eat'

為了解決該問題另萤,必須調(diào)用超類的構(gòu)造方法保證正常的初始化,后面兩節(jié)分別介紹了兩種做法诅挑。

9.2.2 調(diào)用未綁定的超類構(gòu)造方法

如下為調(diào)用未綁定的超類構(gòu)造方法四敞,屬于歷史遺留寫法:

class SingBird(Bird):
    def __init__(self):
        Bird.__init__(self)
        self.sound = 'Squawk'
    def sing(self):
        print self.sound
9.2.3 使用super函數(shù)

使用super函數(shù)的寫法:

__metaclass__ = type#super類只能在新式類中使用
class SingBird(Bird):
    def __init__(self):
        super(SingBird, self).__init__()
        self.sound = 'Squawk'
    def sing(self):
        print self.sound

9.3 成員訪問

序列和映射是對象的集合,為了實現(xiàn)它們的基本行為拔妥,我們要實現(xiàn)一些魔法方法忿危。如果集合中的對象是不可變的那么實現(xiàn)兩個魔方方法即可,否則要實現(xiàn)四個魔法方法没龙。

  • __len__(self) 如果返回0铺厨,該對象被當做布爾變量使用時是假
  • __getitem__(self, key) 如果是序列,key是0~n-1的整數(shù)硬纤,如果是映射解滓,key可能會是任何類型。
  • __setitem__(self, key, value)
  • __delitem__(self, key)
9.3.1 基本的序列和映射規(guī)則

讓我們實踐一把筝家,創(chuàng)建一個無窮序列:

def checkKey(key):
    if not  isinstance(key, (int, long)):
        raise TypeError
    elif key < 0:
        raise IndexError


class InfinitSequence():

    def __init__(self, start=0, step=1):
        self.start = 0
        self.step = 1
        self.changed = {}

    def __getitem__(self, key):
        checkKey(key)
        try:
            return self.changed[key]
        except KeyError:
            return self.start + key * self.step

    def __setitem__(self, key, value):
        checkKey(key)
        self.changed[key] = value

sequence = InfinitSequence(1, 2)
print sequence[4] #4
sequence[4] = 2
print sequence[4] #2
print sequence[5] #5

因為序列是無窮的洼裤,所以沒有實現(xiàn)_len_方法,因此之前上面所說的實現(xiàn)兩個或者四個魔法方法是可選的溪王,甚至有些方法對于你實現(xiàn)數(shù)據(jù)結(jié)構(gòu)根本不需要腮鞍,因此不需要實現(xiàn)值骇。

9.3.2 子類化列表、字典和字符串

要模擬基本的序列/映射要實現(xiàn)其他的特殊方法和普通方法缕减,這是一項繁瑣的工作雷客,好在我們有繼承芒珠。如下實現(xiàn)一個和內(nèi)建列表行為相似的序列桥狡,可以使用子類內(nèi)建類型list:

__metaclass__=type

class CounterList(list):
    def __init__(self, *args):
        super(CounterList, self).__init__(*args)
        self.counter = 0
    def __getitem__(self, index):
        self.counter += 1
        return super(CounterList, self).__getitem__(index)

c1 = CounterList(range(10))
print c1 #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
c1.reverse()
print c1 #[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
del c1[3:6]
print c1 #[9, 8, 7, 3, 2, 1, 0]
print c1.counter #0
print c1[4] + c1[2] #9
print c1.counter #2

9.4 更多魔力

還有很多特殊方法不詳述,參考Python參考手冊皱卓。

9.5 屬性

訪問器方法是一個簡單的方法裹芝,能夠使用類似于getHeight何setHeight這樣的名字綁定一些屬性,看如下例子中的Recantagle類:

__metaclass__=type

class Recantagle(list):
    def __init__(self):
        self.height = 0
        self.width = 0

    def getSize(self):
        return self.width, self.height

    def setSize(self, size):
        self.width, self.height = size

r = Recantagle() #(0, 0)
print r.getSize()
r.setSize((200,400))
print r.getSize() #(200, 400)

我們知道方法的實現(xiàn)是在getSize里面娜汁,更好的做法是隱藏訪問方法嫂易。Python中有兩種機制,后面主要討論新式類中使用的property函數(shù)掐禁,以及類方法和靜態(tài)方法怜械,然后簡單介紹如何使用特殊方法實現(xiàn)屬性。

9.5.1 property屬性

property函數(shù)的使用很簡單傅事,只需要將訪問器函數(shù)用作參數(shù)將結(jié)果賦值給一個名為size的屬性缕允。可以用同樣的方式處理width和height:

__metaclass__=type

class Recantagle(list):
    def __init__(self):
        self.height = 0
        self.width = 0

    def getSize(self):
        return self.width, self.height

    def setSize(self, size):
        self.width, self.height = size

    size = property(getSize, setSize)
    
r = Recantagle()
print size

property的參數(shù)可以用0-4個(此處只提及蹭越,使用查詢文檔)障本,在新式類中應(yīng)該使用property函數(shù)而不是訪問器方法。

9.5.2 靜態(tài)方法和類成員方法

靜態(tài)方法是創(chuàng)建時被裝入Staticmethod類型的特征响鹃,靜態(tài)方法沒有self屬性驾霜,能夠被類本身直接調(diào)用。

類成員方法是創(chuàng)建時被裝入Classmethod類型的特征买置,類方法在定義時需要cls(類似于self的參數(shù))粪糙,類成員方法可以直接用類的對象調(diào)用。

請看下面的例子:

__metaclass__=type

class MyClass():

    def smeth():
        print 'This is static method'
    smeth = staticmethod(smeth)

    def cmeth(cls):
        print 'This is class method of ', cls
    cmeth = classmethod(cmeth)


MyClass.cmeth()  #This is class method of  <class '__main__.MyClass'>
c = MyClass()
c.cmeth() #This is class method of  <class '__main__.MyClass'>

MyClass.smeth() #This is static method

也可以用裝飾器來定義靜態(tài)方法和類成員方法:

__metaclass__=type

class MyClass():

    @staticmethod
    def smeth():
        print 'This is static method'

    @classmethod
    def cmeth(cls):
        print 'This is class method of ', cls


MyClass.cmeth()  #This is class method of  <class '__main__.MyClass'>
c = MyClass()
c.cmeth() #This is class method of  <class '__main__.MyClass'>

MyClass.smeth() #This is static method

靜態(tài)方法和類成員方法雖然目前還沒有大量運功過忿项,以后可以在工廠函數(shù)中用到蓉冈。

9.5.3 __getattr__、 __setattr__和它的朋友們

在不使用property屬性之前倦卖,如下四個方法提供了攔截對對象特性的功能:

  • __getattribute__(self, name) 當name被訪問時自動被調(diào)用洒擦,只能在新式類中使用
  • __getattr__(self, name) 當name被訪問時且對象沒有相應(yīng)的可直接訪問的特性時候調(diào)用
  • __setattr__(self, name, value) 當試圖給特性賦值時候會自動調(diào)用
  • __delattr__(self, name) 但試圖刪除特性name時自動調(diào)用

盡管相對property使用起來稍微復(fù)雜,但是還是很強大的:

__metaclass__=type

class Recantagle(list):
    def __init__(self):
        self.height = 0
        self.width = 0

    def __getattr__(self, name):
        if name == 'size':
            return self.width, self.height
        else:
            raise AttributeError

    def __setattr__(self, name, value):
        if name == 'size':
            self.width, self.height = value
        else:
            self.__dict__[name] = value

r = Recantagle() 
print r.size #(0, 0)
r.size = (100, 200)
print r.size #(100, 200)

9.6 迭代器

此處只討論一個特殊的迭代器方法__iter__怕膛,這個方法是迭代器規(guī)則的基礎(chǔ)熟嫩。

9.6.1 迭代器的規(guī)則

迭代意思是重復(fù)做一件事情能夠很多次,到目前為止我們使用了for循環(huán)對序列和字典進行迭代褐捻,本章介紹的是對實現(xiàn)了__iter__方法的對象進行迭代掸茅。

__iter__方法會返回一個迭代器椅邓,迭代器是一個有next方法的對象,調(diào)用迭代器的next方法時會返回它的下一個值昧狮,如果沒有值返回就會引發(fā)一個StopIteration異常景馁。

使用迭代器的好處是什么? 相比較使用列表一次性獲得所有的元素的值占用大量內(nèi)存而言,迭代顯得更加簡單優(yōu)雅逗鸣,如下的例子“斐波拉契數(shù)列”是一個使用列表的例子合住,否則列表長度必須無限:

如下是一個使用迭代去的例子:

__metaclass__=type
class Fibs():
    def __init__(self):
        self.a = 0
        self.b = 1

    def next(self):
        self.a, self.b = self.b, self.a + self.b
        return self.a

    def __iter__(self):
        return self

fibs = Fibs()

for f in fibs:
    if f > 1000:
        print f
        break

內(nèi)建函數(shù)可以從可迭代對象中直接獲得迭代器,比如:

>>> it = iter([1,2,3])
>>> it.next()
1
>>> it.next()
2
9.6.2 從迭代器得到序列

可以將迭代器和可迭代對象轉(zhuǎn)化序列撒璧,如下是使用list方法顯式將迭代器轉(zhuǎn)化為列表的例子:

class TestIterator():
    value = 0
    def next(self):
        self.value += 1
        if self.value > 10:
            raise StopIteration
        return self.value

    def __iter__(self):
        return self

ti = TestIterator()
print list(ti)  #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

9.7 生成器

生成器是一種普通的函數(shù)語法定義的迭代器透葛,可以幫助我們寫出很優(yōu)雅的代碼,當然編程時不使用生成器也是可以的卿樱。下面先簡單介紹如何創(chuàng)建和使用生成器僚害,然后再理解下它的機制。

9.7.1 創(chuàng)建生成器

我們要創(chuàng)建展開嵌套列表并按照順序打印的函數(shù)繁调,不適用生成器的時候代碼大概是這樣的:

nested = [[1,2], [3, 4], [5]]

def flatten(nested):
    for sublist in nested:
        for element in sublist:
            print element

flatten(nested)

現(xiàn)在要把它改寫成生成器的方式:

nested = [[1,2], [3, 4], [5]]

def flatten(nested):
    for sublist in nested:
        for element in sublist:
            yield element

for number in flatten(nested):
    print number

唯一的區(qū)別在于yield語句萨蚕,任何包含yield的語句被稱作生成器,它和普通函數(shù)的差別在于普通函數(shù)直接返回值蹄胰,而生成器每次生成一個值后函數(shù)會被凍結(jié)岳遥,等到再次被調(diào)用的時候又會被激活,被激活后函數(shù)會從之前被凍結(jié)的點開始執(zhí)行烤送。

9.7.2 遞歸生成器

上面的例子中嵌套有兩層寒随,因此使用兩個for循環(huán)。通過求助于遞歸帮坚,可以遍歷多層級的嵌套結(jié)構(gòu)(樹):

def flatten(nested):
    try:
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except:
            yield nested

print list(flatten([[[1], 2], 3, 4, [5, [6, 7]], 8])) # [1, 2, 3, 4, 5, 6, 7, 8]

flatten被調(diào)用時妻往,兩種情況:nested為一個元素,進而引發(fā)TypeError異常试和,生成器繼而生成一個元素讯泣;nested為一個列表,那么就會進入到第二個for循環(huán)阅悍,遍歷flatten(sublist)從而實現(xiàn)遞歸(這里面運用到了深度遍歷的思想)好渠。

有一種情況是需要特別進行處理的,如果遍歷的元素中包含了字符串节视,我們當然不希望對字符串進行遍歷拳锚。對一個元素是否是字符串的最好的檢測辦法是直接將元素和字符串拼接看是否發(fā)生錯誤。因此改寫了的代碼如下所示(頗有點巧妙):

def flatten(nested):
    try:
        try:
            nested + ''
        except TypeError:
            pass
        else:
            raise TypeError
        for sublist in nested:
            for element in flatten(sublist):
                yield element
    except:
            yield nested

print list(flatten([[[1], 2], 3, 4, [5, [6, 7]], 8])) # [1, 2, 3, 4, 5, 6, 7, 8]

假定nested是字符串寻行,那么在內(nèi)層try檢測中一定不會導(dǎo)致TypeError霍掺,因此在else中手動誘發(fā)TypeError好交給外層處理;如果不是字符串且不是普通的單個元素(不然進入不到第一個try子句里),那么會觸發(fā)內(nèi)層的TypeError杆烁,不需要進行處理而是直接跳過好讓后面的for中遞歸內(nèi)容執(zhí)行牙丽。

9.7.3 通用生成器

生成器是由兩部分組成的:生成器的函數(shù)和生成器的迭代器。用于def語句定義的包含yield部分的就是生成器的函數(shù)兔魂,生成器的迭代器則是這個函數(shù)的返回部分烤芦。兩個實體經(jīng)常被當做一個,合作生成器析校。如下一個簡單例子方便理解這兩個概念:

def simple_generator():
    yield 1

print simple_generator  #<function simple_generator at 0x1004edaa0>
print simple_generator() #<generator object simple_generator at 0x1004eb140>
9.7.4 生成器方法

從2.5開始Python中引入了屬性能夠為生成器提供值构罗,這樣生成器就能與外部進行交互:

  • 外部作用域訪問生成器的send方法,就像使用next一樣勺良,只不過前者需要一個參數(shù)
  • 當生成器運行時候绰播,返回通過send發(fā)送的值骄噪,如果next方法被使用則放回None

如下是一個簡單例子:

def repeater(value):
    while True:
        new = (yield value)
        if new is not None:
            value = new

r = repeater(42)
print r.next()
9.7.5 模擬生成器

生成器在比較舊的版本中是不可用的尚困,可以使用代碼來模擬生成器×慈铮考慮到目前還沒有使用到生成器的需求事甜,如何模擬也暫且先跳過,有需要再回來翻看滔韵。

9.8 八皇后問題

該節(jié)會使用生成器來解決經(jīng)典的編程問題逻谦。

9.8.1 生成器和回溯

略。

9.8.2 問題

簡述:8*8的棋盤中陪蜻,放置八個皇后使得他們相互之間不會相互威脅(即不在同一條橫線豎線斜線上)邦马。

9.8.3 狀態(tài)表示

八個皇后的狀態(tài)可以用一個長度為8的元組表示,比如state[0]=3表示第1行的皇后放在第4列宴卖。

9.8.4 尋找沖突

可以把沖突的判定定義為一個函數(shù):

def conflict(state, nextX):
    nextY = len(state) #2
    for i in range(nextY): #2
        if abs(nextX - state[i]) in (0, nextY - i):
            return True
    return False

nextY為下一個皇后的豎直位置(nextX和nextY的含義理解了就容易了)滋将,然后遍歷所有已經(jīng)放置好的皇后,如果新的位置和放置好的皇后位置在同一個豎直位置上或者斜線上症昏,那么就返回True随闽,否則返回False。

9.8.5 基本情況

這里先把問題簡化為n皇后肝谭,假定前面n-1個皇后的位置都已經(jīng)找到了掘宪,你只需要處理最后一步,你現(xiàn)在需要做的是根據(jù)前面n-1個皇后的位置找到第n個皇后所能放置的所有位置攘烛。如下用代碼進行表示:

def queens(nums, state):
    if len(state)  ==  nums - 1:
        for pos in range(nums):
            if not conflict(state, pos):
                yield pos

list(queens(4, [1, 3, 0])) # [2]

/Users/appledev072/Desktop/Screen Shot 2015-01-30 at 2.50.19 PM.png

9.8.6 需要遞歸的情況
def conflict(state, nextX):
    nextY = len(state) #2
    for i in range(nextY): #2
        if abs(nextX - state[i]) in (0, nextY - i):
            return True
    return False

def queens(nums = 8, state = ()):
        for pos in range(nums):
            if not conflict(state, pos):
                if len(state)  ==  nums - 1:
                    yield (pos, )
                else:
                    for result  in queens(nums, state + (pos,)):
                        yield (pos,) + result

print list(queens(3)) #[]
print list(queens(4)) #[(1, 3, 0, 2), (2, 0, 3, 1)]
print len(list(queens(8))) #92

內(nèi)層部分相當于我們之前所處理的情況魏滚,區(qū)別在于現(xiàn)在變成了元組,即該部分會獲得所有最后一個皇后的位置并返回給父級調(diào)用(內(nèi)層for循環(huán)中的queens)坟漱,并跟后面7皇后的位置結(jié)果進行合并鼠次。以此類推。

9.8.7 打包

可以將八皇后的結(jié)果輸出的稍微好理解一點,這樣也有有助于發(fā)現(xiàn)錯誤:

import random

def prettyprint(solution):
    def line(pos, length = len(solution)):
        return  '. ' * (pos) + 'X ' + '. ' * (length - pos - 1)
    for pos in solution:
        print line(pos)

prettyprint(random.choice(list(queens(8))))

9.9 小結(jié)

  • 舊式類和新式類
  • 魔法方法
  • 構(gòu)造方法
  • 重寫
  • 序列和映射
  • 迭代器
  • 生成器
  • 八皇后問題
9.9.1 本章的新函數(shù)
  • iter(obj)
  • property(fget, fset, fdel, doc)
  • super(class, obj)
9.9.2 接下來學(xué)習(xí)什么

測試须眷、擴展竖瘾、打包和一些項目的具體實現(xiàn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末花颗,一起剝皮案震驚了整個濱河市捕传,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌扩劝,老刑警劉巖庸论,帶你破解...
    沈念sama閱讀 206,126評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異棒呛,居然都是意外死亡聂示,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,254評論 2 382
  • 文/潘曉璐 我一進店門簇秒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鱼喉,“玉大人,你說我怎么就攤上這事趋观】盖荩” “怎么了?”我有些...
    開封第一講書人閱讀 152,445評論 0 341
  • 文/不壞的土叔 我叫張陵皱坛,是天一觀的道長编曼。 經(jīng)常有香客問我,道長剩辟,這世上最難降的妖魔是什么掐场? 我笑而不...
    開封第一講書人閱讀 55,185評論 1 278
  • 正文 為了忘掉前任,我火速辦了婚禮贩猎,結(jié)果婚禮上熊户,老公的妹妹穿的比我還像新娘。我一直安慰自己融欧,他們只是感情好敏弃,可當我...
    茶點故事閱讀 64,178評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著噪馏,像睡著了一般麦到。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上欠肾,一...
    開封第一講書人閱讀 48,970評論 1 284
  • 那天瓶颠,我揣著相機與錄音,去河邊找鬼刺桃。 笑死粹淋,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播桃移,決...
    沈念sama閱讀 38,276評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼屋匕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了借杰?” 一聲冷哼從身側(cè)響起过吻,我...
    開封第一講書人閱讀 36,927評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蔗衡,沒想到半個月后纤虽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,400評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡绞惦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,883評論 2 323
  • 正文 我和宋清朗相戀三年逼纸,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片济蝉。...
    茶點故事閱讀 37,997評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡杰刽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出堆生,到底是詐尸還是另有隱情专缠,我是刑警寧澤,帶...
    沈念sama閱讀 33,646評論 4 322
  • 正文 年R本政府宣布淑仆,位于F島的核電站,受9級特大地震影響哥力,放射性物質(zhì)發(fā)生泄漏蔗怠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,213評論 3 307
  • 文/蒙蒙 一吩跋、第九天 我趴在偏房一處隱蔽的房頂上張望寞射。 院中可真熱鬧,春花似錦锌钮、人聲如沸桥温。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,204評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽侵浸。三九已至,卻和暖如春氛谜,著一層夾襖步出監(jiān)牢的瞬間掏觉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,423評論 1 260
  • 我被黑心中介騙來泰國打工值漫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留澳腹,地道東北人。 一個月前我還...
    沈念sama閱讀 45,423評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像酱塔,于是被迫代替她去往敵國和親沥邻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,722評論 2 345

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

  • 我們在學(xué)習(xí)web前端的路程起步時總是疑問,我們?nèi)绾胃玫谋闅v元素呢迁沫?迭代器和生成器是什么芦瘾?今天為大家?guī)吓c精彩的E...
    儂姝沁兒閱讀 3,298評論 0 6
  • 本文翻譯自Functional Programming Howto 本文將介紹Python中函數(shù)式編程的特性。在對...
    大蟒傳奇閱讀 2,601評論 4 14
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理集畅,服務(wù)發(fā)現(xiàn)近弟,斷路器,智...
    卡卡羅2017閱讀 134,599評論 18 139
  • 你不知道JS:異步 第四章:生成器(Generators) 在第二章挺智,我們明確了采用回調(diào)表示異步流的兩個關(guān)鍵缺點:...
    purple_force閱讀 948評論 0 2
  • 感情從來是相互的祷愉,我失去的同樣你也失去,我有什么好值得難過的赦颇。 我們都在改變二鳄,你早就不是過去的你,我也不是曾經(jīng)的我...
    yf2880閱讀 242評論 0 1