Classes of Python | Python中的類詳解

Classes of Python(Version 2.7.13)

全文主要內(nèi)容翻譯自 Python 2.7.13官方文檔,示例代碼及講解皆為本人撰寫裁奇,轉(zhuǎn)載請先聯(lián)系

A First Look at Classes

Classes introduce a little bit of new syntax, three new object types, and some new semantics

類引入了一些新的語法桐猬,三個新的對象類型,和一些新的語義刽肠。(下文一一講解)

Class Definition Syntax

class ClassName:
    <statement-1>
    .
    .
    .
    <statement-N>

類的定義溃肪,就像函數(shù)定義(def)一樣,必須在他們作用之前被執(zhí)行音五”棺可能會將函數(shù)
定義放入 if 分支中,這時候就要記住上一句話了躺涝。

if 1:
    def f():
        print "calling f()"
    f() # calling f()
'''
 # 這時候因為上面的 if 分支是肯定被執(zhí)行的
 # f() 函數(shù)是被加到上下文的 namespaces中
'''
f() # calling f()

'''
 # 可是如果 if 分支不一定執(zhí)行的時候呢厨钻?  比如肯定不執(zhí)行的 if 0:
 # 這時候就會發(fā)生 `undefined name f` 錯誤了!
 # 將定義放入分支的時候坚嗜,切記先讓函數(shù)定義被執(zhí)行之后夯膀,再引用
'''

Class Objects

Class 對象支持兩種操作:屬性引用、實例化惶傻。

屬性引用( Attribute references ) 用 obj.name 形式的語法棍郎,
class 被創(chuàng)建后,他命名空間內(nèi)的所有 name 都是有效的屬性 name
(即可以被 obj.name 引用到)银室。[靜態(tài)變量可以不創(chuàng)建 class 也能引用]

類實例化使用函數(shù)符號(foo())涂佃,假使 class 對象是一個無參函數(shù),返回值是
class 的新的實例蜈敢。

x = MyClass()

實例化操作創(chuàng)建了一個空對象辜荠,大多數(shù)時候我們希望自定義地創(chuàng)建一個實例,這個實例有
他特殊的初始狀態(tài)抓狭。例如伯病,新建一個 people 對象,我們希望他是個10歲的孩子,即
people.age 是10午笛,這是在創(chuàng)建好對象的時候就已經(jīng)初始化的狀態(tài)惭蟋。因此我們定義了
一個特殊的方法 __init__

def __init__(self):
   self.age = 10

當(dāng)一個 class(類) 定義了 __init__() 方法药磺,類的實例化操作會自動調(diào)用該方法
去實例化新的類實例告组。當(dāng)然,為了更好的靈活性癌佩,__init__() 方法可以有參數(shù)木缝。這樣我們可以在創(chuàng)建 people 的時候就顯式的初始化他的年紀。

class People:
  def __init__(self,age=1):
      self.age = age

baby = People() # default age is 1
young = People(20) # age 20
old = People(60) # age 60

靜態(tài)變量和實例變量

class Clazz:
    static_var = 0
    def __init__(self):
        self.i = 1

    def f():
        print "f()"
# 靜態(tài)變量可以不用創(chuàng)建對象也能引用围辙,所有實例共享同一個變量
print Clazz.static_var # 0
# 實例化 class
c = Clazz()
# Attribute references 屬性引用
print c.i # 1
print c.f
print c.f() # f()

Instance Objects

實例對象(instance objects) 只接受 屬性引用(attribute references) 操作我碟。
這有兩種有效的屬性名( attribute names ),數(shù)據(jù)屬性和方法(data attributes and methods)姚建。

數(shù)據(jù)屬性對應(yīng)著 Smalltalk 中的“實例變量”矫俺,以及 C++ 中的“數(shù)據(jù)成員”。數(shù)據(jù)屬性不需要被直接聲明掸冤;就像 local variables(局域變量)恳守,在她們第一次被賦值的時候就開始存在了。

class Clazz:
    def foo():
        print "foo()"
