Python面向?qū)ο笈c類

一稠氮、面向?qū)ο蟾拍?/h3>
  1. 面向?qū)ο笫且环N主流的編程思想,基本單元:對象半开,把數(shù)據(jù)和對象封裝起來隔披,實現(xiàn)很好的復用性、靈活性寂拆、擴展性奢米;

  2. 面向?qū)ο笫且环N抽象,抽象是指用分類的眼光看待事物的方法纠永,需要對事物進行總結(jié)恃慧,分析共性,利用抽象能夠簡化解決問題的難度渺蒿;

  3. 基本概念
    類:定義事物的抽象特點
    對象:類的一個實例

  4. 基本要素:
    屬性:類的信息
    方法:類的功能

  5. 類的特性

  • 封裝:類可以實現(xiàn)很多的功能痢士,對外調(diào)用時,不需要知道具體是怎么實現(xiàn)的茂装;

  • 繼承:定義一個新類時怠蹂,不必從頭編寫,可以從現(xiàn)有的類中繼承少态,獲得現(xiàn)有類的所有功能城侧,新類只需要編寫現(xiàn)有類缺少的功能;

  • 多態(tài):繼承于同一個父類的不同之子類彼妻,父類的方法嫌佑,各個子類都有,但調(diào)用時的結(jié)果卻不相同侨歉;

  • 類對象創(chuàng)建后屋摇,類命名空間中所有的命名都是有效屬性名。

二幽邓、定義類


  1. 語法:class Class_name(object):

  2. __init__:定義類時炮温,為類設(shè)置必要的屬性,即初始化實例

  3. 示例

class Student(object):
    def __init__(self, name, sex, grade):
        self.name = name,
        self.sex = sex,
        self.grade = grade

if __name__ == '__main__':
    student = Student('larry', 'male', 5)        # 創(chuàng)建實例
    print('student of class:\n', student)        # 查看student類
    print('----------------------------')
    print('type of student:\n', type(student))      # 查看student的類型
    print('----------------------------')
    print('attribute of student:\n', dir(student))      # 查看student的屬性

student of class:
 <__main__.Student object at 0x1063207b8>
----------------------------
type of student:
 <class '__main__.Student'>
----------------------------
attribute of student:
['__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__', 'grade', 'name', 'sex']


三牵舵、定義類的屬性


  1. 方法
  • 直接在類中定義:被類的所有對象(方法)共享柒啤,其屬性值都是一樣的倦挂;
  • 通過構(gòu)造函數(shù):def __init__(self, [, ....]),其屬性值依賴于傳入的值担巩;
  1. 訪問控制
  • 實際上方援,Python中并沒有訪問控制,Python沒有提供私有屬性的功能涛癌;

  • 通過屬性命名規(guī)范可以實現(xiàn)訪問控制肯骇,不希望被外部訪問的屬性,在屬性名前添加雙下劃線(__)即可祖很。在實際工作中笛丙,這些命名規(guī)范全靠自覺;

  • 單下劃線開頭的屬性假颇,可以在子類中使用胚鸯;雙下劃線開頭的屬性,不能被外部調(diào)用笨鸡,也不能在子類中使用姜钳,即繼承時這些私有屬性和方法不會被覆蓋。

  1. 示例
class Person(object):
    hobby = 'Play Computer'     # 直接在類中定義屬性hobby

    def __init__(self, name, sex, age):     # 構(gòu)造函數(shù)中定義初始化屬性
        self.name = name,
        self._sex = sex,
        self.__age = age

    def get_age(self):
        return self.__age


if __name__ == '__main__':
    person = Person('larry', 'female', '28')        # 創(chuàng)建實例
    print('attribute of person:\n', dir(person))    # 查看類的屬性
    print(person.__dict__)      # 查看構(gòu)造函數(shù)中定義的屬性
    print(person.get_age())     # 調(diào)用獲取age屬性的方法
    print(person._Person__age)  # 變相獲取雙下劃線開頭的age屬性

