大話Python類語義

北門吹雪發表於2020-10-06


  物以類聚,人以群分,就是相同特徵的人和事物會自動聚集在一起,核心驅動點就是具有相同特徵或相類似的特徵,我們把具有相同特徵或相似特徵的事物放在一起,被稱為分類,把分類依據的特徵稱為類屬性

  計算機中分類的思想叫做物件導向,Python中把資料抽象成物件,通過物件或物件間的關係來描敘資料。

  我們把一些相似事物的共同特徵通過一個方式描敘出來,也就是說,你是按什麼標準對事物進行分類,相似點是什麼,計算機把對相似事物的特徵資料進行描敘稱為類定義

計算機中類的三大特徵
  1. 封裝資料的可見性進行約束,分為公有public、私有private、非公有, 公有資料可以直接通過屬性訪問語法 obj.attr 直接訪問,但是私有、非公有則通過方法進行訪問,訪問行為其實就是SQL中的增刪改查,查稱為讀,增刪改稱為寫,在Python中類的資料稱為資料屬性,類中定義的函式稱為方法,方法是關聯物件的函式

class Person:
    """資料封裝實現"""
    def __init__(self, name, age, sex):
        """名字是公開的, 性別是非公有, 年齡是私有"""
        # 現在給例項插入資料
        # 公有資料
        self.name = name
        # 非公有使用一個下劃線
        self._sex = sex
        # 私有變數使用兩個下劃線
        self.__age = age

    def get_name(self):
        """通過方法讀取名稱"""
        return self.name

    def set_age(self, value):
        """對年齡進行修改"""
        self.__age == value

    def get_age(self):
        """通過方法獲取私有屬性年齡"""
        return self.__age


if __name__ == '__main__':
    # 類的例項話類似函式呼叫,也可以使用關鍵字引數和位置引數
    p = Person("北門吹雪", 20, "male")
    # 通過 obj.name 屬性訪問語言訪問例項的屬性,這個飯方法只能訪問公有屬性
    print(p.name)

    # 通過方法修改年齡
    p.set_age(22)
    # 通過方法訪問私有屬性
    print(p.get_age())
    pass

  2. 繼承 需要理清幾個概念,父類、子類、基類、派生類,父類就是基類,子類就是派生類。繼承是建立在類的基礎上,子類完全繼承父類的所有屬性以及控制屬性訪問的方法。繼承要理清差異共相同點,對依據對事物進行分類的特徵要非常確定才能寫計算機中的類,不然不是分類,分類的前提是公共特徵,繼承的前提是共性與差異,如果不理解共同特徵你就無法分類,你不理解同一類的共性與差異你無法寫出繼承,繼承強調的是公共特徵,包括屬性和方法

class Human(object):
    """定義人類, 每個人類都有名字和國家, 都會說話"""
    def __init__(self, name, country):
        self.name = name
        self.country = country

    def say(self, language):
        """交流說話"""
        print(f"{self.name} 能說 {language}")


class Chinese(Human):
    """定義一箇中國人,繼承人類

     Human被稱為這個類的基類或這個類的父類,Chinese被成為Human的派生類"""

    def __init__(self, name, country, skin):
        """中國人和外國人最大的不同是膚色"""
        # 呼叫父類的建構函式
        super(Chinese, self).__init__(name, country)
        self.skin = skin


if __name__ == '__main__':
    c = Chinese("北門吹雪", 20, "yellow")
    print(c.skin)
    c.say("中文")
    pass

   3. 多型 同一個行為具有不同表現形式或形態的能力,計算機中最接近多型的是介面interface,介面定義相同行為,然後我們對介面行為的分類,就產生所謂的抽象基類,通過繼承機制,然後子類重寫方法從而實現多型,說白了就是同一個方法中有不同的實現,再說漏骨一點就是函式的名稱相同,函式的形參相同,函式的返回值相同,但是函式體內的語句邏輯不一樣,這個函式體不同被稱為多型。多型是建立在繼承的基礎上然後對方法進行重寫,其實能重寫(又稱為過載)的只有函式體,多型強調的是方法

class HumanInterface(object):
    """定義一個人類的抽象介面,用於實現多型, 多型強調的是方法

    定義了兩個介面,一個是吃 一個是說
    """
    def say(self, language):
        """說"""
        pass

    def eat(self, what):
        """吃"""
        pass


class Chinese(HumanInterface):
    """定義一箇中國人,繼承人類"""

    def __init__(self, name, country):
        """中國人和外國人最大的不同是膚色"""
        # 呼叫父類的建構函式
        self.name = name
        self.country = country

    def eat(self, what):
        """過載或重寫 父類中的方法,實現多型"""
        print(f"{self.name} 正在吃{what}ing")
        pass

    def say(self, language):
        print(f"{self.name} 能說 {language}")
        pass