c = Clazz()
'''
 # 可以發(fā)現(xiàn)贩虾,在實例對象中引用一個不存在的變量并賦值催烘,該變量就存在在實力對象中了
 # 而不需要在定義的時候顯式的聲明該變量
 # 這里我們也可以給變量賦值一個函數(shù)對象(function object)
'''
c.i = 1 # i = 1
'''
 # 刪除實例中的數(shù)據(jù)屬性
'''
del c.i

另一種實例屬性引用是 方法(method)。方法是一個屬于對象的函數(shù)( A method is a function that “belongs to” an object.)缎罢。(在 Python 中伊群,(術(shù)語)方法并不是只有類實例才有:其他對象類型也可以有方法。比如說策精,list 對象有很多方法叫做 append,insert,remove 之類的舰始。不過,在下面的討論中咽袜,我們只用(術(shù)語)方法表示類實例對象的方法丸卷,除非另有明確聲明)

一個實例對象中有效的函數(shù)名取決于他的類。在定義中询刹,一個類中定義的所有函數(shù)對象屬性對應(yīng)著類實例的方法谜嫉。(類中的 functions 對應(yīng)著 實例中的 methods)。這段有點繞凹联,看不懂的看原文

Method Objects

這里只講兩點吧:

  • 第一點:
class Clazz:
    def f(self):
        print 'Hello World'
c = Clazz()
c.f() # Hello World
# right way
# reusable
cf = c.f
cf() # Hello World
  • 第二點:

我們看到了在定義方法 f(self) 的時候傳入了一個參數(shù) self沐兰,而在調(diào)用的時候 c.f() 并沒有傳入任何參數(shù)。這里我們實際上調(diào)用方法的時候是追尋到類定義的方法蔽挠。在我們的例子中住闯,c.f()Clazz.f(x) 是完全等價的。

# 接上一點的 Clazz
Clazz.f(c) # Hello World

Class and Instance Variables

通常來說,實例變量(instance variables)是為了保持每個實例的數(shù)據(jù)唯一性比原,而類變量(class variables)是為了在所有類的實例之間共享屬性(attributes)和方法(method)插佛。

class Dog:
    kind = 'canine'         # class variable shared by all instances
    def __init__(self, name):
        self.name = name    # instance variable unique to each instance
>>> d = Dog('Fido')
>>> e = Dog('Buddy')
>>> d.kind                  # shared by all dogs
'canine'
>>> e.kind                  # shared by all dogs
'canine'
>>> d.name                  # unique to d
'Fido'
>>> e.name                  # unique to e
'Buddy'

'''
既然 class variables 作為共享的數(shù)據(jù)源,
任何一個實例更改了變量值量窘,全部實例都會"看到"
'''
d.king = 'Dtime'
print e.kind # Dtime

Random Remarks

如果名稱一樣的話朗涩,數(shù)據(jù)屬性會覆蓋( override ) 方法屬性;為了避免偶然發(fā)生的绑改、在大型程序中難以發(fā)現(xiàn)的命名沖突,用一些公約(慣例)來最小化沖突發(fā)生的可能是非常明智的兄一。

Data attributes may be referenced by methods as well as by ordinary users (“clients”) of an object. In other words, classes are not usable to implement pure abstract data types. In fact, nothing in Python makes it possible to enforce data hiding — it is all based upon convention. (On the other hand, the Python implementation, written in C, can completely hide implementation details and control access to an object if necessary; this can be used by extensions to Python written in C.)

沒有嚴格地定義函數(shù)定義必須要在類定義中function厘线,也可以將函數(shù)賦值給類中的一個局部變量。(不建議這么使用)

# Function defined outside the class
def f1(self, x, y):
    return min(x, x+y)

class C:
    f = f1

    def g(self):
        return 'hello world'

    h = g

方法可以通過 self 的方法屬性調(diào)用其他方法:

class Bag:
    def __init__(self):
        self.data = []

    def add(self, x):
        self.data.append(x)

    def addtwice(self, x):
        self.add(x)
        self.add(x)