attribute of person:
 ['_Person__age', '__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__', 
'_sex', 'get_age', 'hobby', 'name']
{'name': ('larry',), '_sex': ('female',), '_Person__age': '28'}
28
28


四形耗、定義類的方法


  1. 概念
  • 函數(shù)是直接使用函數(shù)名進行調(diào)用哥桥;

  • 方法是類的一部分,必須和對象結(jié)合在一起使用激涤,使用類名進行調(diào)用拟糕,而不是某個對象;

  • 方法的訪問限制倦踢,和屬性一樣送滞,沒有嚴格的語法控制,只是遵循一些規(guī)范辱挥;

  • 類中定義的方法犁嗅,都是實例方法,可以看作是類的一個屬性晤碘,第一個參數(shù)永遠是self褂微,表示創(chuàng)建的實例本身,

  • @classmethod:裝飾的方法是類方法园爷,類方法的第一個參數(shù)將傳入類本身宠蚂,通常將參數(shù)名命名為cls;

  • @property:裝飾的方法腮介,調(diào)用時肥矢,像訪問屬性一樣(不需要帶括號)。

  1. 示例
class Person(object):
    hobby = 'Play Cumputer'     # 直接在類中定義屬性hobby

    def __init__(self, name, sex, age):     # 構(gòu)造函數(shù)中定義初始化屬性
        self.name = name,
        self._sex = sex,
        self.__age = age

    @classmethod
    def get_hobby(cls):
        return cls.hobby

    @property 
    def get_age(self):
        return self.__age 

    def self_introduction(self):
        print(f"My name is {self.name[0]}\nI am {self.__age} years old")

if __name__ == '__main__':
    person = Person('larry', 'male', 28)
    print(dir(person))
    print(Person.get_hobby())
    print(person.get_age)
    person.self_introduction()

['_Person__age', '__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__', '_sex', 
'get_age', 'get_hobby', 'hobby', 'name', 'self_introduction']
Play Cumputer
28
My name is larry
I am 28 years old


五叠洗、類的繼承


  1. 概念
  • 繼承的子類:會繼承父類的屬性和方法甘改,也可以自己定義,覆蓋父類的屬性和方法灭抑;
  • 使用supper()調(diào)用父類的方法十艾,或者直接使用父類的名稱調(diào)用;
  • isinstance():可以判斷一個實例是否是指定的類腾节;
  • issubclass():判斷一個類是否是子類;
  • 類繼承機制允許多重繼承忘嫉,派生類可以覆蓋(override)基類中的任何方法或類,可以使用相同的方法名稱調(diào)用基類的方法案腺。
  1. 示例
# 類的繼承

class Person(object):
    hobby = 'Play Cumputer'     # 直接在類中定義屬性hobby

    def __init__(self, name, sex, age):     # 構(gòu)造函數(shù)中定義初始化屬性
        self.name = name,
        self._sex = sex,
        self.__age = age

    @classmethod
    def get_hobby(cls):
        return cls.hobby

    @property 
    def get_age(self):
        return self.__age 

    def self_introduction(self):
        print(f"My name is {self.name[0]}\n I am {self.__age} years old")

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


if __name__ == '__main__':
    student = Student('larry', 'male', 28, 62)
    print(type(student))
    print(dir(student))
    print(student.__dict__)
    print(isinstance(student, Student))     # 實例student庆冕,是否是指定的類Student
    print(issubclass(Student, Person))      # 類Student,是否是類Person的子類

<class '__main__.Student'>
['_Person__age', '__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__', '_sex', 
'get_age', 'get_hobby', 'hobby', 'name', 'self_introduction', 'weight']
{'name': ('larry',), '_sex': ('male',), '_Person__age': 28, 'weight': 62}
True
True


