Python基礎(chǔ)-類

Python基礎(chǔ)-類

@(Python)[python, python基礎(chǔ)]

寫在前面

如非特別說(shuō)明亿昏,下文均基于Python3

摘要
本文重點(diǎn)講述如何創(chuàng)建和使用Python類箫攀,綁定方法與非綁定方法的區(qū)別我注,以及Python的多態(tài)與簡(jiǎn)單繼承。

1. 面向?qū)ο缶幊?/h3>

1.1 對(duì)象和類

面向?qū)ο筮@種思想其實(shí)只是人類思維在程序設(shè)計(jì)領(lǐng)域的一種自然延伸郊闯。程序設(shè)計(jì)領(lǐng)域?qū)F(xiàn)實(shí)世界中事物自然延伸為“對(duì)象”舌涨,事物擁有其屬性和作用,對(duì)象也一樣抓半,擁有屬性以及方法喂急;復(fù)雜的面向?qū)ο蟪绦蚓褪腔谝粋€(gè)個(gè)基本的對(duì)象,相互交織笛求,構(gòu)造一個(gè)完整的對(duì)象生態(tài)廊移。

現(xiàn)實(shí)世界中“類”這個(gè)概念其實(shí)并不顯著,但是也存在探入。類在面向?qū)ο笾惺菍?duì)一個(gè)對(duì)象集合的抽象狡孔,抽象集合中對(duì)象共有的屬性,方法構(gòu)成類蜂嗽。通過(guò)類可以構(gòu)建具體的對(duì)象苗膝。

1.2 一切皆對(duì)象

Python哲學(xué)是

一切皆對(duì)象

在使用Python編程和學(xué)習(xí)時(shí),需時(shí)刻秉持這一思想植旧。

2. 定義Python類&對(duì)象

2.1 最簡(jiǎn)單的python類

Python類定義的句法很簡(jiǎn)單荚醒,關(guān)鍵字class后接合法類名即可芋类;最簡(jiǎn)單的Python類如下:

class Person:
    pass

類對(duì)象
Python一切皆對(duì)象,類也不例外界阁。Python解釋器在解釋完類定義這段代碼時(shí),在當(dāng)前作用域創(chuàng)建了一個(gè)類對(duì)象用來(lái)表示該類胖喳,并使用名字Person指向該類對(duì)象泡躯;
使用類對(duì)象,可以進(jìn)行以下操作:

  1. 實(shí)例化
  2. 屬性引用

實(shí)例化&實(shí)例對(duì)象
實(shí)例化就是用類對(duì)象創(chuàng)建一個(gè)實(shí)例對(duì)象過(guò)程丽焊,實(shí)例化的結(jié)果是實(shí)例對(duì)象较剃;語(yǔ)法如下:

p = Person()

以上語(yǔ)句在當(dāng)前作用域創(chuàng)建Person類對(duì)象的實(shí)例對(duì)象,并使用名字p指向該對(duì)象技健。

屬性引用
引用對(duì)象的屬性非常簡(jiǎn)單写穴,使用obj.attr的方式就可以引用對(duì)象obj的屬性attr

2.2 屬性綁定

只有對(duì)象綁定過(guò)屬性之后雌贱,才能引用該屬性啊送。Python是動(dòng)態(tài)語(yǔ)言,可以在可變對(duì)象創(chuàng)建之后為對(duì)象綁定屬性欣孤。
類對(duì)象的綁定屬性被稱為類變量馋没;實(shí)例對(duì)象的綁定屬性被稱為實(shí)例變量。通常來(lái)說(shuō)降传,實(shí)例變量是對(duì)于每個(gè)實(shí)例都獨(dú)有的數(shù)據(jù)篷朵,而類變量是該類所有實(shí)例共享的屬性和方法。

由于Python是動(dòng)態(tài)語(yǔ)言婆排,因此可以在對(duì)象創(chuàng)建之后修改對(duì)象的信息声旺。
可以在Person類對(duì)象創(chuàng)建之后綁定屬性:

Person.school = 'Whu University'

也可以在Person實(shí)例對(duì)象創(chuàng)建之后綁定屬性:

p = Person()
p.name = 'Richard'
p.age = 20

def print_info(p):
    print(p.name, p.age)

print_info(p)

更多關(guān)于類變量與實(shí)例變量的區(qū)別與聯(lián)系,參考 Python基礎(chǔ)-類變量和實(shí)例變量

3. 封裝

如果在對(duì)象創(chuàng)建之后再根據(jù)需要綁定屬性段只,并且在外部函數(shù)隨意訪問(wèn)實(shí)例對(duì)象的屬性腮猖,那么類機(jī)制的優(yōu)點(diǎn)就無(wú)法體現(xiàn)出來(lái)了。在實(shí)踐中翼悴,我們一般在定義類時(shí)就決定了類變量與實(shí)例變量缚够。

3.1 隱藏細(xì)節(jié)

通常來(lái)說(shuō),對(duì)象的使用者只需要關(guān)心對(duì)象能“做什么”鹦赎,而不需要也不應(yīng)該關(guān)心“怎么做”谍椅,這就是封裝了。按照封裝的思想古话,一個(gè)Python類應(yīng)該向外提供接口雏吭,并隱藏接口實(shí)現(xiàn)細(xì)節(jié):

class Person:
    school = 'Whu University' # 類屬性綁定
    
    def __init__(self, name, age):
        self.name = name # 實(shí)例屬性綁定
        self.age = age # 實(shí)例屬性綁定
    
    def print_info(self): # 暴露公共接口
        print(self.name, self.age)

p = Person('Richard', 20)
p.print_info()

如上,將屬性的綁定放到類定義中陪踩,并向外提供了接口杖们。然而不幸的是悉抵,在類外部還是可以引用到類實(shí)例的屬性。

3.2 綁定方法與非綁定方法

通過(guò)直接將print_info打印出來(lái)摘完,可以直觀看到綁定方法與非綁定方法的區(qū)別:

print(Person.print_info) 
print(p.print_info) 

output:

<function Person.print_info at 0x006E2AE0>
<bound method Person.print_info of <__main__.Person object at 0x006E0E10>>

可以看到類對(duì)象Person的函數(shù)print_info是個(gè)function姥饰;而實(shí)例對(duì)象p的方法print_info是個(gè)bound method綁定方法。

也可以查看它們的類型:

print(type(Person.print_info)) # <class 'function'>
print(type(p.print_info)) # <class 'method'>

一般來(lái)說(shuō)孝治,非綁定方法也叫函數(shù)列粪,綁定方法簡(jiǎn)稱方法。綁定方法的綁定谈飒,在于函數(shù)與特定的對(duì)象綁定在了一起岂座。

引用非數(shù)據(jù)屬性的實(shí)例屬性時(shí),會(huì)搜索它對(duì)應(yīng)的類杭措。如果名字是一個(gè)有效的函數(shù)對(duì)象费什,Python會(huì)將實(shí)例對(duì)象連同函數(shù)對(duì)象打包到一個(gè)抽象的對(duì)象中并且依據(jù)這個(gè)對(duì)象創(chuàng)建方法對(duì)象:這就是被調(diào)用的方法對(duì)象(綁定方法)。當(dāng)使用參數(shù)列表調(diào)用方法對(duì)象時(shí)手素,會(huì)使用實(shí)例對(duì)象以及原有參數(shù)列表構(gòu)建新的參數(shù)列表鸳址,并且使用新的參數(shù)列表調(diào)用函數(shù)對(duì)象。

那么刑桑,以綁定形式調(diào)用方法時(shí)氯质,第一個(gè)參數(shù)不是顯式傳遞的,而是解釋器隱式傳遞的:

p.print_info()

同樣祠斧,也可以通過(guò)調(diào)用綁定方法的函數(shù)版本達(dá)到相同的目的:

Person.print_info(p) # 函數(shù)必須顯式傳遞參數(shù)

3.3 魔法方法__init__