Methods may reference global names in the same way as ordinary functions. The global scope associated with a method is the module containing its definition. (A class is never used as a global scope.) While one rarely encounters a good reason for using global data in a method, there are many legitimate uses of the global scope: for one thing, functions and modules imported into the global scope can be used by methods, as well as functions and classes defined in it. Usually, the class containing the method is itself defined in this global scope, and in the next section we’ll find some good reasons why a method would want to reference its own class.[這部分我也蒙圈... 不大清楚說啥出革,以后再來填吧]

每個值都是一個對象造壮,因此有一個類(也成為他的類型)。他存儲為 object.__class__骂束。

Inheritance

派生類的定義語法如下:

class DerivedClassName(BaseClassName):
    <statement ...>

父類 BaseClassName 必須定義在包含派生類 DerivedClassName 的作用域中耳璧。也可以使用其他任意表達式代替基類名稱。比如展箱,當(dāng)基類定義在其他模塊中時:

class DerivedClassName(modulename.BaseClassName):

父類和派生類名詞解釋
基類: 下面的程序中旨枯,Base 就是基類,也稱父類混驰。
派生類: Derive 繼承了 Base 類攀隔,他就是 Base 類的派生類,也稱 Base 類的子類栖榨。

class Base:
    pass # 定義一個空類

class Derive(Base):
    pass 

派生類定義的執(zhí)行與基類的執(zhí)行相同。當(dāng)類對象被構(gòu)造(創(chuàng)建)時,基類被記住(remembered)启绰。這用于解析屬性引用:如果在類中找不到請求的屬性爱谁,則搜索繼續(xù)查找基類。如果基類本身是從某個其他類派生的愚争,則此規(guī)則將遞歸應(yīng)用映皆。

對派生類的實例化沒有什么特別的:DerivedClassName()創(chuàng)建一個新的類實例。方法引用解析如下:如果需要轰枝,搜索相應(yīng)的類屬性劫扒,如果有必要,則降序排列基類鏈狸膏,如果這產(chǎn)生一個函數(shù)對象沟饥,方法引用是有效的。

'''
可以發(fā)現(xiàn) Derive 類打印了 num 屬性,但是 Derive 類并沒有定義 num 屬性贤旷,
所以這時候在解析屬性的時候广料,會去父類 Base 類中尋找,這就是根據(jù)降序排列基類鏈去搜索屬性幼驶。
'''
class Base:
     num = 10

class Derive(Base):
    def p(self):
         print self.num

派生類可以覆蓋其基類的方法艾杏。因為方法在調(diào)用同一對象的其他方法時沒有特殊的權(quán)限,
所以一個基類中的方法再調(diào)用定義在同個基類中其他方法的時候盅藻,最終可能會調(diào)用派生類的同名方法來覆蓋它购桑。(對于C ++程序員:Python中的所有方法都是虛擬的。)

派生類中的重寫方法實際上可能希望擴展而不是簡單地替換同名的基類方法氏淑。有一種簡單的方法來直接調(diào)用基類方法:只需調(diào)用 BaseClassName.methodname(self勃蜘,arguments)。這有時對客戶有用假残。 (請注意缭贡,這只有在基類可以作為 BaseClassName 在全局范圍內(nèi)訪問時才有效。)

Python有兩個內(nèi)置的函數(shù)作用在繼承上:

  • 使用 isinstance() 來檢查實例的類型:isinstance(obj,int) 將只有當(dāng) obj .__ class__int 或從 int 派生的類時才為 True辉懒。
  • 使用 issubclass() 檢查類繼承:issubclass(bool阳惹,int)True,因為 boolint 的子類眶俩。但是莹汤,issubclass(unicode,str)False颠印,因為 unicode不是 str 的子類(它們只共享一個共同的祖先体啰,basestring)。

Multiple Inheritance

Python也支持有限形式的多重繼承嗽仪。具有多個基類的類定義如下所示:

class DerivedClassName(Base1, Base2, Base3):
    <statement ...>

對于舊式(old-style)類荒勇,唯一的規(guī)則是深度優(yōu)先,從左到右闻坚。因此沽翔,如果在 DerivedClassName 中找不到屬性,則在 Base1 中搜索窿凤,然后(遞歸地)在 Base1 的基類中搜索仅偎,并且僅當(dāng)在那里找不到時,才會在 Base2 中搜索雳殊,以此類推橘沥。