class American(HumanInterface):
    """美國人"""
    def __init__(self, name, country):
        """中國人和外國人最大的不同是膚色"""
        # 呼叫父類的建構函式
        self.name = name
        self.country = country

    def eat(self, what):
        """過載或重寫 父類中的方法,實現多型"""
        print(f"{self.name}吃{what}再跳舞")
        pass

    def say(self, language):
        print(f"{self.name} 不僅能說 {language}, 還會其他國家語言")
        pass

if __name__ == '__main__':
    c = Chinese("北門吹雪", "中國")
    a = American("alex", "美國")
    c.eat("大米")
    a.eat("漢堡包")

    c.say("中文")
    a.say("英語")
    # 你會發現他們方法名相同,但是輸出不同,也就是形態不同

Python中類定義
類定義

class Name:
    pass

  # 定義是可執行的語句,在被import語句匯入或以main檔案執行時,定義就會被執行
  # 類定義的執行,首先會在當前作用域引入一個用於儲存類中屬性的名稱空間。然後把這個類名稱空間封裝成物件返回,並把這個類物件繫結到class關鍵字指定的名稱,這個名稱又被繫結到class關鍵子所在的名稱空間
  # Name -> 類物件 > 類名稱空間
  # 其實類定義中包含的一般是函式定義,函式定義的第一個引數其實時例項本身,通過例項本身就可以訪問例項中的資料屬性和方法

類物件
  # 支援兩種操作:屬性引用 和 例項化
  # 屬性引用使用Python標準屬性引用語法 obj.name
  # 例項化: 類的例項化,類似於函式呼叫,把括號裡的引數傳遞給類的__init__方法,通過__init__方法為類的新例項初始化特定的屬性,這個init方法又被稱為工廠函式, 其他語言中的類通過new關鍵字建立。Python中通過函式呼叫傳參的形式實現類的例項化

class Person(object):
    """人類"""
    # 能說話
    can_say = True
    # 能吃
    can_eat = True
    # 能睡覺
    can_sleep = True

    def __init__(self, name, age, country):
        self.name = name
        self.__age = age
        self.country = country

    def show_country(self):
        """顯示國籍"""
        print(f"{self.name}的國籍是: {self.country}")


if __name__ == '__main__':
    # 屬性引用
    print(Person.can_eat)
    print(Person.can_sleep)
    print(Person.can_sleep)

    # 例項化
    c = Person("北門吹雪", 20, "中國")

例項物件
  # 支援唯一的操作就是屬性引用, 其實和普通的變數引用一樣,只是多個歸屬字首而已,通過方法對例項裡的變數進行修改,實際上在函式封裝過程的基礎上再把資料和函式繫結起來

class Person(object):
    """人類"""
    # 能說話
    can_say = True
    # 能吃
    can_eat = True
    # 能睡覺
    can_sleep = True

    def __init__(self, name, age, country):
        self.name = name
        self.__age = age
        self.country = country

    def show_country(self):
        """顯示國籍"""
        print(f"{self.name}的國籍是: {self.country}")

    def set_age(self, value):
        """修改年齡"""
        self.__age = value

    def get_age(self):
        """獲取年齡"""
        return self.__age


if __name__ == '__main__':
    # 例項化
    user = Person("北門吹雪", 20, "中國")
    # 屬性引用
    user_age = user.get_age()
    print(user_age)

    # 設定年齡
    user.set_age(22)
    print(user.get_age())

方法物件
  # 方法是從屬某個物件的函式,類中的函式定義了類的例項所擁有的方法,也就是說物件的型別決定了物件支援的操作
  # 方法對比函式,函式定義在模組或函式中,方法定義在類定義中,方法的第一個引數固定時例項物件

類和例項變數
  # 例項變數是每個例項的唯一資料,而類變數是該類的所有例項共享的屬性和方法
  # 相同屬性名稱出現在類和例項中,首先被找到的時例項屬性

class Person(object):
    """人類"""
    # 該類被例項化多少次
    object_count = 0

    # 預設全球通用語言是英語
    language = "En"

    def __init__(self, name, age, country, language):
        self.name = name
        self.__age = age
        self.country = country
        self.language = language

    def show_country(self):
        """顯示國籍"""
        print(f"{self.name}的國籍是: {self.country}")

    def set_age(self, value):
        """修改年齡"""
        self.__age = value

    def get_age(self):
        """獲取年齡"""
        return self.__age

    @classmethod
    def add_obj(cls):
        cls.object_count += 1


if __name__ == '__main__':
    # 例項化
    user = Person("北門吹雪", 20, "中國", "Cn")
    # 例項化一次則類變數增加一次
    Person.add_obj()

    user_two = Person("alex", 30, "美國", "En")
    Person.add_obj()

    # 列印被例項化幾次
    print(Person.object_count)

    # 類變數和屬性同名訪問,優先選擇例項
    print(user.language)

 

  

 

相關文章