方法__init__是一個(gè)充滿魔力的方法闻察,一般以雙下劃線開頭并且結(jié)尾的方法對(duì)于Python都有特殊的意義,在滿足條件的時(shí)候被調(diào)用琢锋。
__init__就是一個(gè)構(gòu)造方法辕漂,在類對(duì)象的實(shí)例化過(guò)程中被調(diào)用,即在p = Person()這條語(yǔ)句中吴超,Python解釋器自動(dòng)調(diào)用了__init__方法钉嘹。

一般來(lái)說(shuō),使用__init__方法來(lái)初始化實(shí)例對(duì)象鲸阻,即為實(shí)例對(duì)象綁定屬性跋涣。

3.4 綁定方法參數(shù)self

注意到類Person定義的兩個(gè)方法中都有一個(gè)占據(jù)第一個(gè)參數(shù)位置,名為self的參數(shù)鸟悴。其實(shí)這是一個(gè)特殊參數(shù):當(dāng)調(diào)用綁定方法時(shí)陈辱,調(diào)用實(shí)例對(duì)象會(huì)被Python解釋器作為第一個(gè)參數(shù)來(lái)調(diào)用綁定方法。

因此细诸,重要的是參數(shù)位置沛贪,在綁定方法中,第一個(gè)參數(shù)總是代表當(dāng)前調(diào)用實(shí)例對(duì)象,與參數(shù)名字無(wú)關(guān)利赋。但是水评,self的字面意思是自身的意思,這個(gè)名字能很好的體現(xiàn)第一個(gè)參數(shù)的實(shí)際意義媚送。

在類中中燥,類的局部作用域與函數(shù)的局部作用域是不能相互訪問(wèn)的,詳見:Python進(jìn)階 - 命名空間與作用域季希。因此褪那,函數(shù)直接只能以對(duì)象引用的方式訪問(wèn)其他屬性,這也是對(duì)外提供的接口都有self參數(shù)的原因式塌。

class Person:
    school = 'Whu University'
    
    def __init__(self, name, age):
        self.name = name
        self.age = age
        # print(school) 類屬性school是不能直接訪問(wèn)的,需要用Person.school的形式
    
    def print_info(self): # 如果沒(méi)有self友浸,將訪問(wèn)不到name和age
        print(self.name, self.age)

3.5 私有化

Python并沒(méi)有語(yǔ)法支持屬性的私有化峰尝,但是Python可以使用“名稱變化術(shù)”改變私有屬性的名字:

class Person:
    __school = 'Whu University'
    
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    
    def print_info(self):
        print(self.__name, self.__age)

p = Person('Richard', 20)
p.print_info()
print(p.__dict__) # {'_Person__name': 'Richard', '_Person__age': 20}

通常來(lái)說(shuō),Python解釋器會(huì)將類定義中所有以__開頭的屬性變名收恢,具體變名的規(guī)則由解釋器決定武学,目前的CPython解釋器是在前面加_類名的方式。

誠(chéng)然伦意,仍然可以使用變名后的屬性名火窒,如此處的_Person__name, _Person__age來(lái)訪問(wèn)實(shí)例對(duì)象的屬性,但是通常不建議這么做驮肉。因?yàn)樽兠囊?guī)則是解釋器決定的熏矿,如果變更解釋器,變名可能就不一樣了离钝;再則票编,變名是類作者給類使用者的一個(gè)強(qiáng)力信號(hào),不建議使用者直接訪問(wèn)屬性卵渴。

一般地慧域,還可以在屬性名前加前綴_,如_name, _age浪读,來(lái)表達(dá)私有屬性昔榴。這種方式不會(huì)引起解釋器的變名,但是發(fā)出了不應(yīng)該直接訪問(wèn)這些屬性的信號(hào)碘橘。同時(shí)互订,這種規(guī)則的屬性不會(huì)被from module import *的方式導(dǎo)入。

4. 多態(tài)

多態(tài)意味著就算不知道變量所引用的對(duì)象的類型蛹屿,還是能夠?qū)λM(jìn)行操作屁奏,而它會(huì)根據(jù)對(duì)象的實(shí)際類型的不同表現(xiàn)出不同的行為。

4.1 其他語(yǔ)言的多態(tài)