對于新式(new-style)類, 方法解析順序(MRO)會動態(tài)更改,以支持對 super()的協(xié)作調(diào)用夯秃。這種方法在一些其他多繼承語言中稱為 call-next-method座咆,比單繼承語言中的 super 調(diào)用更強大痢艺。[多重繼承下的方法解析不了解,谷歌了一下 Python 的多重繼承介陶,新式類的方法解析順序]

'''
以 object 作為基類堤舒,這就是新式(new-style)類。
因為 Base 類是以 object 為基類哺呜,所以 Derive 類也是新式類了舌缤。
'''
class Base(object):
    pass

class Derive(Base):
    pass
'''
# Python3 之后就默認的是新式類了,不需要專門的去繼承 object 了某残。
# 這篇例子是講新式類的繼承順序
# Python 3.5
'''
class A:
    def __new__(cls, *argv, **kwargs):
        print('nA')
        return super().__new__(cls)

    def __init__(self, a):
        print('A')
        self.a = a

    def comeon(self):
        print('A.comeon')


class B(A):
    def __new__(cls, *argv, **kwargs):
        print('nB')
        return super().__new__(cls)

    def __init__(self, b):
        super().__init__(b)
        print('B')
        self.b = b

    def comeon(self):
        print('B.comeon')


class C(A):
    def __new__(cls, *argv, **kwargs):
        print('nC')
        return super().__new__(cls)

    def __init__(self, c):
        super().__init__(c)
        print('C')
        self.c = c

    def comeon(self):
        print('C.comeon')


class D(B, C):
    def __new__(cls, *argv, **kwargs):
        print('nD')
        return super().__new__(cls)

    def __init__(self, d):
        super().__init__(d)
        print('D')
        self.d = d


d = D('d')
d.comeon()

'''
# output
nD
nB
nC
nA
A
C
B
D
B.comeon
'''

最后執(zhí)行 d.comeon() 實際上調(diào)用的方法是從左自右得來的左邊的那個 B 的 comeon() 方法 国撵。那么如何實現(xiàn)這樣的效果呢?很簡單玻墅,讓 B 的 __init__() 最后一個執(zhí)行介牙,就能覆蓋掉 C 和 D 寫入的 comeon() 方法。

所以實際調(diào)用new的順序就是 D--B--C--A椭豫,之后遞歸棧回過頭來初始化旨指,調(diào)用 __init__() 的順序就是 A--C--B--D赏酥,只有這樣才能保證 B 里的 comeon() 方法能夠覆蓋掉 A 和 C 創(chuàng)建的 comeon() 方法,同樣保證如果你的 D 里有 comeon()谆构,它是最后一個被初始化的裸扶,將最后寫入而覆蓋掉其它的。
栗子來源于偶然看見的 Coldwings 的知乎回答搬素。不過很明顯這里是講的新式類的呵晨,舊式類與此不同(參上)。

Private Variables and Class-local References

除了在對象內(nèi)部不能訪問的“私有”實例變量在Python中不存在熬尺。然而摸屠,大多數(shù) Python code 遵守著這樣一個約定:如果前綴為一個下劃線(比如 "_attr")的命名,應(yīng)該被當(dāng)作是 API 的非公有部分(不論它是一個函數(shù)粱哼,方法亦或是數(shù)據(jù)成員)季二。 它應(yīng)被視為細節(jié)的實現(xiàn),如有更改揭措,恕不另行通知胯舷。

(It should be considered an implementation detail and subject to change without notice.
)

class Base:
    class_var = 1 # 可以被子類 "看到"
    __private_var = 0 # 不可以被子類 '看到',這就是Python實現(xiàn)私有(private) 變量的方式

class Derive(Base):
    def p(self):
        print self.class_var
        print self.__private_var
# instantiation
Derive().p() 

