Python系列7——類和對象(1)

目錄

一、面向對象編程

二、類及其定義

三、類的屬性與方法

四、實例方法、類方法、靜態方法

實例方法

類方法

靜態方法

五、魔法方法



一、面向對象編程

在研究對象時主要考慮對象的屬性和行爲。通常將屬性及其行爲相同的或相似的對象歸爲一類(求同存異)。類可以看作是一類對象的抽象,代表此類對象所具有的共同屬性和行爲。Python是一門面向對象的程序設計,程序的基本組成是類。程序在運行時由類生成對象,對象之間通過發送消息進行通信,進而完成一系列的操作。對象是程序的核心。面向對象程序設計的核心是對象。面向對象中涉及的主要概念有抽象、封裝、繼承和多態抽象是對一類具體對象的抽象,得到他們共有的屬性和行爲,形成類,類就是他們的抽象。封裝是有清楚的邊界,所有對象的內部信息被限定在這個邊界內,接口是對象向外界提供的方法,外界可以通過這些方法與對象進行交互。由於封裝的特性禁止了外界對象直接操作類中的數據使得模塊與模塊之間只能通過嚴格控制的接口進行交互,這使得模塊之間的耦合度大大降低,從而保證了模塊具有很好的獨立性,使得程序的維護和修改變的十分的容易。繼承從某種程度上來說是反抽象或者說是更加具體的一種行爲,他爲類的重用提供了方便。多態是一個程序中同名的不同方法共存的情況,比如“啓動”是所有交通工具的行駛的充要條件,但是不同的交通工具啓動的方法也不盡相同。此時,我們可以定義“汽車啓動”“輪船啓動”,這些名字也都不一樣,太麻煩了。而多態就可以幫助我們解決這個問題,只起一個名字“啓動”,這樣一來通過不同交通工具就都可以相應他們自己“啓動”的方法了。Python中的類型其實不僅僅包括數據本身的格式和大小,還包括數據的方法,而類也是一種類型。他應該也能向integer一樣進行運算,只不過,類的對象需要自己去定義他的運算(方法)。簡單說,類是對一類對象的抽象,是對象的模板,而對象是這個類的具體實例。

二、類及其定義

類是對一類對象的抽象,是對象的模板,而對象是這個類的具體實例。在另一方面,類也是一種用戶自己數據類型,通過定義自己的類,可以實例化類的對象(定義自己的數據類型)。

//類的定義語法
class Student(object):
    """定義了一個Student類屬性,具有name, sex, age等屬性"""
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age


student1 = Student("jack", 'male', 10)
print(student1)
print(student1.name, student1.sex, student1.age)
print(student1.__doc__)

//輸出
<__main__.Student object at 0x00000276D5B4F0B8>
jack male 10
定義了一個Student類屬性,具有name, sex, age等屬性
class Student(object):
    """定義了一個Student類屬性,具有name, sex, age等屬性"""
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def student_print(self):
        print(self.name, self.sex, self.age)


student1 = Student("jack", 'male', 10)
print(student1)
student1.student_print()
print(student1.__doc__)

/************************輸出**********************/
<__main__.Student object at 0x00000200D758F0B8>
jack male 10
定義了一個Student類屬性,具有name, sex, age等屬性
class Student(object):
    """定義了一個Student類屬性,具有name, sex, age等屬性"""
    def __init__(self, name, sex, age):
        self.name = name
        self.sex = sex
        self.age = age

    def student_print(self):
        print(self.name, self.sex, self.age)


student1 = Student("jack", 'male', 10)
student1.id = 20181220
student1.student_print()

student2 = Student("曹亞磊", 'male', 20)
student2.student_print()
print(student1.id)
print(student2.id)

/**************************輸出*********************/
jack male 10
曹亞磊 male 20
20181220
Traceback (most recent call last):
  File "E:/space/Python/PycharmPython/classTemp.py", line 18, in <module>
    print(student2.id)
AttributeError: 'Student' object has no attribute 'id'

總結:

類是創建實例的模板,而實例是一個一個具體的對象,各個實例擁有的數據都相互獨立,互不影響。

方法就是與實例綁定的函數,和不同函數不同,方法可以直接實例的數據。

self:每一個類的方法的第一個參數都是self,該self是一個指針,指向當前對象。

