天天看點

類及對象初體驗

一、類建立

class Animal:

    def setName(self,name):
        self.name=name

    def getName(self):
        return self.name

#建立動物貓的對象
cat=Animal()
cat.setName("cat")
#調用cat對象的屬性name
print(cat.name)
#調用cat方法的getName方法
print(cat.getName())
#調用cat方法的getName方法 另一種方式
print(Animal.getName(cat))      
  • 類的建立使用關鍵字class定義,類名跟在class之後
  • 類中的方法就是函數
  • 每一個方法中的第一個參數都是self,如果方法中有多個參數,第一個參數将作為self參數使用,在調用方法時,這個參數不用自己傳入,系統會将方法所屬的對象傳入這個參數。
  • 調用對象方法的方式有兩種,一種是直接通過對象調用;另一種是通過類調用,并且傳入相應的對象。

 二、方法的私有化

  在Java這類語言中提供了private關鍵字,進行方法或者變量的私有化,但是在python中并沒有提供,不過可以使用其它方式來達到這種效果,在python類的方法名前面加上“__”,可以杜絕外部通路這個類中的方法。

class FOO:

    def f1(self):
        return "我是f1"

    def __f2(self):
        return "我是f2"

    #類的内部是可以調用私有方法的
    def f3(self):
        return self.__f2()

f=FOO()
f.f1()
f.__f2() #AttributeError: 'FOO' object has no attribute '__f2'      

  可以看到f2是私有方法,類外部不能進行通路,否則會抛出異常,而在類的内部是可以調用私有方法的。

  f2是否是真的在類外部不能調用了呢?當然不是,實際上python編譯器遇到"__"開頭的方法會将方法名變成“_ClassName__MethodName”,照着這種形式調用,是可行的。

...

print(f._FOO__f2())#我是f2

...      

  另外,如果想檢視類中的所有方法,應該如何做呢?

import inspect
methods=inspect.getmembers(f,predicate=inspect.ismethod)
print(methods)#[('_FOO__f2', <bound method FOO.__f2 of <__main__.FOO object at 0x0000000000676F28>>), 
        #('f1', <bound method FOO.f1 of <__main__.FOO object at 0x0000000000676F28>>), 
        #('f3', <bound method FOO.f3 of <__main__.FOO object at 0x0000000000676F28>>)]      

三、類的繼承

  類的繼承就是一個類從另一個類中獲得所有的成員,父類的成員可以在子類中使用。建立的類可以繼承一個或多個父類(python支援多繼承),父類又可稱為基類或超類,建立的類稱為派生類或子類。

class A:
    pass

class B:
    pass

class C(A): #單繼承 C是派生類,A是基類
    pass

class D(A,B):#多繼承,繼承多個類,中間以逗号分隔開
    pass      

  D類中會按照從左到右的順序繼承A類、B類中的成員,如果多個父類中有相同的成員,會按照父類書寫的順序繼承,也就是說前面的父類會覆寫寫在後面父類同名的方法。

四、檢測繼承關系

  有時需要判斷類與類之間是否有繼承關系,這樣可以利用父類中的方法,那麼這種繼承關系應該如何判斷呢?可以使用issubclass函數進行判斷,它接收2個參數,第一個是子類,第二個是父類,如果是繼承關系傳回True,否則傳回False,間接的繼承關系也是适用的。

class Fruits:
    pass

class Apple(Fruits):
    pass

print(issubclass(Apple,Fruits))#True      

   如果擷取已知類的父類們,可以直接使用"__bases__",這是類的一個特殊屬性

class Fruits:
    pass

class Apple(Fruits):
    pass

print(Apple.__bases__)#(<class '__main__.Fruits'>,)      

五、類、類成員、對象的判斷

a、hasattr()

判斷對象或者類中是否存在某個成員

class Bar:

    def f1(self):
        pass
b=Bar()
print(hasattr(b,"f1"))#True
print(hasattr(Bar,"f1"))#True      

b、getattr()

擷取類中或對象中成員的值,它有三個參數第三個參數用于制定預設值

class Bar:

    def f1(self):
        pass
b=Bar()

print(getattr(Bar,"f1"))#<function Bar.f1 at 0x0000000000535BF8>      

c、setattr()

用于設定對象中成員的值,setattr函數有三個參數,前兩個與getattr相同,第三個參數用于指定成員的值

#如果對象中有name屬性,則更新該值,如果沒有,會添加一個新的name屬性,也可以更新或者添加類屬性
setattr(b,"name","bright")
print(b.name)#bright      

動态添加函數

class Bar:

    def f1(self):
        pass
b=Bar()

####類添加f2函數####
def f2():
    print("動态添f2")
setattr(Bar,'f2',f2)
Bar.f2()  #類調用

####對象添加f2函數###
def f2():
    print("動态添f2")
setattr(b,'f2',f2)
b.f2()  #對象調用      

d、isinstance

用于判斷執行個體和類之間的關系

class A:
    print("A")

class B(A):
    print("B")

a=A()
b=B()

print(isinstance(a,A))#True
print(isinstance(b,A))#True      

 六、多态

同類對象的多種形态,應用多态增加了程式的靈活性、擴充性。

實作多态的步驟:

  • 定義新的子類
  • 重寫對應的父類方法
  • 使用子類的方法直接處理,不調用父類的方法
class Animal:

    def eat(self):
        pass

    def run(self):
        pass

class Dog(Animal):

    def run(self):
        pass      

簡單的來說,Dog是新定義的子類,不想調用父類的run方法,需要執行自己的run方法,這就是多态,一個類産生的多個對象,調用同一個方法,産生不同的執行結果。

作者:iveBoy

出處:http://www.cnblogs.com/shenjianping/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須在文章頁面給出原文連接配接,否則保留追究法律責任的權利。

上一篇: 裝飾器
下一篇: restful規範