程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

python學習-6-面向對象

編輯:Python

類與實例

  • 創建類的格式:
class Student(object): # class 類名(繼承)
pass
  • init()方法就是java中的構造器
  • 類中的self相當於java中的this,java不用顯示聲明,python中需要在參數列表中聲明
    • 第一個參數一定是self

訪問限制

  • 私有屬性用雙下劃線__開頭,只有內部可訪問 (private)
    • 訪問需要類提供get方法,這和java一樣
      _ 修改就需要set方法
    • 實際上,並不是私有的,只是python解釋器給屬性改了一個名,變為._類名__屬性名
  • python中雙下劃線開頭與結尾的,都是特殊變量,一般不能用
  • 發現個好玩的,即使類中沒有的屬性,也是可以xx.xx = xx進行設置的,然後就可以使用了

繼承

  • 繼承會引發多態
    • 子類是父類,父類不是子類
    • 調用方只管調用,不管細節,無需知道子類型,從而盡可能滿足開閉原則
  • java是靜態語言,它在進行編譯的時候就要來檢查傳入對象的類型是否合法
  • Python是動態語言,不需要保證類型完全,只需要它有本方法中需要的方法和屬性就ok了
    • 鴨子類型,無需嚴格繼承,只要 看起來像鴨子,走起來也像鴨子 就ok

對象信息

  • type(obj) 類型,指向函數
    • type(obj)
    • if type(xxx) == type(已知類型)
    • if type(xxx) == types.FunctionType 判斷是否是函數…
  • instance(obj,已知類型) 判斷類型是否相等
    • 返回True or False
    • 可用於繼承
    • 判斷是否是其中一種 instance(obj,(xxx,xxx))
  • dir(obj) 將所有方法 屬性 字符串列表返回
  • len(obj) 獲取對象的長度
    • 自動調用__len__()方法
    • 可以被復寫
  • hasattr(obj,“xxx”) 是否擁有某種屬性
    • 注意是字符串
  • getattr(obj,“xxx”,404) 最後一個參數是默認值,防止不存在報錯
    • 方法和屬性都是一樣的,都用這個
  • setattr(obj,“xxx”,xx)
  • 結合上面的鴨子類型,可以使用對象信息來判斷是否像鴨子
    • if hasattr(obj,“xxx”): …

實例屬性與類屬性

  • 實例可以任意綁定屬性
    • 類沒有定義name屬性,但我可以 實例.name=xxx,然後用

slots

  • 作為動態語言,python可以給實例綁定方法與屬性
  • 而給類動態的綁定,則可以對每個實例都適用,具體操作和實例的綁定一樣
  • 為了限制綁定,需要__slots__
    • 其作為一個變量,可以定義 允許綁定的 屬性名稱
    • 其他屬性是不能夠綁定的
    • 對繼承的子類無效

@property

  • 一般的屬性都是不對外暴露的,所以需要getter方法,setter方法
    • 這樣使用起來就很麻煩
  • 所以實際上可以使用 @property 來讓get方法變成屬性,然後使用 @屬性.setter 注解setter方法
class Stu(Object):
@property
def score(self): # 該注解下就是屬性名稱
return self.__score
@score.setter
def score(self,val):
self.__score = val
  • 此時就可以直接 xx.屬性 進行賦值與調用,不用寫get賦值了,方便很多
 xx = Stu()
xx.score = css
print(xx.score)
  • 原理是裝飾器
  • 注意 屬性的方法名不要與 實際的屬性名 相同
    • 如果相同,會發生 自環,從而導致無限遞歸,最終棧溢出
  • 注意這裡的無論啥方法,名稱都要統一,也就是你 注解定義了score,那麼所有的方法也得叫score

多重繼承

  • 多個類別交叉時,就會造成 類的層次復雜
  • 這點區別於java,java是單繼承,然後使用接口來進行擴展
class Bat(Mammal,FlyableMixIn,XxxMinIn):
pass
  • 同時繼承多個父類的功能
  • 我們可以把繼承的第一個類叫做主線,其他額外混入的類,稱為MixIn

定制類

  • str() 打印實例信息,直接print即可,可自定義
  • repr() 打印實例信息,為調試服務
  • iter() 實現該方法,返回一個迭代對象,該類可用於 for…in,變成一個Iterable對象
    • 一般還要搭配一個__next__()方法來
  • getitem()可以將類當成list來使用,按下邊訪問元素
  • getattr()當有屬性找不到時,python解釋器就會調用該方法
  • call(),把實例對象當方法使用 xxx() 將對象看做是函數

枚舉類

from enum import Enum
@unique #檢查有無重復值
class Weekday(Enum):
Sun = 0
Mon = 1
...
print(Weekday.Mon) # 1

元類

from hello import Hello
h = Hello()
h.hello()
  • 其中,Hello是一個class,它的類型是type
  • h是Hello的實例,它的類型是Hello
  • type()可以返回一個實例的類型: type(obj)
  • type()也可以創建新的類型,此時就不需要再 class Hello(object)之類的麻煩定義
  • type(class名稱,基繼承的父類集合(tuple,),方法名)
def function(self): # 這裡的self必須要有,因為要建類
print("ok")
Hello = type("Hello",(object,),dict(hello=function))
h = Hello()
h.hello()
  • metaclass 元類
    • 對於類,首先我們定義類,然後創建實例
    • metacalss是類的元,先定義metaclass,然後創建類,然後創建實例
    • 類是metaclass的實例
    • 基本不會用,這個太抽象了,魔術代碼

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved