Python學習筆記《Python核心編程》第13章 面向對象編程


類:

    類與函數的聲明很相似,如下:

class ClassName(object):

      'class documentation string'      #類文檔字符串

      class_suite                       #類體

類屬性:         

 class c(object);

       foo = 100                #類屬性,也就是靜態屬性,直接通過類名引用,不通過過實例

 print c.foo                    # 100

類方法:

 class MyClass(object):

        def myNoActionMethod(self):

            pass

 mc = MyClass()

 mc.myNoActionMethod()         #必須通過實例調用方法

特殊的類屬性:

     對於任何類C,顯示如下:

     C.__name__           類C的名字(string)

     C.__doc__             類C的文檔字符串

     C.__bases__          類C的所有父類構成元素(包含了以個由所有父類組成的元組)

     C.__dict__             類C的屬性(包含一個字典,由類的數據屬性組成) 

     C.__module__        類C定義所在的模塊(類C的全名是'__main__.C',如果C位於一個導入模塊mymod中,那么C.__module__ 等於 mymod)

     C.__class__           實例C對應的類

實例:

     如果類是一種數據結構定義類型,那么實例則聲明了以個這種類型的變量。實例是有生命的類。  通過調用類對象來創建實例。     

     __init__() “構造器”方法(相當於構造函數),在類調用實例化的時候檢查是否有__init__方法,如果有就調用它。__init__應當返回None

     __new__() ....? 與樓上的有啥區別?

     __del__() "解構器"方法,該函數要直到該實例對象所有的引用都被清除掉后才會執行。解構器只能被調用一次,一旦引用計數為0,則對象就被清除了

實例屬性:設置實例的屬性可以再實例創建后任意時間進行;內建函數dir()可以顯示類屬性,也可以顯示實例屬性。

特殊的實例屬性,任意對象I

I.__class__                      實例化I的類

I.__dict__                       I的屬性,內建類型不存在__dict__屬性,內建類型:int  float complex....

類屬性與實例屬性

      類屬性通過 類名.屬性名 來訪問,也可以通過  實例名.屬性名 來訪問,但是類屬性只能通過類來更新(不可變對象),如果給這個實例同一個屬性賦值

這會在這個實例上面增加這個屬性,不會影響類屬性。

靜態方法和類方法:

      staticmethod() 和  classmethod() 內建函數: 

class TestStaticMethod:
    def foo():
        print 'calling static method foo()'        
    foo = staticmethod(foo)

class TestClassMethod:
    def foo(cls):
        print 'calling class method foo()'
        print 'foo() is part of class:',cls.__name__
    foo = classmethod(foo)

tsm = TestStaticMethod()
TestStaticMethod.foo()    # calling static method foo()
tsm.foo()                 #calling static method foo()

tcm = TestClassMethod()
TestClassMethod.foo()     #calling class method foo\n  foo() is part of class: TestClassMethod
tcm.foo()                 # 同上

使用函數修飾符:

     除了上面的使用內建方法外,還可以使用函數修飾符如下:

class TestStaticMethod:
    @staticmethod
    def foo():
        print 'calling static method foo()'        

class TestClassMethod:
    @classmethod
    def foo(cls):
        print 'calling class method foo()'
        print 'foo() is part of class:',cls.__name__

tsm = TestStaticMethod()
TestStaticMethod.foo()   # calling static method foo()
tsm.foo()    #calling static method foo()

tcm = TestClassMethod()
TestClassMethod.foo()     #calling class method foo\n  foo() is part of class: TestClassMethod
tcm.foo()    # 同上

子類和派生:

     創建子類: 括號里面是父類,如果沒有從任何祖先類派生,可以使用object作為父類的名字。                

class SubClassName(ParentClass1[,ParentClass2,...]):

      'optional class documentation string'

      class_suite

__bases__類屬性:對於任何子類,它是以個包含其父類的集合的元組。沒有父類的類,他們的__bases__屬性為空。

在子類方法中調用父類同名方法:

class P(object):    #父類

    def foo(self):

    print 'Hi, I am P-foo()'

