面向?qū)ο蟮某绦蜷_發(fā)
"""
用幾大特征表達(dá)一類事物稱為一個類,類更像是一張圖紙,表達(dá)的是一個抽象概念
對象是類的具體實(shí)現(xiàn),更像是由這圖紙產(chǎn)出的具體物品,類只有一個,但對象可以通過這個類實(shí)例化出多個
對象是類的實(shí)例,類是對象的模板
*類中的成員只有方法和屬性,不要裸露的把判斷和循環(huán)直接寫在類中,而是用方法包起來
(1)類的定義
(2)類的實(shí)例化
(3)類的基本結(jié)構(gòu)
(4)類的命名
"""
1. 類的定義
# 1
class Car:
pass
# 2 推薦
class Car():
pass
# 3.
class Car(object):
pass
2. 類的實(shí)例化
class Car():
pass
obj = Car()
print(obj)
3. 類的基本結(jié)構(gòu)
"""
類中兩樣?xùn)|西:
(1)成員屬性
(2)成員方法
"""
class Car():
# 成員屬性
color = "白色"
# 成員方法
def didi():
print("小車會滴滴的叫")
# 語法上不報(bào)錯,但是嚴(yán)禁使用,破壞了類中的結(jié)構(gòu),不要裸露的把判斷和循環(huán)直接寫在類中,而是用方法包起來
class Car():
if 5 ==5 :
print(11223344)
4. 類的命名
"""類的命名 : 推薦使用大駝峰命名法,每個單詞的首字母都要大寫"""
"""
mycar => MyCar
zhangbaozhang => ZhangBaoZhang
"""
面向?qū)ο笕筇卣? 封裝 繼承 多態(tài)
封裝
對類中成員屬性和方法的保護(hù),控制外界對內(nèi)部成員的訪問,修改,刪除等操作
對象的操作
"""
封裝:
1.私有 : 在類內(nèi)可以互相訪問,在類外不能訪問
2.公有 : 在類內(nèi)或者類外都可以訪問
類中成員:
1.成員屬性
2.成員方法
綁定方法:
1.綁定到對象 : 當(dāng)對象去調(diào)用類中成員方法時(shí),系統(tǒng)會默認(rèn)把該對象當(dāng)成參數(shù)傳遞給該方法
2.綁定到類 : 當(dāng)對象或者類去調(diào)用類中成員方法時(shí),系統(tǒng)會默認(rèn)把該類當(dāng)成參數(shù)傳遞給該方法
使用方式:
對象.成員屬性
對象.成員方法
"""
class MyCar():
# 公有屬性
logo = "布加迪威龍"
# 私有屬性, 前面加兩個下劃線
__price = "2000萬"
# 公有方法
def run(self): # 必須要寫上一個形參。調(diào)用時(shí)自動傳參(強(qiáng)制操作)
print("百公里油耗300L,logo={} , price={}".format(self.logo, self.__price))
# 私有方法
def __info(self):
print("車主信息保密,據(jù)說是某個房地產(chǎn)大佬的兒子")
# 實(shí)例化對象(類的實(shí)例化)
obj = MyCar()
# (1)實(shí)例化的對象訪問成員屬性和方法
# 公有
print(obj.logo)
obj.run()
# 私有 (私有成員無法在類外訪問,類內(nèi)可以)
# obj.__price # error
# obj.run()
# obj.__info() # error
#(2)實(shí)例化的對象動態(tài)添加公有成員屬性
obj.color = "黃色"
obj.logo = "五菱宏光"
print(obj.color)
print(obj.logo)
# __dict__ 獲取類對象的內(nèi)部成員
print(obj.__dict__)
print(MyCar.__dict__)
#(3)實(shí)例化的對象動態(tài)添加公有成員方法
# 1.無參方法 (類外定義的方法,不會強(qiáng)制傳參)
def dahuangfeng():
print("請加我大黃蜂")
obj.dahuangfeng = dahuangfeng
obj.dahuangfeng()
# 2.有參方法
# 基本版
def qingtianzhu(name):
print("請叫我一柱擎天么,{}".format(name))
obj.qingtianzhu = qingtianzhu
obj.qingtianzhu("擎天柱")
# 升級版
def qingtianzhu(obj,name):
print("請叫我一柱擎天么,{},我的顏色是{}".format(name,obj.color))
obj.qingtianzhu = qingtianzhu
obj.qingtianzhu(obj,"擎天柱")
# 究極版
"""如果要創(chuàng)建綁定方法,參數(shù)的順序,self對象本身要放到第一位."""
def qingtianzhu(obj,name):
print("請叫我一柱擎天么,{},我的顏色是{}".format(name,obj.color))
import types
# 創(chuàng)建綁定方法,系統(tǒng)自動把該對象當(dāng)成參數(shù)傳遞給方法;
# types.MethodType(方法,對象) => 綁定方法
res = types.MethodType(qingtianzhu,obj)
print(res) # <bound method qingtianzhu of <__main__.MyCar object at 0x77>>
# 自動將obj作為參數(shù)傳給該方法
obj.qingtianzhu = types.MethodType(qingtianzhu,obj)
obj.qingtianzhu("擎天柱")
# 3.lambda表達(dá)式
obj.weizhentian = lambda : print("我是威震天")
obj.weizhentian()
類的操作
"""
使用方式:
類.成員屬性
類.成員方法
"""
class MyCar():
# 公有成員屬性
platenum = "京A7758BB"
# 私有成員屬性
__earning = "月收入6000"
# 公有成員方法
def car_info():
print("牌照信息可以公開")
print("<======>")
MyCar.__money_info()
# 私有成員方法
def __money_info():
print( "收入信息保密" , MyCar.__earning )
# (1)定義的類訪問公有成員屬性和方法
print(MyCar.platenum)
MyCar.car_info()
# MyCar.__money_info() error
# (2)定義的類動態(tài)添加公有成員屬性
MyCar.oil = "1000L"
print(MyCar.oil)
print(MyCar.__dict__)
# (3)定義的類動態(tài)添加公有成員方法
# 1.無參方法
def car_light():
print("我是造車燈的方法")
MyCar.car_light = car_light
MyCar.car_light()
# 2.有參方法
def car_engine(name):
print("我是造{}發(fā)動機(jī)的方法".format(name))
MyCar.car_engine = car_engine
MyCar.car_engine("三缸發(fā)動機(jī)")
# 3.lambda表達(dá)式
MyCar.luntai = lambda : print("我是造輪胎的方法")
MyCar.luntai()
# 對比 對象和類之間的不同
"""
1.類中的無參方法默認(rèn)只能類來調(diào)用,對象無法調(diào)取
2.對象可以調(diào)用類中的成員,反過來,類不能調(diào)用對象中的成員
3.每創(chuàng)建一個對象都會在內(nèi)存中占用一份空間,對象之間是彼此獨(dú)立的;
"""
obj = MyCar()
# obj.car_info() error
MyCar.car_info()
obj.price = "10萬"
print(MyCar.price)
如何在類外訪問私有成員
class Plane():
# 公有成員
captian = "趙沈陽"
# 私有成員
__air_sister = "3名空姐"
# 公有綁定方法
def fly(self):
print("飛機(jī)要非要平流層,才能減少震動",self.__air_sister)
# 私有綁定方法
def __age(self):
print("空姐年齡保密")
# 公有無參方法
def fly2():
print("航天飛機(jī)飛到天空層,翱翔太空")
# 私有無參方法
def __earn():
print("機(jī)長的收入保密")
def pub_get1(self):
print(self.__air_sister)
self.__age()
def pub_get2():
print(Plane.__air_sister)
Plane.__earn()
# 實(shí)例化對象
obj = Plane()
# 方法一.訪問私有成員 (不推薦)
# python私有化: 采取了改名策略 => _類名 + __air_sister
# print(obj.__air_sister) # 報(bào)錯
print(obj._Plane__air_sister)
print(Plane.__dict__)
# 方法二.訪問私有成員 (使用類中的公有方法,間接訪問私有成員) (推薦)
obj = Plane()
obj.pub_get1()
Plane.pub_get2()
使用類對象刪除相應(yīng)的成員
"""
1.對象可以訪問類中的公有成員,但是無權(quán)修改或者刪除該類中的成員
2.對象在訪問成員時(shí),優(yōu)先訪問該對象自己的成員,如果沒有在訪問類的,類如果也沒有直接報(bào)錯;
"""
# 刪除對象成員屬性
obj.captian = "趙世超"
del obj.captian
print(obj.captian)
# 刪除對象成員方法
obj.basketball = lambda : print("我的私人飛機(jī)可以在天上打籃球")
print(obj.__dict__)
obj.basketball()
del obj.basketball
print(obj.__dict__)
# obj.basketball() # error
# 刪除類中成員屬性
del Plane.captian
print(Plane.__dict__)
# Plane.captian # error
# print(obj.captian) # error
# 刪除類中成員方法
del Plane.fly2
# Plane.fly2() # error
# 注意: 對象無法調(diào)無參方法!! 反過來,類可以調(diào)用對象的綁定方法么? 可以!!
Plane.fly(obj)
__init__ 構(gòu)造方法
'''
觸發(fā)時(shí)機(jī):實(shí)例化對象,初始化的時(shí)候觸發(fā)
功能:為對象添加成員
參數(shù):參數(shù)不固定,至少一個self參數(shù)
返回值:無
'''
# (1) 基本語法
class MyClass():
def __init__(self):
print("構(gòu)造方法被觸發(fā) ... ")
self.color = "屎黃色"
# 實(shí)例化對象
obj = MyClass()
print(obj.__dict__)
print(obj.color)
# (2) 帶有多個參數(shù)的構(gòu)造方法
class MyClass():
def __init__(self,color):
self.color = color
# 實(shí)例化對象
obj1 = MyClass("狗屎綠")
print(obj1.color)
obj2 = MyClass("粉嫩紅")
print(obj2.color)
# (3)類可以是一個,對象可以是多個,創(chuàng)造的對象彼此是獨(dú)立的;
class Children():
def __init__(self,name,skin):
self.name = name
self.skin = skin
def cry(self):
print("小孩一下生久哇哇哇的哭")
def la(self):
print("小孩一下生久拉粑粑")
def __eat(self):
print("小孩一下生就要吃奶奶..")
def info(self):
print("小孩的名字:{},小孩的膚色{}".format(self.name,self.skin))
def info2(self,name,skin):
print("小孩的名字:{},小孩的膚色{}".format(name,skin))
# 實(shí)例化對象
afanda = Children("阿凡達(dá)","深藍(lán)色")
afanda.cry()
afanda.info()
haoke = Children("綠巨人","綠色的")
haoke.la()
haoke.info()
wangbaoqiang = Children("王寶強(qiáng)","亮綠色")
wangbaoqiang.info()
# wangbaoqiang.__eat() error
wangbaoqiang.info2("張保張","黃色")
繼承
"""
一個類除了自身所擁有的屬性方法之外,還獲取了另外一個類的成員屬性和方法 是一種繼承關(guān)系
被繼承的類叫做父類(基類,超類),繼承的類叫做子類(衍生類)
在python中所有類都繼承object這個父類
繼承: (1) 單繼承 (2) 多繼承
"""
單繼承
class Human(object):
eye = "黑色的"
def jump(self):
print("古代人類都能上樹")
def beat_animal(self):
print("古代人類都會打獵")
def __makefire(self): # 只能在本類內(nèi)部調(diào)用
print("古代人類會生火")
# (1) 子父繼承之后,子類可以調(diào)用父類的公有成員
class Man(Human):
pass
obj = Man()
obj.jump()
# (2) 子父繼承之后,子類不能調(diào)用父類的私有成員
class Woman(Human):
def pub_func(self):
self.__makefire()
obj2 = Woman()
# obj2.__makefire() # 報(bào)錯 不行
# obj2.pub_func() # 報(bào)錯 不行 __makefire 方法調(diào)用失敗
# (3) 子父繼承之后,子類可以重寫父類的同名公有方法
class Children(Human):
def beat_animal(self):
print("小孩天生只會打泡泡,不會打獵")
obj3 = Children()
obj3.beat_animal()
多繼承
# (1) 基本語法
class Father():
property = "風(fēng)流倜儻,才華橫溢,玉樹臨風(fēng),才高八斗,學(xué)富五車,英姿灑窗"
def f_hobby():
print("抽煙喝酒燙頭")
class Mother():
property = "傾國傾城,貌美如花,沉魚落雁,閉月羞花,婀娜多姿,如花似玉"
def m_hobby(self):
print(self.property)
print("讀書看報(bào)")
class Daughter(Father,Mother):
pass
obj = Daughter()
print(obj.property) # 存在順序關(guān)系
obj.m_hobby()
# (2) 多繼承的成員調(diào)用
class Father():
property = "風(fēng)流倜儻,才華橫溢,玉樹臨風(fēng),才高八斗,學(xué)富五車,英姿灑窗"
def f_hobby():
print("抽煙喝酒燙頭")
class Mother():
property = "傾國傾城,貌美如花,沉魚落雁,閉月羞花,婀娜多姿,如花似玉"
def m_hobby(self):
print(self.property)
print("讀書看報(bào)")
"""
(1)super本身是一個類 super()是一個對象 用于調(diào)用父類的綁定方法
(2)super() 只應(yīng)用在綁定方法中,默認(rèn)自動傳遞self對象 (前提:super所在作用域存在self)
(3)super用途: 解決復(fù)雜的多繼承調(diào)用順序
"""
class Son(Father,Mother):
property = "打游戲,吃小零食"
def m_hobby(self):
print("son中m_hobby方法")
# 用類調(diào)用成員
def skill1(self):
Father.f_hobby()
print(Mother.property)
# 用對象調(diào)用成員
"""self按照順序找: 對象本身 => 類 => 父類 對應(yīng)的成員 """
def skill2(self):
print(self.property)
self.m_hobby()
# 用super調(diào)用成員
"""super()只調(diào)用父類的相關(guān)成員,順帶傳遞對象參數(shù)。不調(diào)用自己的"""
def skill3(self):
print(super()) # <super: <class 'Son'>, <Son object>>
print(super().property)
super().m_hobby()
obj2 = Son()
# obj2.skill1()
obj2.property = "喜歡看lol,dnf,wow,跑跑卡丁車,ddo,霸王大陸,澄海3"
# obj2.skill2()
obj2.skill3()
菱形繼承 (鉆石繼承)
class Human():
pty = 1
def feelT(self):
print("古代人類,天熱了,光腚1")
print(self.pty) # 4 3 2 1
print("古代人類,天冷了,穿樹衣2")
class Man(Human):
# pty = 2
def feelT(self):
print("男人,天熱了,光膀子3")
print(super(),"<==2==>") # <super: <class 'Man'>, <Children object>>
super().feelT()
print("男人,天冷了,光腚4")
class Woman(Human):
# pty = 3
def feelT(self):
print("女人,天熱了,脫毛5")
print(super(),"<==3==>") # <super: <class 'Woman'>, <Children object>>
super().feelT()
print("女人,天冷了,穿貂6")
class Children(Man,Woman):
# pty = 4
def feelT(self):
print("小孩,天熱了,光腚7")
print(super(),"<==1==>") # <super: <class 'Children'>, <Children object>>
super().feelT() # 將super() 對象傳給feelT() 方法
print("小孩,天冷了,多喝熱水8")
# ### super的深層理解
obj = Children()
obj.feelT()
# 73512648
"""
# 菱形繼承 查找方法解析原則:super() 調(diào)用時(shí)查找順序
# mro: 方法解析順序 (c3算法計(jì)算的)
# 語法: 類.mro() => 列表
m :method
r :resolution
o :order
super 會自動根據(jù)mro列表返回出來的順序關(guān)系,依次調(diào)用
super作用:專門用于解決復(fù)雜的多繼承調(diào)用順序關(guān)系;依照mro返回的列表順序,依次調(diào)用;
super調(diào)用的順序:會按照c3算法的廣度優(yōu)先原則進(jìn)行調(diào)用
super傳參:會默認(rèn)在調(diào)用方法時(shí),傳遞該對象參數(shù);
"""
lst = Children.mro()
print(lst)
"""
[
<class '__main__.Children'>,
<class '__main__.Man'>,
<class '__main__.Woman'>,
<class '__main__.Human'>,
<class 'object'>
]
"""
內(nèi)置函數(shù) issubclass
與isinstance
issubclass
判斷類的子父關(guān)系(應(yīng)用在類與類之間)
class MyClass():
pass
"""只要在一條繼承鏈上滿足關(guān)系即可"""
res = issubclass(Children,Man)
res = issubclass(Children,Human)
res = issubclass(Children,MyClass) # False
# 如果元組當(dāng)中有一個父類滿足,即返回真
res = issubclass(Children, (Man,Human,MyClass) )
print(res) # True
isinstance
判斷對象的類型 (應(yīng)用在類與對象之間)
"""只要在一條繼承鏈上滿足關(guān)系即可"""
res = isinstance(obj,Children) # True
res = isinstance(obj,Human) # True
res = isinstance(obj,MyClass) # False
# 如果元組當(dāng)中有一個類滿足,即返回真
res = isinstance(obj, (Man,Human,MyClass) )
print(res) # True
多態(tài)
不同的子類對象,調(diào)用相同的父類方法,產(chǎn)生不同的執(zhí)行結(jié)果文章來源:http://www.zghlxwxcb.cn/news/detail-431938.html
"""繼承 重寫 """
class Soldier():
def attack(self):
pass
def back(self):
pass
# 陸軍
class Army(Soldier):
def attack(self):
print("[陸軍]開坦克裝甲部隊(duì),開大炮轟炸敵方根據(jù)地,拼刺刀,手撕鬼子")
def back(self):
print("[陸軍]為了一條性命,夜行八百,日行一千,回家")
# 海軍
class Navy(Soldier):
def attack(self):
print("[海軍]開航空母艦,扔魚叉,撒網(wǎng)捆住敵人,收網(wǎng)")
def back(self):
print("[海軍]直接跳水,下海喂魚,原地爆炸")
# 空軍
class AirForce(Soldier):
def attack(self):
print("[空軍]空對地投放原子彈,空對空發(fā)射巡航導(dǎo)彈")
def back(self):
print("[空軍]直接跳機(jī),落地成盒")
# 創(chuàng)建士兵
obj1 = Army()
obj2 = Navy()
obj3 = AirForce()
#
lst = [obj1,obj2,obj3]
# lst = [Army(),Navy(),AirForce()]
strvar = """
將軍請下令:
1.全體出擊
2.全體撤退
3.海軍出擊,其他兵種撤退
"""
num = input(strvar)
for i in lst:
# print(i)
if num == "1":
i.attack() # 方法名相同,但是結(jié)果不一樣
elif num == "2":
i.back()
elif num == "3":
if isinstance(i,Navy):
i.attack()
else:
i.back()
else:
print("風(fēng)太大,小弟聽不見")
break
python對成員的保護(hù)分為兩個等級
- 私有的: private
在本類內(nèi)部可以訪問,類的外部不可以訪問.(python中 屬性或者方法前面加上兩個下劃線__
) - 公有的: public
在本類的內(nèi)部和外部都可以訪問.
# 私有成員的改名策略 [_類名__成員名]
# 對象的相關(guān)操作
(1)實(shí)例化的對象訪問公有成員屬性和方法
(2)實(shí)例化的對象動態(tài)添加公有成員屬性和方法
(3)實(shí)例化的對象刪除公有成員屬性和方法
# 類的相關(guān)操作
(1)定義的類訪問公有成員屬性和方法
(2)定義的類動態(tài)添加公有成員屬性和方法
(3)定義的類刪除公有成員屬性和方法
普通方法: 沒有任何參數(shù)傳遞,只能類調(diào)用
綁定方法: 把默認(rèn)傳參的方法叫做綁定方法,綁定到對象(默認(rèn)傳對象),綁定到類(默認(rèn)傳類)
非綁定方法:靜態(tài)方法(無需傳任何參數(shù),對象和類都能調(diào)用)
私有的:只能載類或者對象的結(jié)構(gòu)中訪問
公有的:可以載任何位置訪問
受保護(hù):可以載當(dāng)前類或者對象 和子類或者子類對象中訪問
類內(nèi) 子類中 類外部
公有的: √ √ √
私有的: √ X X
受保護(hù): √ √ X (python語言不支持)
魔術(shù)方法(特定時(shí)機(jī)自動觸發(fā))
__init__ 魔術(shù)方法(構(gòu)造方法)
'''
觸發(fā)時(shí)機(jī):實(shí)例化對象,初始化的時(shí)候觸發(fā)
功能:為對象添加成員
參數(shù):參數(shù)不固定,至少一個self參數(shù)
返回值:無
'''
__new__ 魔術(shù)方法
'''
觸發(fā)時(shí)機(jī):實(shí)例化類生成對象的時(shí)候觸發(fā)(觸發(fā)時(shí)機(jī)在__init__之前)
功能:控制對象的創(chuàng)建過程
參數(shù):至少一個cls接受當(dāng)前的類,其他根據(jù)情況決定
返回值:通常返回對象或None
'''
# (1) 基本使用
class MyClass2():
a = 100
obj2 = MyClass2()
# print(obj2)
class MyClass1():
def __new__(cls):
print(cls) # <class '__mian__.MyClass1'>
# 1.返回本類對象
"""類.成員方法(類)"""
return object.__new__(cls)
# 2.返回其他類的對象
# return obj2
# 3.不返回對象,None
# return None
obj = MyClass1()
# print(obj.a)
print(obj)
# (2) __new__ 觸發(fā)時(shí)機(jī)要快于 __init__
"""
# 先創(chuàng)建對象,然后初始化對象
__new__ 創(chuàng)建對象
__init__ 初始化對象
"""
class MyClass():
def __new__(cls):
print(1)
return object.__new__(cls)
def __init__(self):
print(2)
obj = MyClass() # 1 2
# (3) __new__的參數(shù)要和__init__參數(shù)一一對應(yīng)
class Boat():
def __new__(cls,name): # 不加name參數(shù)會報(bào)錯
return object.__new__(cls)
def __init__(self,name):
self.name = name
obj = Boat("萬里陽光號")
print(obj.name)
# 使用收集參數(shù)進(jìn)行改造 ***
class Boat():
# *args,**kwargs 可以收集多余的所有參數(shù)
def __new__(cls,*args,**kwargs):
return object.__new__(cls)
def __init__(self,name,type):
self.name = name
self.type = type
obj = Boat("萬里陽光號","破木頭做的")
print(obj.name , obj.type)
# (4) __new__和__init__之間的注意點(diǎn)
"""
如果 __new__ 沒有返回對象或者返回的是其他類的對象,不會調(diào)用構(gòu)造方法.
只有在返回自己本類對象的時(shí)候,才會調(diào)用 __iniy__ 構(gòu)造方法.
"""
class Children():
def __new__(cls,*args,**kwargs):
return obj2
# pass # 需要return cls
def __init__(self,name,skin):
print("構(gòu)造方法被觸發(fā) ... ")
# self.name = name
# self.skin = skin
obj = Children("滅霸","紫薯")
# 沒有返回對象,默認(rèn)是None,無法在None關(guān)鍵字上加name屬性
# print(obj.name) error
# print(obj.skin) error
單例模式
同一個類,無論實(shí)例化多少次,都有且只有一個對象文章來源地址http://www.zghlxwxcb.cn/news/detail-431938.html
"""
每創(chuàng)建一個對象,就會在內(nèi)存中多占用一份空間
為了節(jié)省空間,提升執(zhí)行效率,使用單態(tài)(單例)模式
場景:只是單純調(diào)用類中的成員,而不會額外為當(dāng)前對象添加成員;
"""
class Singleton():
__obj = None
def __new__(cls):
if cls.__obj is None:
cls.__obj = object.__new__(cls)
return cls.__obj
"""
第一次,在實(shí)例化對象時(shí)觸發(fā)__new__魔術(shù)方法
if cls.__obj is None 條件成立 cls.__obj = object.__new__(cls) 創(chuàng)建一個對象給私有成員屬性__obj
return cls.__obj 用obj1接收到了對象
第二次,在實(shí)例化對象時(shí)觸發(fā)__new__魔術(shù)方法 if cls.__obj is None不滿足,因?yàn)橐呀?jīng)在__obj屬性中存放了一個對象
return cls.__obj
第三次,在實(shí)例化對象時(shí)觸發(fā)__new__魔術(shù)方法 if cls.__obj is None不滿足,因?yàn)橐呀?jīng)在__obj屬性中存放了一個對象
return cls.__obj
"""
obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()
print(obj1,obj2,obj3)
# 完整版
class Singleton():
__obj = None
def __new__(cls,*args,**kwargs):
if cls.__obj is None:
cls.__obj = object.__new__(cls)
return cls.__obj
def __init__(self,name):
self.name = name
obj1 = Singleton("康玉康")
obj2 = Singleton("張保張")
print(obj1,obj2) # 同一個對象,指向同一個內(nèi)存地址
print(obj1.name) # 張保張
print(obj2.name) # 張保張
__del__ 魔術(shù)方法(析構(gòu)方法)
'''
觸發(fā)時(shí)機(jī):當(dāng)對象被內(nèi)存回收的時(shí)候自動觸發(fā)[1.頁面執(zhí)行完畢回收所有變量 2.所有對象被del的時(shí)候]
功能:對象使用完畢后資源回收
參數(shù):一個self接受對象
返回值:無
'''
# (1) 基本語法
class Lion():
def __init__(self,name):
self.name = name
def __del__(self):
print("析構(gòu)方法被觸發(fā) ... ")
# 觸發(fā)方式一: 頁面執(zhí)行完畢回收所有變量
obj1 = Lion("辛巴")
# 觸發(fā)方式二: 所有對象被del的時(shí)候
obj2 = obj1
obj3 = obj1
print(obj2 , obj1 ,obj3)
print("<====start===>")
del obj1
del obj2 # 對象沒有引用的時(shí)候才會觸發(fā)
del obj3
print("<====end===>")
# (2) 模擬文件操作
import os
class ReadFile():
# 根據(jù)文件是否存在,創(chuàng)建對象
def __new__(cls,filename):
if os.path.exists(filename):
return object.__new__(cls)
else:
print("抱歉,沒有這個文件")
# 打開文件
def __init__(self,filename):
self.fp = open(filename,mode="r",encoding="utf-8")
# 關(guān)閉文件
def __del__(self):
self.fp.close()
# 讀取文件
def readcontent(self):
return self.fp.read()
obj = ReadFile("0.py")
print(obj.readcontent())
__str__ 魔術(shù)方法
'''
觸發(fā)時(shí)機(jī): 使用print(對象)或者str(對象)的時(shí)候觸發(fā)
功能: 查看對象
參數(shù): 一個self接受當(dāng)前對象
返回值: 必須返回字符串類型
'''
class Cat():
gift = "抓老鼠"
def __init__(self,name):
self.name = name
def cat_gift(self):
return "小貓叫{},小貓會{}".format(self.name,self.gift)
def __str__(self):
return self.cat_gift()
__repr__ = __str__
tom = Cat("湯姆")
# 觸發(fā)時(shí)機(jī)1 : print(對象)
# print(tom)
# 觸發(fā)時(shí)機(jī)2 : str(對象)
res = str(tom)
print(res)
print("<==================>")
res = repr(tom)
print(res , type(res))
print("<==================>")
__repr__ 魔術(shù)方法
'''
觸發(fā)時(shí)機(jī): 使用repr(對象)的時(shí)候觸發(fā)
功能: 查看對象,與魔術(shù)方法__str__相似
參數(shù): 一個self接受當(dāng)前對象
返回值: 必須返回字符串類型
'''
class Mouse():
gift = "偷油吃"
def __init__(self,name):
self.name = name
def mouse_gift(self):
return "老鼠叫{},老鼠會{}".format(self.name,self.gift)
def __repr__(self):
return self.mouse_gift()
# 系統(tǒng)底層默認(rèn)把__repr__方法賦值給__str__方法,所以通過print或者str強(qiáng)轉(zhuǎn)可以觸發(fā);
# __str__ = __repr__
jerry = Mouse("杰瑞")
# res = repr(jerry)
# print(res)
# 可以觸發(fā)
# print(jerry)
res = str(jerry)
print(res)
__call__ 魔術(shù)方法
'''
觸發(fā)時(shí)機(jī):把對象當(dāng)作函數(shù)調(diào)用的時(shí)候自動觸發(fā)
功能: 模擬函數(shù)化操作
參數(shù): 參數(shù)不固定,至少一個self參數(shù)
返回值: 看需求
'''
# (1) 基本語法
class MyClass():
def __call__(self):
print("__call__魔術(shù)方法被觸發(fā) ... ")
obj = MyClass()
obj() # 如果沒寫 __call__魔術(shù)方法 則報(bào)錯
# (2) 利用__call__魔術(shù)方法做統(tǒng)一調(diào)用
class Wash():
def __call__(self,something):
print("我要洗{}".format(something))
self.step1(something)
self.step2()
self.step3()
return "洗完了"
def step1(self,something):
print("放水,把{}扔進(jìn)去".format(something))
def step2(self):
print("倒洗衣粉,洗衣液,藍(lán)月亮,金紡,立白 ... ")
def step3(self):
print("洗一洗,晾干,穿上")
obj = Wash()
# obj.step1()
# obj.step2()
# obj.step3()
res = obj("襪子")
print(res)
# (3) 模擬整型強(qiáng)轉(zhuǎn)操作
import math
class MyInt():
def __call__(self,num):
if isinstance(num,bool):
if num == False:
return 0
else:
return 1
elif isinstance(num,int):
return num
elif isinstance(num,float):
# 方法一
# a,b = str(num).split(".")
# return eval(a)
# 方法二
"""
if num >= 0:
return math.floor(num)
else :
return math.ceil(num)
"""
# 簡寫
return math.floor(num) if num >= 0 else math.ceil(num)
elif isinstance(num,str):
if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal():
# 獲取當(dāng)前字符串的正負(fù)值
if num[0] == "+":
sign = 1
elif num[0] == "-":
sign = -1
# 截取符號后面的字符串傳遞
return self.calc(num[1:],sign)
elif num.isdecimal():
return self.calc(num)
else:
return "這個算不了兄弟~"
# 計(jì)算最后的數(shù)值
def calc(self,num,sign=1):
# 去掉前面的"0"字符串
num = num.lstrip("0")
# print(num , type(num) , "<==============>")
if num == "":
return 0
return eval(num) * sign
myint = MyInt()
res = myint(-5.67)
print(res , type(res))
res = myint("-000000000000055555")
print(res , type(res))
res = myint("asdfasdfasdfasdf")
print(res , type(res))
# print(myint("+0000000000000"))
# bool int float 純數(shù)字字符串
"""
print( int("00000000000001223") ) # 1223
print( int("-00000000000001223") ) # -1223
print( int("+00000000000001223") ) # 1223
print( int("+0000000000000") ) # 0
"""
# print( int("asdfasdfasdfasdf") ) # 報(bào)錯
# print( eval("00000000000001223") ) # 報(bào)錯
__bool__ 魔術(shù)方法
'''
觸發(fā)時(shí)機(jī):使用bool(對象)的時(shí)候自動觸發(fā)
功能:強(qiáng)轉(zhuǎn)對象
參數(shù):一個self接受當(dāng)前對象
返回值:必須是布爾類型
'''
'''
類似的還有如下等等(了解):
__complex__(self) 被complex強(qiáng)轉(zhuǎn)對象時(shí)調(diào)用
__int__(self) 被int強(qiáng)轉(zhuǎn)對象時(shí)調(diào)用
__float__(self) 被float強(qiáng)轉(zhuǎn)對象時(shí)調(diào)用
...
...
'''
class MyClass():
def __bool__(self):
return True # 返回的不是bool 類型會報(bào)錯
obj = MyClass()
print(bool(obj))
__add__ 魔術(shù)方法 (與之相關(guān)的__radd__ 反向加法)
'''
觸發(fā)時(shí)機(jī):使用對象進(jìn)行運(yùn)算相加的時(shí)候自動觸發(fā)
功能:對象運(yùn)算
參數(shù):二個對象參數(shù)
返回值:運(yùn)算后的值
'''
'''
類似的還有如下等等(了解):
__sub__(self, other) 定義減法的行為:-
__mul__(self, other) 定義乘法的行為:
__truediv__(self, other) 定義真除法的行為:/
...
...
'''
class MyClass():
def __init__(self,num):
self.num = num
# 當(dāng)對象在 + 號的左側(cè)時(shí),自動觸發(fā)
def __add__(self,other):
# print(self) # 對象
# print(other) # + 號右邊的數(shù)據(jù)
return self.num * 3 + other
# 當(dāng)對象在 + 號的右側(cè)時(shí),自動觸發(fā)
def __radd__(self,other):
# print(self) # 對象
# print(other) # 7 + 號左邊的數(shù)據(jù)
return self.num * 5 + other
# add的觸發(fā)方式
a = MyClass(3)
res = a + 1
print(res) # 10
# radd的觸發(fā)方式
b = MyClass(5)
res = 7 + b
print(res) # 32
# 對象 + 對象
res = a + b
print(res) # 34
"""
a+b 觸發(fā)的是add魔術(shù)方法 self 接受的是a other 接受的是b
return a.num + b => return 9 + b
res = 9 + b 觸發(fā)的是radd魔術(shù)方法 self 接受的是b other 接受的是9
return b.num * 5 + 9 => 5 * 5 + 9 => 34
"""
__len__ 魔術(shù)方法
'''
觸發(fā)時(shí)機(jī):使用len(對象)的時(shí)候自動觸發(fā)
功能:用于檢測對象中或者類中某個內(nèi)容的個數(shù)
參數(shù):一個self接受當(dāng)前對象
返回值:必須返回整型
'''
'''
類似的還有如下等等(了解):
__iter__(self) 定義迭代容器中的元素的行為
__reversed__(self) 定義當(dāng)被 reversed() 調(diào)用時(shí)的行為
__contains__(self, item) 定義當(dāng)使用成員測試運(yùn)算符(in 或 not in)時(shí)的行為
...
...
'''
# len(對象) => 類中的所有自定義成員
class MyClass():
pty1 = 1
pty2 = 2
__pty3 = 3
def func1():
pass
def func2():
pass
def __func3():
pass
def __len__(self):
# 以__開頭并且以__結(jié)尾的成員過濾掉;
return len( [ i for i in MyClass.__dict__ if not ( i.startswith("__") and i.endswith("__") ) ] )
obj = MyClass()
print(len(obj))
魔術(shù)屬性
class Man():
pass
class Woman():
pass
class Sasuke(Man,Woman):
"""
描述: 佐助這個的天生屬性,技能
成員屬性: __eye skin
成員方法: skylight __moonread
"""
__eye = "血輪眼->萬花筒->輪回眼"
skin = "白色"
def skylight(self , myfunc):
print("使用天照,一團(tuán)黑色的火焰 ... 恐怖如斯")
res = myfunc.__name__
print(res , type(res) )
def __moonread(self):
print("使用月讀,讓敵人拉入到幻術(shù)空間,被施法者掌握")
obj = Sasuke()
__dict__ 獲取對象或類的內(nèi)部成員結(jié)構(gòu)
dic = Sasuke.__dict__ # <class 'mappingproxy'> 類型
dic = obj.__dict__ # <class 'dict'>
print(dic)
__doc__ 獲取對象或類的內(nèi)部文檔
print(Sasuke.__doc__)
print(obj.__doc__)
__name__ 獲取類名函數(shù)名
def func343434():
print("佩恩出場時(shí),使用一手地爆天星,技驚四座,點(diǎn)燃所有觀眾")
obj.skylight(func343434) # func343434
__class__ 獲取當(dāng)前對象所屬的類
print(obj.__class__) # <class '__main__.Sasuke'>
__bases__ 獲取一個類直接繼承的所有父類,返回元組
print(Sasuke.__bases__) # (<class Man>, <Woman>)
到了這里,關(guān)于【python基礎(chǔ)語法十】面向?qū)ο蟮奈恼戮徒榻B完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!