在一些高級(jí)語(yǔ)言中错负,為實(shí)現(xiàn)多態(tài)坟瓢。首先會(huì)定義一個(gè)接口勇边,然后實(shí)現(xiàn)若干繼承接口的的具體類,以頂層的接口來(lái)引用具體的接口實(shí)現(xiàn)折联,在運(yùn)行時(shí)根據(jù)具體實(shí)現(xiàn)的不同表現(xiàn)出不同的行為:

interface Top {
    void bar();
}

class A implements Top {
    public void bar(){
        // implementing of A
    }
}

class B implements Top {
    public void bar(){
        // implementing of B
    }
}

void foo(Top t) {
    t.bar()
}

這里foo方法根據(jù)參數(shù)t實(shí)際類型的不同會(huì)表現(xiàn)出不同的行為粒褒。

4.2 Python的多態(tài)

Python的多態(tài)思想與上面是相同的,但是在實(shí)現(xiàn)上有所不同诚镰。Python中的多態(tài)是基于對(duì)象的行為奕坟,而不像其他語(yǔ)言是基于父類或者接口。Python雖然是強(qiáng)類型語(yǔ)言清笨,但是Python的變量是沒(méi)有類型的月杉,因此Python多態(tài)不需要一個(gè)頂層的接口。只需要實(shí)際的對(duì)象擁有需要的屬性即可:

class FooLike1:
    def wow(self):
        print('foo in FooLike1')
        
class FooLike2:
    def wow(self):
        print('foo in FooLike2')
        
def bar(foo):
    foo.wow()
    
bar(FooLike1()) # foo in FooLike1
bar(FooLike2()) # foo in FooLike2

當(dāng)然參與多態(tài)的對(duì)象有共同父類也是可以的抠艾,重點(diǎn)是都有參與多態(tài)需要的函數(shù)苛萎。Python中的多態(tài)要靈活得多;只要對(duì)象擁有指定方法检号,就可以參與多態(tài)腌歉,這種對(duì)象成為“like”對(duì)象,如和file對(duì)象擁有read方法的對(duì)象是file like對(duì)象齐苛,可以參與到關(guān)于read的多態(tài)中翘盖。

5. 繼承

繼承是一個(gè)懶惰的行為,子類可以不勞而獲從父類獲取必要信息凹蜂。如現(xiàn)在有一個(gè)Person類馍驯,擁有名字和年齡屬性,現(xiàn)在要?jiǎng)?chuàng)建一個(gè)Student類炊甲,也有名字和年齡泥彤,并且增加和學(xué)號(hào)信息;通過(guò)繼承卿啡,可以從Person不勞而獲一些信息吟吝。

5.1 如何繼承

Python的繼承語(yǔ)法也很簡(jiǎn)單,只需要在類名后跟括號(hào)颈娜,括號(hào)中寫入要繼承的類即可:

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

當(dāng)然剑逃,如果是多繼承,在繼承列表里添加即可:

class DerivedClassName(BaseClassName1, BaseClassName2, ..., BaseClassNamen):
    <statement-1>
    .
    .
    .
    <statement-N>

5.1 繼承到了什么

那么官辽,子類到底從父類繼承到了什么呢蛹磺?一個(gè)直觀的例子可以看出:

class Person:
    __school = 'Whu University'
    
    def __init__(self, name, age):
        self.__name = name
        self.__age = age
    
    def print_info(self):
        print(self.__name, self.__age)

    def test():
        pass

class Student(Person):
    
    def __init__(self):
        pass

print(dir(Student))

s = Student()
print(dir(s))

output:

['_Person__school', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'print_info', 'test']
=======分割線=======
['_Person__school', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'print_info', 'test']

可以看出,子類類對(duì)象繼承到了父類類對(duì)象的所有東西同仆,包括類屬性萤捆,函數(shù)。但是子類實(shí)例對(duì)象沒(méi)有繼承到父類實(shí)力對(duì)象的實(shí)例屬性,即 __name__age沒(méi)有繼承到俗或。

我們說(shuō)過(guò)市怎,屬性只有綁定之后才能引用,顯然辛慰,在子類中沒(méi)有調(diào)用父類的__init__方法区匠,父類的實(shí)例對(duì)象的屬性自然沒(méi)有初始化;因此只要在子類中調(diào)用父類的構(gòu)造方法帅腌,就可以繼承到實(shí)例屬性了:

class Student(Person):
    
    def __init__(self, name, age, stu_id):
        self.stu_id = stu_id
        super().__init__(name, age)

子類如何初始化父類是一個(gè)大問(wèn)題驰弄,單繼承比較簡(jiǎn)單,涉及到多繼承的初始化就比較復(fù)雜了速客。

5.2 獲取繼承關(guān)系

Python有兩個(gè)可以判斷繼承關(guān)系的內(nèi)建函數(shù):

  • 使用isinstance()檢查實(shí)例的類型:isinstance(obj, int)戚篙,當(dāng)且僅當(dāng)obj.class是int或者派生與int的類時(shí),返回True
  • 使用issubclass()檢查類的繼承關(guān)系:issubclass(bool, int)返回True溺职,因?yàn)閎ool是int的子類已球。然而issubclass(float, int)返回False,因?yàn)閒loat不是int的子類辅愿。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市忆某,隨后出現(xiàn)的幾起案子点待,更是在濱河造成了極大的恐慌,老刑警劉巖弃舒,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件癞埠,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡聋呢,警方通過(guò)查閱死者的電腦和手機(jī)苗踪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)削锰,“玉大人通铲,你說(shuō)我怎么就攤上這事∑鞣罚” “怎么了颅夺?”我有些...
    開封第一講書人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)蛹稍。 經(jīng)常有香客問(wèn)我吧黄,道長(zhǎng),這世上最難降的妖魔是什么唆姐? 我笑而不...
    開封第一講書人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任拗慨,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赵抢。我一直安慰自己剧蹂,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開白布昌讲。 她就那樣靜靜地躺著国夜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪短绸。 梳的紋絲不亂的頭發(fā)上车吹,一...
    開封第一講書人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音醋闭,去河邊找鬼窄驹。 笑死,一個(gè)胖子當(dāng)著我的面吹牛证逻,可吹牛的內(nèi)容都是我干的乐埠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼囚企,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼丈咐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起龙宏,我...
    開封第一講書人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤棵逊,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后银酗,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辆影,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年黍特,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蛙讥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡灭衷,死狀恐怖次慢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情今布,我是刑警寧澤经备,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站部默,受9級(jí)特大地震影響侵蒙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜傅蹂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一纷闺、第九天 我趴在偏房一處隱蔽的房頂上張望算凿。 院中可真熱鬧,春花似錦犁功、人聲如沸氓轰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)署鸡。三九已至,卻和暖如春限嫌,著一層夾襖步出監(jiān)牢的瞬間靴庆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工怒医, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留炉抒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓稚叹,卻偏偏與公主長(zhǎng)得像焰薄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扒袖,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

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

  • 定義類并創(chuàng)建實(shí)例 在Python中塞茅,類通過(guò) class 關(guān)鍵字定義。以 Person 為例季率,定義一個(gè)Person類...
    績(jī)重KF閱讀 3,952評(píng)論 0 13
  • Python基礎(chǔ)-類變量和實(shí)例變量 寫在前面 如非特別說(shuō)明凡桥,下文均基于Python3 大綱: 1. 類變量和實(shí)例變...
    理查德成閱讀 838評(píng)論 0 7
  • 要點(diǎn): 函數(shù)式編程:注意不是“函數(shù)編程”,多了一個(gè)“式” 模塊:如何使用模塊 面向?qū)ο缶幊蹋好嫦驅(qū)ο蟮母拍钍赐傩浴?..
    victorsungo閱讀 1,504評(píng)論 0 6
  • Python進(jìn)階框架 希望大家喜歡,點(diǎn)贊哦首先感謝廖雪峰老師對(duì)于該課程的講解 一啊掏、函數(shù)式編程 1.1 函數(shù)式編程簡(jiǎn)...
    Gaolex閱讀 5,498評(píng)論 6 53
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蠢络,服務(wù)發(fā)現(xiàn),斷路器迟蜜,智...
    卡卡羅2017閱讀 134,656評(píng)論 18 139