六劈榨、多態(tài)


  1. 概念
  • 有了繼承访递,才有了多態(tài),在調(diào)用類實例方法時同辣,盡量把變量當作父類拷姿,以便所有子類類型都可以正常接收;
  • 多態(tài):繼承于同一個父類的不同之子類旱函,父類的方法响巢,各個子類都有,但調(diào)用時的結(jié)果卻不相同棒妨。
  1. 示例
# 類的多態(tài)

class Person(object):
    hobby = 'Play Cumputer'     # 直接在類中定義屬性hobby

    def __init__(self, name, sex, age):     # 構(gòu)造函數(shù)中定義初始化屬性
        self.name = name,
        self._sex = sex,
        self.__age = age

    @classmethod
    def get_hobby(cls):
        return cls.hobby

    @property 
    def get_age(self):
        return self.__age 

    def self_introduction(self):
        return f"My name is {self.name[0]}\nI am {self.__age} years old"

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

    def self_introduction(self):
        return f"My name is {self.name[0]}\n My weight is {self.weight}"

def introduce(class_name):
    if isinstance(class_name, Person):
        return class_name.self_introduction() 


if __name__ == '__main__':
    person = Person('larry', 'male', 28)
    student = Student('larry', 'male', 28, 62)
    print(introduce(person))
    print(introduce(student))

My name is larry
I am 28 years old

My name is larry
My weight is 62


七踪古、類的魔術(shù)方法

  1. 概念
  • 絕大多數(shù)的Python內(nèi)置函數(shù),都有對應(yīng)的魔術(shù)方法券腔,可以在類中使用灾炭;
  • 魔術(shù)方法,可以更方便自由地進行定制類颅眶,包括:對象建立蜈出、屬性訪問、運算符的支持涛酗、特殊語法等铡原;
  • 面向?qū)ο笾校Q前后各有2個下劃線(__)的方法商叹,都是魔術(shù)方法燕刻,是定義在類中的,不需要直接調(diào)用剖笙;
  • 類中常用的魔術(shù)方法
魔術(shù)方法 含義
__init__() 構(gòu)造函數(shù)卵洗,創(chuàng)建實例的時候被調(diào)用
__str__() 返回適合人看的字符,print()調(diào)用的就是該方法
__repr__ 返回適合機器看的字符
__eq__ 判斷是否相等,比較運算符
__add__ 相加过蹂,數(shù)字運算符
__and__ 判斷條件十绑,邏輯運算符
__dir__ 查看對象的屬性
__setattr__ 設(shè)置對象的屬性,注意避免循環(huán)遞歸酷勺,導致死循環(huán)
__getattribute__ 訪問對象的屬性本橙,注意避免死循環(huán)
__len__ 獲取對象參數(shù)個數(shù)
__call__ 調(diào)用對象
  1. 示例
# 類中的魔術(shù)方法

class Person(object):

    def __init__(self, name, age):      
        """
        構(gòu)造函數(shù),初始化定義屬性
        """
        self.name = name,
        if isinstance(age, int):        # 確保age屬性必須是數(shù)值
            self.age = age
        else:
            raise Exception ('age must be int')

    def __eq__(self, other):
        """
        判斷2個對象是否相等
        """
        if isinstance(other, Person):   # 確保2個對象是同一個父類
            if self.age == other.age:
                return True
            else:
                return False
        else:
            raise Exception ('The class of object must be Person')

    def __add__(self, other):
        """
        2個對象相加
        """
        if isinstance(other, Person):   # 確保2個對象是同一個父類
            return self.age + other.age
        else:
            raise Exception ('The class of object must be Person')

    def __str__(self):
        """
        輸出指定內(nèi)容
        """
        return f"{self.name[0]} is {self.age} years old"

    def __dir__(self):
        """
        設(shè)置輸出的屬性
        """
        return self.__dict__.keys()

    def __setattr__(self, name, value):
        """
        設(shè)置對象的屬性
        """
        self.__dict__[name] = value

    def __getattribute__(self, name):
        """
        訪問對象的屬性
        """
        return super(Person, self).__getattribute__(name)

    def __len__(self):
        """
        返回類的參數(shù)個數(shù)
        """
        return len(self.name)

    def __call__(self, friend):     # friend是調(diào)用對象時傳入的參數(shù)
        """
        調(diào)用對象
        """
        return f"My name is {self.name[0]} ... My friend is {friend}"