# output:
1
Traceback (most recent call last):
  File "D:/workspace_py/python-doc/classdefinition/demonstrate.py", line 10, in <module>
    Derive().p()
  File "D:/workspace_py/python-doc/classdefinition/demonstrate.py", line 8, in p
    print self.__private_var
AttributeError: Derive instance has no attribute '_Derive__private_var'

因為類私有(class-private)成員有一個有效的用例(即避免名稱與子類定義的名稱沖突)绊含,所以對這種機制的有限的支持桑嘶,稱為名稱調(diào)整(name mangling)。任何標識符 __spam(至少兩個前導(dǎo)下劃線躬充,最多一個尾部下劃線)在文本上替換為 _classname__spam逃顶,其中 classname 是帶有前導(dǎo)下劃線的當(dāng)前類名讨便。這種調(diào)整是在不考慮標識符的句法位置的情況下完成的,只要它出現(xiàn)在類的定義內(nèi)即可口蝠。

名稱調(diào)整(name mangling)有助于讓子類重寫方法器钟,而不會打斷類內(nèi)方法調(diào)用。例如:

class Mapping:
    def __init__(self, iterable):
        self.items_list = []
        self.__update(iterable)

    def update(self, iterable):
        for item in iterable:
            self.items_list.append(item)

    __update = update   # private copy of original update() method

class MappingSubclass(Mapping):

    def update(self, keys, values):
        # provides new signature for update()
        # but does not break __init__()
        for item in zip(keys, values):
            self.items_list.append(item)

注意妙蔗,傳遞給 exec傲霸,eval()execfile()的代碼不會將調(diào)用類的類名視為當(dāng)前類;這類似于全局語句global statement的效果,其效果同樣限于字節(jié)編譯在一起的代碼眉反。同樣的限制適用于 getattr()昙啄,setattr()delattr(),以及直接引用 __dict__ 時寸五。 [持續(xù)懵逼... 沒用過 exec之類的梳凛,不知道咋回事,以后用過再來補]

Odds and Ends

有時梳杏,使用類似于 Pascal的"record"或C的"struct"的數(shù)據(jù)類型韧拒,捆綁幾個命名的數(shù)據(jù)項,這樣的結(jié)構(gòu)是有用的十性。一個空類定義可以很好的做到這點:

class People:
    pass

me = People() # create an empty class People
me.name = "Chan"
me.age = 16
me.weight = 1000

一段需要特定抽象數(shù)據(jù)類型的 Python 代碼叛溢,通常可以通過一個類來模擬該數(shù)據(jù)類型的方法劲适。例如楷掉,如果你有一個函數(shù)來格式化一個文件對象的一些數(shù)據(jù),你可以定義一個類方法 read()readline() 從字符串緩沖區(qū)獲取數(shù)據(jù)霞势,并傳遞它作為參數(shù)烹植。

實例方法對象也有屬性:m.im_self 是擁有方法m()的實例對象,m.im_func 是對應(yīng)于方法的函數(shù)對象愕贡。

class Clazz:
    def f(self):
        pass

c = Clazz() 
print c.f.im_self # <__main__.Clazz instance at 0x0000000002915BC8>
print c.f.im_func # <function f at 0x0000000002A9E9E8>

Exceptions Are Classes Too

我們還可以使用類來標識 (創(chuàng)建) 用戶定義的異常( exception )草雕。用這種機制的話,在擴展異常的層次結(jié)構(gòu)上將更加便捷固以。 raise 語句添加了兩種有效的語義形式:

raise Class, instance

raise instance

第一種形式促绵,instance 必須是 Class的或者是 Class 的派生類的實例。
第二種形式是一個簡寫形式嘴纺,實際上是這樣的:

raise instance.__class__, instance

except 子句( clause )中败晴,捕捉的異常類會兼容其派生類,也就是說一個捕捉類似 IOException 的基類栽渴,所有的繼承自 IOException的派生類都會被捕捉到尖坤。
舉個栗子:

class B:
    pass
class C(B):
    pass
class D(C):
    pass

for c in [B, C, D]:
    try:
        raise c()
    except D:
        print "D"
    except C:
        print "C"
    except B:
        print "B"