通過實例調用方法,我們就直接操作了對象內部的數據,但無需知道方法內部的實現細節。

Python是一門動態語言,和靜態語言不同,Python允許對實例變量綁定任何數據,也就是說,對於兩個實例變量,雖然他們都是同一個類的不同實例,但擁有的變量名稱都可能不同

三、類的屬性與方法

類的屬性分類方法有兩種:公有屬性與私有屬性(前面是否有雙下劃線__)、類屬性和實例屬性(屬性是否定義在方法內部)

class Student(object):
    """定義了一個Student類屬性,具有name, sex, age等屬性"""
    # address、__grade類屬性,其中address爲公有屬性,__grade爲私有屬性
    # 類屬性爲所有實例公有
    # 私有屬性不能在類外訪問
    address = '上海'
    __grade = "八年級"

    def __init__(self, name, sex, age, teacher = '董老師'):
        # name、sex、age、__teacher爲對象屬性,其中前三個是公有屬性,最後一個是私有屬性
        # 對象屬性由單個實例所有
        # 私有屬性不能在類外訪問
        self.name = name
        self.sex = sex
        self.age = age
        self.__teacher = teacher

    def student_print(self):
        print(self.name, self.sex, self.age, self.__teacher)


student1 = Student("張同學", 'male', 10)
student1.id = 20181220
student1.student_print()

student2 = Student("曹同學", 'male', 20)
student2.student_print()

print(student1.id)

print(student2.address, student1.address)
"""*************************輸出***************************"""
張同學 male 10 董老師
曹同學 male 20 董老師
20181220
上海 上海

四、實例方法、類方法、靜態方法

class MyClass:
    # 實例方法
    def method(self):
        return 'instance method called', self

    # 類方法
    @classmethod
    def classmethod(cls):
        return 'class method called', cls

    # 靜態方法
    @staticmethod
    def staticmethod():
        return 'static method called'

實例方法

MyClass的第一個方法就叫“方法”,它就是一個普通的實例方法,也是在大多數情況下使用的最基本的、最簡單的方法。該方法接受一個參數self,它在調用該方法時指向一個MyClass的一個實例。(當然,實例方法可以接受的參數不止一個)。

通過self參數,實例方法可以自由地訪問同一對象的屬性和其他方法。當涉及到修改對象的狀態時,實例方法就非常給力。

類方法

類方法用裝飾符@classmethod進行標記。類方法不接受self參數,而是接受一個cls參數。cls參數在調用方法時,指向的是類而不是對象實例。

由於類方法只能訪問cls參數,因此它無法修改對象的實例狀態——那就需要訪問self。但是,類方法仍然可以對應用於類的所有實例的類狀態進行修改。

靜態方法

靜態方法使用一個裝飾符@staticmethod標記的方法。

這個方法既不接受self參數,也不接受cls參數(但是,他可以接受任意數量的其他參數)。

因此靜態方法既不能修改對象狀態,也不能修改類狀態。靜態方法在它們可以訪問的數據方面受到限制,它們主要用於對你的方法進行空間命名。

五、魔法方法

從入門到進階,一個很重要的點就是Python中的魔法方法,魔法方法就是可以給你的類增加魔力的特殊方法,如果你的對象實現了這些方法中的某一個,那麼這個方法就會在特殊的情況下被 Python 所調用,你可以定義自己想要的行爲,而這一切都是自動發生的。它們經常是兩個下劃線包圍來命名的(比如 __init__/__new__等等),Python的魔法方法是非常強大的。

如果你學習過Java,那你會發現Python中的魔法方法像是Java中的重載,Python中的魔法方法可以理解爲:對類中的內置方法的重載,注意這裏不是重寫。

舉個例子,Python中有個比較操作符==用來比較兩個變量的大小,而這個操作符是通過內置函數__eq__來實現的,所以我們只需要通過改變這個內置函數代碼,就可以改變重新定義這個操作符的行爲。

我們定義一個類Word,繼承自str類,現需要重新定義該類的操作符==,使這個操作符用來判斷兩個字符串長度是否相等,而不是通過字母順序判斷兩個字符串是否相等。注意該變化只適用於Word類,而不適用於其它類。

再比如,定義一個利用iter()可以調用__iter__()方法,返回一個迭代器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章