if __name__ == '__main__':
    p1 = Person('Larry', 28)
    p2 = Person('Python', 30)
    print(p1 == p2)     # __eq__根據(jù)age屬性脆诉,判斷是否相等
    print(p1 + p2)      # __add__對age屬性甚亭,相加
    print(p1)           # __str__返回指定的內(nèi)容
    print(dir(p1))      # __dir__輸出指定的屬性
    print(p1.age)       # __setattar__設(shè)置對象的屬性
    print(len(p1))      # __len__返回類的參數(shù)個數(shù)
    print(p1('Tom'))    # __call__調(diào)用對象

False
58
Larry is 28 years old
['age', 'name']
28
1
My name is Larry ... My friend is Tom
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市击胜,隨后出現(xiàn)的幾起案子亏狰,更是在濱河造成了極大的恐慌,老刑警劉巖偶摔,帶你破解...
    沈念sama閱讀 212,383評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暇唾,死亡現(xiàn)場離奇詭異,居然都是意外死亡啰挪,警方通過查閱死者的電腦和手機信不,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來亡呵,“玉大人抽活,你說我怎么就攤上這事∶淌玻” “怎么了下硕?”我有些...
    開封第一講書人閱讀 157,852評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長汁胆。 經(jīng)常有香客問我梭姓,道長,這世上最難降的妖魔是什么嫩码? 我笑而不...
    開封第一講書人閱讀 56,621評論 1 284
  • 正文 為了忘掉前任誉尖,我火速辦了婚禮,結(jié)果婚禮上铸题,老公的妹妹穿的比我還像新娘铡恕。我一直安慰自己,他們只是感情好丢间,可當我...
    茶點故事閱讀 65,741評論 6 386
  • 文/花漫 我一把揭開白布探熔。 她就那樣靜靜地躺著,像睡著了一般烘挫。 火紅的嫁衣襯著肌膚如雪诀艰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評論 1 290
  • 那天,我揣著相機與錄音其垄,去河邊找鬼苛蒲。 笑死,一個胖子當著我的面吹牛捉捅,可吹牛的內(nèi)容都是我干的撤防。 我是一名探鬼主播虽风,決...
    沈念sama閱讀 39,076評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼棒口,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辜膝?” 一聲冷哼從身側(cè)響起无牵,我...
    開封第一講書人閱讀 37,803評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎厂抖,沒想到半個月后茎毁,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡忱辅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,582評論 2 327
  • 正文 我和宋清朗相戀三年七蜘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片墙懂。...
    茶點故事閱讀 38,716評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡橡卤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出损搬,到底是詐尸還是另有隱情碧库,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評論 4 333
  • 正文 年R本政府宣布巧勤,位于F島的核電站嵌灰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏颅悉。R本人自食惡果不足惜沽瞭,卻給世界環(huán)境...
    茶點故事閱讀 40,039評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望剩瓶。 院中可真熱鬧驹溃,春花似錦、人聲如沸儒搭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽搂鲫。三九已至傍药,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背拐辽。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評論 1 266
  • 我被黑心中介騙來泰國打工拣挪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人俱诸。 一個月前我還...
    沈念sama閱讀 46,488評論 2 361
  • 正文 我出身青樓菠劝,卻偏偏與公主長得像,于是被迫代替她去往敵國和親睁搭。 傳聞我的和親對象是個殘疾皇子赶诊,可洞房花燭夜當晚...
    茶點故事閱讀 43,612評論 2 350