【python基礎】十一、Python 面向對象 魔術方法

面向對象

內容

  • 對象
  • 屬性 --> 名詞、形容詞:狀態
  • 方法 --> 動詞 :動作

類名 : 首字母大寫 + 駝峯式命名

ValueError TypeError StopIterator

  • 所有的類 繼承 祖宗類: Object類
定義
class Phone(object):    # python2 必須
    pass
class Phone():          # python3 默認object    
    pass
class Phone:            # () 也可以省略
    pass
class XiaoMi(Phone):  # (父類)
    # 屬性
    # 方法

空類 也可 動態添加屬性


  • 區別 類屬性 和 對象屬性
# 定義類和屬性
class Student(object):
    # 類屬性
    name = 'Jam'
    age = 24


s1 = Student()
print(s1.name)  # 首先 判斷 s1 有沒有name 屬性, 沒有 則去 類中 取對應的 類屬性(初始值)
s1.age = 2
print(s1.age)   # 首先 判斷 s1 有沒有age 屬性,此時的 age 屬性 被重新賦值過, 因此它是 s1的 對象屬性

try:
    print(s1.sex)
except AttributeError as ae:
    print(ae, 'and add it!')
    s1.sex = 0  # 新增 對象屬性

# 類屬性 通過類名 使用
Student.name = 'Null'
s2 = Student()
print(s2.name)

  • 類中的方法

    • 普通方法
    • 魔術方法一:
      • 共性特徵
      • 不同於類屬性
    • 類方法
    • 靜態方法
class xxx():
    def __init__(self):
        self.price = 2999   
        
# init 傳值    
class xxx(object):
    def __init__(self, price):
        self.price = price
        
ooo = xxx(35)   # 傳參 實例化   

面向對象實踐:

# cat
class Cat(object):
    type = '貓'
    type_en = 'cat'

    def __init__(self, nickname, age, color):
        self.nickname = nickname
        self.age = age
        self.color = color

    def eat(self, food):
        print('{}喜歡吃{}'.format(self.nickname, food))

    def catch_mouse(self, weight, color):
        print('{} 抓了一隻{}kg的{}老鼠!'.format(self.nickname, weight, color))

    def sleep(self, hour):
        if hour < 5:
            print('需要睡覺!')
        else:
            print('可以工作!')

    def show_info(self):
        print('正在打印 詳細信息')
        print(self.nickname, self.age, self.color)


cat_1 = Cat('花花', 2, '灰色')

cat_1.catch_mouse(0.5, '黑色')
cat_1.sleep(8)
cat_1.eat('小魚乾')

類方法

認識、瞭解 即可

  • 特點:
  1. 定義需要依賴裝飾器
  2. 自動傳入的參數不是對象,是類
  3. 類方法中只可以使用類屬性,不可以使用
  4. 在創建完成類,實例化對象之前,類方法已經寫入類內存
  5. 類方法 不能調用 普通方法 - 同級普通方法可以互相調用
  • 作用

只能訪問類屬性 和 類方法,使用於 需要 創建對象 之前完成的動作,

# 類方法
# 類方法
class Dog(object):
    __age = 2

    def __init__(self, nickname):   # 魔術方法  依賴於self(這個對象)
        self.nickname = nickname

    def run(self):                  # 普通方法 依賴於self
        print('run')

    @classmethod                    # 類方法 前面加 @classmethod
    def test(cls):                  # 自動傳入 cls(這個類)
        __age += 1
        print(cls.__age)
        # print(self.run())
        # print(cls.nickname)       # AttributeError:

Dog.test()
d = Dog('DaHuang')
# Dog.__age
# d.__age
d.run()
d.test(d)

私有變量

class Person():
    __age = 18

靜態方法

class Person():
    __age = 18
    def __init__(self):
        self.name = 'jack'
    
    @staticmethod
    def static_func():
        # 不能訪問 對象屬性 不能出現 self
        # 可以訪問 類屬性,但不通過 cls
        print(Person.__age)
    
  • 靜態方法 與 類方法相似
  1. 由 @staticmethod 定義
  2. 能 通過類名 訪問類屬性
  3. 不能使用 self、cls 參數
  4. 加載時機 同 類犯法
  • 靜態 和 類方法 很少寫到,認識瞭解即可

  • 面試可能會問,讀源碼可能會出現

  • 相同:

  1. 都只能訪問類的屬性和方法,對象的無法訪問
  2. 都可以通過類名調用
  3. 都在對象實例化之前創建 因此不依賴於對象
  • 不同:
  1. 裝飾器不同
  2. 類方法自帶傳入cls參數,靜態方法默認無傳參
  • 普通方法 與 兩者的區別
  1. 普通 無裝飾器
  2. 依賴於對象 self
  3. 只有實例化對象後 才能調用普通方法

魔術方法

魔術方法就是類/對象中的一個方法
區別在於普通方法需要調用
魔術方法是在特定時刻自動觸發

import sys

class MagicFunc():
    param = 'Para'

    def __new__(cls, *args, **kwargs):
        print('__new__')
        """
        實例化:
        系統默認 存在__new__方法 用於 爲實例化對象 申請開闢內存空間
        重寫 __new__ 則不會自動爲新對象開闢新地址,從而導致 __init__ 不被調用
        return 開闢的地址
        """
        r = object.__new__(cls, *args, **kwargs)
        print(r)
        return r

    def __init__(self):
        print('__init__')
        """
        初始化
        對象實例化後,爲其初始化
        """
        print(self)


    def __call__(self, *args, **kwargs):
        print('__call__')   # 將對象當作函數p() 來使用時觸發
        print(*args)

    def __del__(self):
        print('__del__')
        """
        1. 對象賦值
        析構
        :return:
        """
        print(self)

    def __getattr__(self, item):
        pass


mf = MagicFunc()

mf('hello','hi')
mf('hello')# 觸發__call__

mf_c1 = mf # 克隆mf 將內存空間地址賦值
mf_c2 = mf # clone mf



del mf_c1       # 刪除 mf_c1 ,斷開與 mf 的鏈接
del mf_c2
print(sys.getrefcount(mf))      # 查看mf 內存空間 被使用幾次,包含本次


魔術方法 參考

在b站學習中

個人主頁

學習鏈接

歡迎 批評 指正

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章