class C(P):         #子類,繼承父類P

    def foo(self):

    P.foo(self)     #調用父類同名方法

    print 'Hi, I am C-foo()' 

super()內建方法:super()不但能找到基類方法,而且還為我們傳進self,如下:

class C(p):
    def foo(self):
        super(C,self).foo()   #調用C基類方法,自動查找C的基類
        print 'Hi,I am C-foo()'

從標准類型派生:

    a.不可變類型的例子:

class RoundFloat(float):
     def __new__(cls,val):  #覆蓋float中的__new__
          return float.__new__(cls,round(val,2))  #  也可以 return super(RoundFloat,cls).__new__(cls,round(val,2))

    b. 可變類型的例子:

class SortedKeyDict(dict):
    def keys(self):
        return sorted(super(SortedKeyDict,self).keys())

c = SortedKeyDict({'zheng-cai':67,'hui-jun':68,'xin-yi':2})
>>> c.keys()
['hui-jun', 'xin-yi', 'zheng-cai']
>>> print [key for key in c]
['zheng-cai', 'xin-yi', 'hui-jun']

多重繼承:

     python允許類繼承多個基類,即多重繼承。

     經典類繼承使用深度優先,新式類采用廣度優先查找屬性,新式類有一個__mor__屬性,顯示繼承的查找順序。 

 類、實例和其他對象的內建函數

        issubclass(sub,sup): 判斷一個類是另一個類的子類或者子孫類,如果是就返回True,第二個參數可以使可能父類組成的元組,只要第一個參數是其中給定元組中任何一個候選類的子類時,就返回True。

        isinstance(obj1,class1):判斷一個對象是否是另一個給定類的實例.是就返回True。第二個參數應當是類。

        hasattr()\getattr()\setattr()\delattr() ------ 系列函數可以在各種對象下工作,不限於類和實例。操作obj.attr時就相當於調用*attr(obj,'attr')系列函數。 

class myClass(object):
    def __init__(self):
        self.foo = 100
        
 myInst = myClass()
 hasattr(myInst,'foo')
#True
 getattr(myInst,'foo')         #100
setattr(myInst,'bar',200)
getattr(myInst,'bar')          #200
delattr(myInst,'bar')
hasattr(myInst,'bar')         #False

dir(): 作用在實例上時,顯示實例變量,還有實例所在的類及所有它的基類中定義的方法和類屬性;作用在類上時,則顯示類以及它的所有基類的__dict__中的內容。作用在模塊上時,則顯示模塊的__dict__的內容。不帶參數時,則顯示調用者的局部變量。

super(type[,obj]) 函數:幫助找出相應的父類,然后方便調用相關的屬性;super(MyClass,self).__init__()。

var()函數:與dir()類似。

類,實例及其他對象的內建函數

issubclass(sub,sup)     如果類sub是類sup的子類,則返回True,反之為False
isinstance(obj1,obj2)  如果實例obj1是類obj2或者obj2子類的一個實例;或者obj1是obj2的類型,則返回True;反之為Fasle
hasattr(obj,attr)    如果obj有屬性attr(用字符串給出),返回True,反之,返回False
getattr(obj,attr[,default])   獲取obj的attr屬性;與返回obj.attr類似;如果attr不是obj的屬性,如果提供了默認值,則返回默認值;不然就會引發一個異常 
setattr(obj,attr,val)  設置obj的attr屬性值為val,替換任何已純在的屬性值;不然就創建屬性;類似obj.attr = val
delattr(obj,attr)   從obj中刪除屬性attr,類似於del obj.attr
 dir(obj= None)    返回obj的屬性的一個列表;如果沒有給定obj,dir()則顯示局部名字空間中的屬性,也就是locals().keys()
 super(type,obj=None)  返回一個表示父類類型的代理對象;如果沒有傳入obj,則返回的super對象是非綁定的,反之,如果是以個type,issubclass(obj,type)必為True;否者isinstance(obj,type)就必為True
 vars(obj=None)     返回obj的屬性及其值的一個字典;如果沒有給出obj,vars()顯示局部名字空間字典,也就是locals()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM