Python入門(三)-面向對象

一、創建類

class Student:
    name = "jack"#屬性
    age = 18 #公有屬性
    __private_sttrs = ""#兩個下劃線開頭,聲明該屬性為私有

def __init__(self,age):#__init__是構造方法
    self.age = age
    print ("init")

def __private_method(self):#兩個下劃線開頭,聲明該方法為私有方法,不能在類地外部調用。在類的內部調用
    print "private method"

def setName(self,name):#方法
   self.name = name
   print("setName")

stu = Student(20)#創建實例對象
stu.setName("jim")#調用方法

print stu.name
print stu.age

self 代表類的實例,self 在定義類的方法時是必須有的,雖然在調用時不必傳入相應的參數。
self 不是 python 關鍵字,只是習慣用這個命名表示類的實例,我們把他換成 runoob 也是可以正常執行

class Test:
    def prt(self):
        print(self)
        print(self.__class__)


t = Test()
t.prt()

二、添加,刪除,修改類的屬性

stu.gender = "male" #類中沒有gender屬性,直接添加屬性
stu.gender = "female"#修改屬性
del stu.gender #刪除屬性

三、訪問屬性的函數方法
你也可以使用以下函數的方式來訪問屬性:
getattr(obj, name[, default]) : 訪問對象的屬性。
hasattr(obj,name) : 檢查是否存在一個屬性。
setattr(obj,name,value) : 設置一個屬性。如果屬性不存在,會創建一個新屬性。
delattr(obj, name) : 刪除屬性。

hasattr(stu, "age")    # 如果存在 'age' 屬性返回 True。
getattr(stu, "age")    # 返回 'age' 屬性的值
setattr(stu, "age", 8) # 添加屬性 'age' 值為 8
delattr(stu, "age")    # 刪除屬性 'age'

四、Python內置類屬性
dict : 類的屬性(包含一個字典,由類的數據屬性組成)
doc :類的文檔字符串
name: 類名
module: 類定義所在的模塊(類的全名是'main.className',如果類位于一個導入模塊mymod中,那么 className.module 等于 mymod)
bases : 類的所有父類構成元素(包含了一個由所有父類組成的元組)

print Student.__dict__
print Student.__doc__
print Student.__name__
print Student.__module__
print Student.__bases__
輸出結果:
 {'__module__': '__main__', 'name': 'jack', 'setName': <function setName at 
 0x1096c37d0>, 'age': 18, '__doc__': None, '__init__': <function __init__ at 
 0x1096c3758>}
 None
 Student
 __main__
 ()

五、類的繼承
面向對象的編程帶來的主要好處之一是代碼的重用,實現這種重用的方法之一是通過繼承機制。繼承完全可以理解成類之間的類型和子類型關系。
需要注意的地方:繼承語法 class 派生類名(基類名)://... 基類名寫在括號里,基本類是在類定義的時候,在元組之中指明的。
在python中繼承中的一些特點:
1:在繼承中基類的構造(init()方法)不會被自動調用,它需要在其派生類的構造中親自專門調用。
2:在調用基類的方法時,需要加上基類的類名前綴,且需要帶上self參數變量。區別在于類中調用普通函數時并不需要帶上self參數
3:Python總是首先查找對應類型的方法,如果它不能在派生類中找到對應的方法,它才開始到基類中逐個查找。(先在本類中查找調用的方法,找不到才去基類中找)。
如果在繼承元組中列了一個以上的類,那么它就被稱作"多重繼承" 。
語法:
派生類的聲明,與他們的父類類似,繼承的基類列表跟在類名之后,如下所示:

 class SubClassName (ParentClass1[, ParentClass2, ...]):
     'Optional class documentation string'
     class_suite

 class Parent:  # 定義父類
    parentAttr = 100

    def __init__(self):
        print "調用父類構造函數"

    def parentMethod(self):
        print '調用父類方法'

    def setAttr(self, attr):
        Parent.parentAttr = attr

    def getAttr(self):
        print "父類屬性 :", Parent.parentAttr


 class Child(Parent):  # 定義子類
    def __init__(self):
       print "調用子類構造方法"

    def childMethod(self):
       print '調用子類方法'

c = Child()  # 實例化子類
c.childMethod()  # 調用子類的方法
c.parentMethod()  # 調用父類方法
c.setAttr(200)  # 再次調用父類的方法 - 設置屬性值
c.getAttr()  # 再次調用父類的方法 - 獲取屬性值

六、多繼承

class P1(object):
    def foo(self):
        print 'p1-foo'

class P2(object):
    def foo(self):
        print 'p2-foo'

def bar(self):
    print 'p2-bar'

class C1(P1, P2):
    pass

class C2(P1, P2):
     def bar(self):
         print 'C2-bar'

class D(C1, C2):
     pass

對經典類和新式類來說,屬性的查找順序是不同的。現在我們分別看一下經典類和新式類兩種不同的表現
1、經典類

d = D()
d.foo() # 輸出 p1-foo
d.bar() # 輸出 p2-bar
實例d調用foo()
時,搜索順序是
D = > C1 = > P1
實例d調用bar()
時,搜索順序是
D = > C1 = > P1 = > P2
換句話說,經典類的搜索方式是按照“從左至右,深度優先”的方式去查找屬性。d先查找自身是否有foo方法,沒有則查找最近的父類C1里是否有該方法,如果沒有則繼續向上查找,直到在P1中找到該方法,查找結束。
2、新式類
使用新式類要去掉第一段代碼中的注釋

d = D()
d.foo() # 輸出 p1-foo
d.bar() # 輸出 c2-bar
實例d調用foo()
時,搜索順序是
D = > C1 = > C2 = > P1
實例d調用bar()
時,搜索順序是
D = > C1 = > C2
可以看出,新式類的搜索方式是采用“廣度優先”的方式去查找屬性。

可以調用類的mro屬性來查看查找順序

七、方法重寫
class Parent: # 定義父類
def myMethod(self):
print '調用父類方法'

class Child(Parent):  # 定義子類
    def myMethod(self):
        print '調用子類方法'

c = Child()  # 子類實例
c.myMethod()  # 子類調用重寫方法

單下劃線、雙下劃線、頭尾雙下劃線說明:
foo: 定義的是特殊方法,一般是系統定義名字 ,類似 init() 之類的。
_foo: 以單下劃線開頭的表示的是 protected 類型的變量,即保護類型只能允許其本身與子類進行訪問,不能用于 from module import *
__foo: 雙下劃線的表示的是私有類型(private)的變量, 只能是允許這個類本身進行訪問了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
禁止轉載,如需轉載請通過簡信或評論聯系作者。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,908評論 18 139
  • 寫在之前 因為簡書字數限制,完整版地址:https://www.zybuluo.com/hainingwyx/no...
    hainingwyx閱讀 14,004評論 0 41
  • 前言 人生苦多,快來 Kotlin ,快速學習Kotlin! 什么是Kotlin? Kotlin 是種靜態類型編程...
    任半生囂狂閱讀 26,276評論 9 118
  • 笛聲優雅你的微笑在幽谷里冉冉暈開遠山,晨曦,薄霧Irish色彩 湖上清風搖曳親愛的你在哪里歡快 午后有些倦怠等的人...
    劉小木閱讀 137評論 0 0
  • 前一陣女友間聚會,不知怎地提起了初戀。眾人一致要求我第一個坦白,并說坦白從嚴,抗拒更嚴。為不引起眾怒,我只好投降。...
    小不稀閱讀 394評論 0 4