'''
# output
> B
> C
> D
'''

如果將上面代碼中的 except 子句的順序改變?yōu)?BCD 的順序,會發(fā)現(xiàn)輸出是 "BBB" 闲擦,因為 except B 把其所有的派生類都給捕捉了慢味。

如果出現(xiàn)了沒有處理的異常场梆,會打印錯誤信息,格式是這樣子的:

異常類名纯路,后跟一個冒號再一個空格或油,最后跟上用內(nèi)建方法 `str()` 將實例轉(zhuǎn)換成字符串輸出
__main__.B: <__main__.B instance at 0x00000000024EB0C8>

Iterators

你可能已經(jīng)發(fā)現(xiàn)大多數(shù)容器對象可以使用 for 語句來循環(huán)了。

for element in [1, 2, 3]:
    print element
for element in (1, 2, 3):
    print element
for key in {'one':1, 'two':2}:
    print key
for char in "123":
    print char
for line in open("myfile.txt"):
    print line,

這種操作方式非常的清晰明確且便捷驰唬,統(tǒng)一使用迭代器的操作方式已經(jīng)滲入 Python顶岸。在這便捷之下,for 語句調(diào)用了 iter() 方法作用在容器對象上叫编。該函數(shù)返回了一個迭代器對象辖佣,在迭代器對象內(nèi)定義了 next() 方法,next() 方法一次一個地訪問容器中的元素搓逾。當(dāng)沒有了可訪問元素時卷谈, next() 方法拋出了一個 StopIteration 異常,這個異常會終止 for 循環(huán)霞篡。這有一個栗子世蔗,展示這是怎么工作的:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> it.next()
'a'
>>> it.next()
'b'
>>> it.next()
'c'
>>> it.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
    it.next()
StopIteration

在看完了迭代器協(xié)議背后的機制后,可以開始將迭代器行為到你的類中了朗兵。定義一個 __iter__() 方法污淋,該方法返回一個有 next() 方法的對象。如果類中定義了 next() 方法的話矛市,可以在 __iter__() 方法中直接返回 self诲祸。

class Dict:
    """fool dict"""
    def __init__(self, key, data):
        self.key = key
        self.data = data
        self.index = -1

    def __iter__(self):
        return self

    def next(self):
        self.index += 1
        if self.index > len(self.key)-1:
            raise StopIteration
        return self.key[self.index],self.data[self.index]

    def add(self,add_key,add_data):
        self.key.append(add_key)
        self.data.append(add_data)

key = [0,1,2,3]
data = ['a','b','c','d']
d = Dict(key,data)
d.add(7,'g')
for key,data in d:
    print key,data

'''
# output
0 a
1 b
2 c
3 d
7 g
'''

Generators

生成器是一個用于生成迭代器的簡單且強大的工具。它寫起來就和常規(guī)的函數(shù)一樣找田,但每當(dāng)需要返回數(shù)據(jù)的時候,會使用 yield 語句着憨。每次next() 方法被調(diào)用墩衙,生成器會回到上次它處理過的地方(它會記住所有的數(shù)據(jù)值以及上次執(zhí)行的語句)甲抖。創(chuàng)建一個生成器非常簡單,看下面的栗子:

def access(data):
    for index in range(len(data)):
        yield data[index]

for char in access('access'):
    print char;
'''
# output
a
c
c
e
s
s
'''

所有能被生成器做到的事情准谚,都可以用基于類的迭代器來完成(就在上一節(jié)提到的迭代器)挫剑。生成器會自動生成 __iter()__next() 方法,這使得生成器看起來異常的緊湊(和基于類的迭代器相比)樊破。

另一個重要的特性是,局部變量以及執(zhí)行狀態(tài)在每次調(diào)用之間都被自動的保存了哲戚。與使用實例變量 (如 self.keyself.data) 相比顺少,使得函數(shù)變得更易編寫,且更加清楚祈纯。

除了自動創(chuàng)建方法和保存程序狀態(tài),當(dāng)生成器終止時粒没,它們自動拋出 StopIteration簇爆。結(jié)合起來,這些特性使得創(chuàng)建迭代器和編寫常規(guī)函數(shù)一樣容易响蓉。

