1. 程式人生 > 其它 >python基礎——8.面向物件

python基礎——8.面向物件

概念

類 例項化 物件 例項
 1.所謂模子就是類 抽象的 能知道有什麼屬性 有什麼技能 但不能知道屬性的具體的值
 2.self裡邊存在字典關係  用self.__dict__來列印驗證
 4.過程
    類名() 首先創造一個物件 穿件一個self變數
    呼叫init方法 雷鳴括號裡的引數會被這裡接收
    執行init方法
    返回self
 5.物件名能做的事
    檢視屬性;
    呼叫方法;
    修改屬性;
 6.類名能做的事
    *呼叫方法 一般不用,需要自己傳self引數,用物件呼叫更省事
    例項化
    呼叫類中的屬性,類屬性,靜態屬性
 7.類名和物件名都能呼叫__dict__的屬性,物件名.__dict__還能修改屬性
 8.類中的靜態屬性可以被類名和物件名呼叫
 9.對於不可變資料型別來說,類變數最好用類名操作
    用物件名操作可變資料型別,比如列表,會造成類靜態變數發生改變
    對於可變資料型別用下標可以對靜態變數進行賦值是成立的,修改是共享的
 10.一個類可以沒有__init__
 11.函式,類名.方法名,物件名.方法名列印的結果
    <function 函式名 at>
    <類名.方法名 at>
    <bound method 類名.方法名 of....>
 12.import package --- 就是類的例項化的過程
 13.組合:一個物件的屬性值是另外一個類的物件
 14.class A               父類 基類 超類
    class A_son(A)        # 父類在兒子類的括號裡    子類,派生類
    class A_son(A,B)      可以多個爸爸
    一個類可以被多個類繼承
    一個類可以繼承多個類    python裡獨有的
    在python3裡所有的類都有父類 沒有父類的類都是obecj的子類,叫新式類
    用.__bases__查父類
    super().__init__()
    super(Dog.jin).eat()

三大特性

# 繼承
    繼承的類是子類,被繼承的類是父類.
    子類能利用父類的屬性和方法,不用重複編寫
    class A:
    class B(A):
# 多型
    python 沒有支援多型的機制,天生支援多型
# 封裝
    廣義上面向物件的封裝:程式碼的保護,面向物件的思想本身就是一種
    只讓自己的物件能呼叫自己類中的方法
    狹義上的封裝 --- 面向物件的三大特性之一
    屬性和方法都隱藏起來 不讓看見
    # 私有方法和私有屬性
        __屬性名 為私有屬性
        用物件名.__dict__可以調到變數,看到的字典格式是_類名__屬性名
        所以,用同樣方法在類外能調到,但是不能這麼幹
        在方法中,返回私有屬性也能得到結果
        def get_pwd(self):
            return self.__passwd
        在類的外部不能定義私有變數
        在方法名前加雙下,同樣也看不見了,私有方法.
        物件的私有屬性,類中的私有方法,類中的靜態私有屬性
        父類的私有屬性不能被子類呼叫

    # java 面向物件程式設計
    # 設計模式 --- 介面
    # 抽象類 python原生支援
    # 介面類 python原生不支援
    from abc import abstractmethod,ABCMeta
    class Payment(metaclass=ABCMeta):   # 元類 預設的元類 type
        @abstractmethod
        def pay(self, money):pass       # 沒有實現這個方法
    # 規範:介面類或者抽象類都可以
    # 介面類 預設多繼承,介面類中的所有的方法都必須不能實現 -- java演化來的
    # 抽象類 不支援多繼承,抽象類中可以有一些程式碼的實現  -- java


屬性和方法

# 屬性可以 檢視 修改 刪除
# 在類內部使用 self.__class attribute設定私有屬性
# 可以訪問到,不合規呼叫方式 _類名.__屬性名
# 父類的私有屬性不能被子類呼叫,私有方法同樣調不到
# 私有屬性在類外邊無法被定義
# 用到私有屬性的場景
  1.隱藏起一個屬性,不想讓類的外部呼叫
  2.想保護這個屬性不被任意修改
  3.保護這個屬性不被子類繼承

# 1.類屬性:類名和物件名都能呼叫類屬性
# 2.普通屬性:類名不能呼叫普通屬性
# 3.私有屬性:只能用物件名._類名__類屬性 呼叫
# 4.類方法(@classmethod):類名和方法名都能呼叫類方法(只涉及靜態屬性就用)
# 5.普通方法:類名在不加self下可以呼叫普通方法(不合法)
# 6.靜態方法(@staticmethod):類名和方法名都能調,不用例項化(既和物件沒關又和類沒關就用)
# 7.屬性方法(@property):類名不能呼叫屬性方法
# 8.內建方法:內建的類方法和內建的函式之間有著千絲萬縷的聯絡
# 9.物件可以呼叫類方法和靜態方法,一般推薦用類名呼叫

類的分類

新式類
經典類
關於init:新式類使用super初始化父類,經典類中直接初始化
關於繼承:新式類多繼承中廣度優先,經典類多繼承中深度優先

反射沒有安全問題

反射物件的屬性
hashattr
getattr
setattr
delattr

isinstance(a, A) 物件是否是類的物件

issubclass(B, A) 是否是子類

類裡的內建方法

repr
可以把列印原封不動的表現出來 1, "1"
str
一定return一個字串

object 裡有一個__str__,一旦被呼叫,就返回呼叫這個方法的物件的記憶體地址

class A:
    pass
a = A()
print(str(a))

每當列印一個物件的時候,其實就是呼叫__str__方法,返回回來。

%s str() 直接列印 實際都是執行的__str__方法

__repr__是__str__備胎,但是反過來不行

str(obj)的時候,實際上是內部呼叫了obj.__str__方法,如果str方法有,那麼它返回的必定是一個str

如果沒有__str__ 會找本類中__repr__方法,再沒有再找父__str__

引用計數?

call 一個物件加上()執行了這個方法