面向對象
內容
- 類
- 對象
- 屬性 --> 名詞、形容詞:狀態
- 方法 --> 動詞 :動作
類名 : 首字母大寫 + 駝峯式命名
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('小魚乾')
類方法
認識、瞭解 即可
- 特點:
- 定義需要依賴裝飾器
- 自動傳入的參數不是對象,是類
- 類方法中只可以使用類屬性,不可以使用
- 在創建完成類,實例化對象之前,類方法已經寫入類內存
- 類方法 不能調用 普通方法 - 同級普通方法可以互相調用
- 作用
只能訪問類屬性 和 類方法,使用於 需要 創建對象 之前完成的動作,
# 類方法
# 類方法
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)
- 靜態方法 與 類方法相似
- 由 @staticmethod 定義
- 能 通過類名 訪問類屬性
- 不能使用 self、cls 參數
- 加載時機 同 類犯法
-
靜態 和 類方法 很少寫到,認識瞭解即可
-
面試可能會問,讀源碼可能會出現
-
相同:
- 都只能訪問類的屬性和方法,對象的無法訪問
- 都可以通過類名調用
- 都在對象實例化之前創建 因此不依賴於對象
- 不同:
- 裝飾器不同
- 類方法自帶傳入cls參數,靜態方法默認無傳參
- 普通方法 與 兩者的區別
- 普通 無裝飾器
- 依賴於對象 self
- 只有實例化對象後 才能調用普通方法
魔術方法
魔術方法就是類/對象中的一個方法
區別在於普通方法需要調用
魔術方法是在特定時刻自動觸發
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 內存空間 被使用幾次,包含本次