Generator Expressions

一些簡單的生成器可以簡潔地編碼為表達式哨毁,使用類似于列表推導(dǎo)的語法,但使用括號而不是方括號想幻。這些表達式設(shè)計用于生成器立即被封閉它的函數(shù)使用的情況话浇。

與完整的生成器定義相比,生成器表達式更緊湊幔崖,但特性也少了赏寇。生成器表達式比等效的列表推導(dǎo)更內(nèi)存友好。

上栗子:

>>> sum(i*i for i in range(10))                 # sum of squares
285

>>> xvec = [10, 20, 30]
>>> yvec = [7, 5, 3]
>>> sum(x*y for x,y in zip(xvec, yvec))         # dot product
260

>>> from math import pi, sin
>>> sine_table = dict((x, sin(x*pi/180)) for x in range(0, 91))

>>> unique_words = set(word  for line in page  for word in line.split())

>>> valedictorian = max((student.gpa, student.name) for student in graduates)

>>> data = 'golf'
>>> list(data[i] for i in range(len(data)-1,-1,-1))
['f', 'l', 'o', 'g']

===========日志分割線===========

update log:

  • 更新于 2017年1月19日01:03:16 | 添加 Coldwings 的關(guān)于新式類繼承的栗子
  • 初次完成于 2017年1月18日19:04:44 | 全篇翻譯完畢
  • 更新于 2017年1月18日16:55:08 | 添加 Exceptions Are Classes Too 至文末
  • 更新于 2017年1月5日 21:34:00 | 添加 Inheritance 至文末
  • 更新于 2017年1月4日 23:00:36 | 添加 Class and Instance Variables
  • 創(chuàng)建于 2017年1月4日 16:26:36
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末自娩,一起剝皮案震驚了整個濱河市椒功,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌动漾,老刑警劉巖旱眯,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異共虑,居然都是意外死亡呀页,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門尘分,熙熙樓的掌柜王于貴愁眉苦臉地迎上來培愁,“玉大人缓窜,你說我怎么就攤上這事∷焦桑” “怎么了时肿?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵港粱,是天一觀的道長查坪。 經(jīng)常有香客問我,道長偿曙,這世上最難降的妖魔是什么望忆? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任竿秆,我火速辦了婚禮幽钢,結(jié)果婚禮上傅是,老公的妹妹穿的比我還像新娘。我一直安慰自己帽驯,他們只是感情好书闸,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著享甸,像睡著了一般梳侨。 火紅的嫁衣襯著肌膚如雪走哺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天择示,我揣著相機與錄音晒旅,去河邊找鬼。 笑死谈秫,一個胖子當(dāng)著我的面吹牛鱼鼓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播硕淑,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼于樟!你這毒婦竟也來了拇囊?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纠永,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涉波,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡啤覆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年惭聂,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片笨觅。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡见剩,死狀恐怖扫俺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情羹呵,我是刑警寧澤畸颅,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布没炒,位于F島的核電站,受9級特大地震影響送火,放射性物質(zhì)發(fā)生泄漏种吸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一镜盯、第九天 我趴在偏房一處隱蔽的房頂上張望猖败。 院中可真熱鬧,春花似錦艺糜、人聲如沸幢尚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽理茎。三九已至,卻和暖如春园爷,著一層夾襖步出監(jiān)牢的瞬間式撼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工扰楼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留美浦,地道東北人浦辨。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像币厕,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子页衙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理店乐,服務(wù)發(fā)現(xiàn)呻袭,斷路器,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法踪古,類相關(guān)的語法券腔,內(nèi)部類的語法,繼承相關(guān)的語法枕扫,異常的語法辱魁,線程的語...
    子非魚_t_閱讀 31,630評論 18 399
  • 寫在前面 本篇文章是《The Python Tutorial》(3.6.1)染簇,第九章,類的譯文锻弓。 9. Class...
    理查德成閱讀 747評論 0 8
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,516評論 1 51
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉暴心,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,709評論 0 9