我的python學習之路-oop面向物件
本節內容:
一、類的基礎
二、封裝
三、繼承
四、多型
五、魔術方法
5.9__add__ 魔術方法 (與之相關的 __radd__ 反向加法)
一、類的基礎
1、類的定義
# 推薦使用 class MyCar(): pass class MyCar: pass class MyCar(object): pass
2、類的例項化
class MyCar(): pass # 類的例項化 / 例項化物件 obj = MyCar()print(obj)
3、類的基本結構
- 成員屬性
- 成員方法
class MyCar(): # 成員屬性 color = "粉色系" # 成員方法 def didi(): print("會滴滴的叫")
4、類的命名
類的命名 => 推薦使用大駝峰命名法;
mycar => MyCar
mycat => MyCat
chengfabiao => ChengFaBiao
二、封裝
封裝等級:
- 公有:在類的內部和外部都可以訪問到
- 私有:在類的內部可以使用,再類外無法呼叫
成員:
- 成員屬性
- 成員方法
呼叫:
- 物件.成員屬性
- 物件.成員方法
繫結方法:
- 繫結到物件:物件.類中方法()時,系統會自動把該物件當成引數傳遞到方法中;
- 繫結到類 :物件.類中方法()或者類.方法()時,系統會自動把該類當成引數傳遞到方法中
1.封裝-物件的相關操作
定義一個類
class Car(): # 公有成員屬性 color = "黃色" # 私有成員屬性 __price = "200多萬" # 公有方法 def run(self): # 類內呼叫公有成員 self <=> obj print(self.color,"內部") # 類內呼叫私有成員 print(self.__price) print("小車每秒140米的速度前進") # 私有方法 def __drive(): print("小車可以無人駕駛")
(1)例項化的物件訪問公有成員屬性和方法
# 例項化物件
obj = Car()
# 訪問屬性 print(obj.color,"<外部>") # print(obj.__price) #error # 訪問方法 obj.run() # obj.__drive() #error
(2)例項化的物件動態新增公有成員屬性和方法
obj優先呼叫自己的,在呼叫類的,都沒有報錯
1) 、 新增成員屬性
obj.engine = "16缸發動機" obj.color = "綠色" # 優先呼叫物件自己的顏色 print(obj.engine) print(obj.color) obj.run() # __dict__ 檢視物件或者類中的內部成員,返回字典 print(obj.__dict__) print(Car.__dict__)
2)、新增成員方法
注意點: 物件.類外方法()時,系統不會自動把該物件當成引數傳遞到該方法中
(1)、新增無參方法
def dahuangfeng(): print("變形~ 我叫大黃蜂") obj.dahuangfeng = dahuangfeng obj.dahuangfeng() print(obj.__dict__)
(2)、新增有參方法
基本版:
def qingtianzhu(name): print("變形~ 我叫{}".format(name)) obj.qingtianzhu = qingtianzhu obj.qingtianzhu("一柱擎天")
升級版 (手動傳遞obj),由於要用物件中的其他的屬性,所以要傳遞obj
def qingtianzhu(obj,name): print( "變形~ 我叫{}".format(name) , "顏色為{}".format(obj.color) ) obj.qingtianzhu = qingtianzhu obj.qingtianzhu(obj,"擎天柱")
究極版 (自動傳遞obj)
MethodType => 建立繫結方法(繫結到物件) 讓系統自動幫助我們傳遞obj物件
import types """types.MethodType(函式,物件)""" func = types.MethodType(qingtianzhu,obj) print(func) obj.qingtianzhu = func obj.qingtianzhu("擎天柱")
(3) 新增lambda 表示式
obj.hongzhizhu = lambda : print("變形~ 我是反派角色紅蜘蛛") obj.hongzhizhu()
2、封裝 - 類相關操作
定義一個類
class Taxi(): # 公有成員屬性 platenum = "粵B 666888" # 私有成員屬性 __earn = "12000" # 公有方法 def lake(): print("計程車經常拉客人~") # 私有方法 def __ranquan(): print("部分司機繞圈圈~")
(1)定義的類訪問公有成員屬性和方法
obj = Taxi() """類中的無參方法只能類來呼叫;""" # obj.lake() # 成員屬性 print(Taxi.platenum) # Taxi.__earn error # 成員方法 Taxi.lake()
(2)定義的類動態新增公有成員屬性和方法
(1)、動態新增成員屬性
Taxi.luntai = "米其林" print(Taxi.luntai) print(obj.luntai) #米其林 對用可以呼叫 print(Taxi.__dict__) print(obj.__dict__) #{} 看看出物件和類是兩個記憶體空間
(2)、動態新增成員方法
(1) 無參方法
def fangxiangpan(): print("我是製造方向盤的方法") Taxi.fangxiangpan = fangxiangpan Taxi.fangxiangpan()
(2) 有參方法
def engin(name): print("我是製造{}的方法".format(name)) Taxi.engin = engin Taxi.engin("EA888")
(3) lambda表示式
Taxi.zuoyi = lambda : print("我是製造加熱座椅的方法") Taxi.zuoyi()
3、注意點: 物件和類之間的不同
(1)物件去呼叫類中方法時,系統都會預設傳遞該物件引數;
(2)物件可以預設呼叫類中的公有成員,反過來,類不能呼叫物件中的相關成員.
(3)一個類可以建立多個物件,而物件和物件之間是彼此獨立的;
4、訪問類中私有成員
定義一個類
1 class Plane(): 2 3 # 公有成員屬性 4 captain = "李雅琪" 5 6 # 私有成員屬性 7 __airsister = "10個空姐" 8 9 # 公有成員方法 10 def fly(self): 11 print("飛機飛到平流層,可以飛機的機身的抖動") 12 13 # 私有成員方法 14 def __price(self): 15 print("飛機的價格保密") 16 17 # 公有無參成員方法 18 def fly2(): 19 print("飛機在降落時,落地的一瞬間會向上彈起,請記好安全帶") 20 21 # 私有無參成員方法 22 def __info(): 23 print("關於飛機中的機長和空姐的資訊保密") 24 25 # 利用公有方法調取私有成員[物件操作] 26 def pub_info1(self): 27 print(self.__airsister) 28 self.__price() 29 30 # 利用公有方法調取私有成員[類操作] 31 def pub_info2(): 32 print(Plane.__airsister) 33 Plane.__info()View Code
(1 ).方法一 私有化的實現方式:改名策略 (不推薦,破壞了封裝性)
# 例項化物件 obj = Plane() print(Plane.__dict__) # 類去訪問私有成員屬性 print(Plane._Plane__airsister) # 類去訪問私有成員方法 Plane._Plane__info() # 物件去訪問私有成員屬性 obj._Plane__airsister # 物件去訪問私有成員方法 obj._Plane__price()
2.方法二 利用一個公有方法,間接呼叫私有成員 (推薦)
obj.pub_info1()
Plane.pub_info2()
注意點:如果無參只能類來調取,如果有參,物件和類都能調取
# obj.pub_info2() #error Plane.pub_info1(obj)
5、刪除類物件中公有成員屬性方法
1.刪除成員時,一定要注意,該成員歸屬於誰,如果物件中沒有該成員,只有使用的權利,沒有刪除和修改的權利
2.物件獲取成員時,先看自己空間有沒有,如果有就調取,否則上類中成員尋找,如果類中也沒有,直接報錯
定義一個類:
1 class Plane(): 2 3 # 公有成員屬性 4 captain = "李雅琪" 5 6 # 私有成員屬性 7 __airsister = "10個空姐" 8 9 # 公有成員方法 10 def fly(self): 11 print("飛機飛到平流層,可以飛機的機身的抖動") 12 13 # 私有成員方法 14 def __price(self): 15 print("飛機的價格保密") 16 17 # 公有無參成員方法 18 def fly2(): 19 print("飛機在降落時,落地的一瞬間會向上彈起,請記好安全帶") 20 21 # 私有無參成員方法 22 def __info(): 23 print("關於飛機中的機長和空姐的資訊保密") 24 25 # 利用公有方法調取私有成員[物件操作] 26 def pub_info1(self): 27 print(self.__airsister) 28 self.__price() 29 30 # 利用公有方法調取私有成員[類操作] 31 def pub_info2(): 32 print(Plane.__airsister) 33 Plane.__info()View Code
1、刪除物件中的屬性
obj.captain = "家營和" # 不能刪除類中的,只能自己新增 print(obj.__dict__) del obj.captain print(obj.captain,"<111>")
2、刪除物件中的方法
obj.pub_info1 = lambda : print("我是pub_info方法") del obj.pub_info1
3、刪除類中的屬性
del Plane.captain #print(Plane.captain) error # print(obj.captain,"<2222>") error
4、刪除類中的方法
del Plane.pub_info1 # Plane.pub_info1(obj) error # obj.pub_info1() error
三 、繼承
繼承:一個類除了自身所擁有的屬性方法之外,還獲取了另外一個類的成員屬性和方法
被繼承的就是父類(基類,超類)
繼承的就是子類(衍生類)
python中所有類的父類是object
1、單繼承
class Human(): property1 = "遠古人類不穿衣服" def fire(self): print("遠古人類鑽木去火") def drinkblood(self): print("遠古人類茹毛飲血") def __mao(self): print("遠古人類一身毛,不能碰") class Man(Human): pass
1、子類繼承了父類之後,子類可以使用父類的公有成員
obj = Man() print(obj.property1)
2、子類繼承了父類之後,子類不能使用父類的私有成員
class Woman(Human): def pub_func(self): self.__mao() obj = Woman() # obj.pub_func() error
3、子類繼承了父類之後,子類可以重寫父類的公有成員
class Children(Human): def drinkblood(self): print("剛出生的小孩只能喝奶奶") obj = Children() obj.drinkblood()
4、總結
在繼承的環境當中,物件的調取順序:
先檢視自己物件中是否含有該成員 => 自己的類是否含有 => 該類的父類是否含有 => 報錯
2、多繼承
1.基本用法
class Father(): f_pty = "風流倜儻,玉樹臨風,一枝梨花壓海棠" def f_hobby(self): print("打麻將,吃喝嫖賭,開跑車約妹子") class Mother(): m_pty = "傾國傾城,貌美如花,一直紅杏出牆來" def m_hobby(self): print("打麻將,蹦野迪,勾引小鮮肉") class Daughter(Father,Mother): pass obj = Daughter() print(obj.f_pty) obj.m_hobby()
2.深度使用
(1)super本身是一個類 super()是一個物件 用於呼叫父類的繫結方法
(2)super() 只應用在繫結方法中,預設自動傳遞self物件 (前提:super所在作用域存在self)
(3)super用途: 解決複雜的多繼承呼叫順序
1 class Father(): 2 pty = "風流倜儻,玉樹臨風,一枝梨花壓海棠" 3 def hobby(self): 4 print(self) 5 print("打麻將,吃喝嫖賭,開跑車約妹子") 6 7 class Mother(): 8 pty = "傾國傾城,貌美如花,一直紅杏出牆來" 9 def hobby(self): 10 print("打麻將,蹦野迪,勾引小鮮肉") 11 12 class Son(Father,Mother): 13 pty = "可愛,有趣,愛學習,愛勞動,三道槓" 14 15 def hobby(self): 16 print("喜歡打遊戲,lol,wow.dnf.ddo,cs,cf") 17 18 # 1.使用類呼叫類中成員 19 def skill1(self): 20 # 呼叫mother中的成員 21 print(Mother.pty) 22 Mother.hobby(self) 23 24 # 呼叫father中的成員 25 print(Father.pty) 26 # Father.hobby() 27 28 # 2.使用物件呼叫類中成員 29 """obj呼叫成員時,會按照 obj成員 -> 子類成員 -> 父類成員""" 30 def skill2(self): 31 print(self.pty) 32 # obj.hobby() error 33 self.hobby() 34 35 # 3.使用super呼叫類中成員 36 """1.super只調用父類的繫結方法 2.會自動把該物件當成引數進行傳遞""" 37 def skill3(self): 38 print(super) 39 print(super()) 40 print(super().pty) 41 super().hobby() 42 43 obj = Son() 44 print("<=======1========>") 45 obj.skill1() 46 print("<=======2========>") 47 obj.skill2() 48 print("<=======3========>") 49 obj.skill3()View Code
3、菱形繼承
class Human(): pty = 4 def feelT(self): print("天熱了,脫毛1") print(self.pty) print("天冷了,穿貂2") class Man(Human): pty = 3 def feelT(self): print("天熱了,光膀子3") super().feelT() print("天冷了,穿貂4") class Woman(Human): pty = 2 def feelT(self): print("天熱了,脫衣服5") super().feelT() print("天冷了,多喝熱水6") class Children(Man,Woman): pty = 1 def feelT(self): print("天熱了,光屁股7") super().feelT() print("天冷了,喝奶8") obj = Children() obj.feelT() # 7 3 5 1 2 6 4 8 print(obj.pty)#1
mro列表:方法解析順序列表
類.mro() => 方法解析順序列表
super呼叫的順序要依賴mro列表所呈現的順序,依次呼叫;
作用: super用途: 解決複雜的多繼承呼叫順序(菱形繼承)
super要點:
1.super只調用父類成員
2.super呼叫父類成員採用廣度優先原則(依照類.mro列表順序呼叫)
3.super呼叫父類方法時,會自動傳遞該物件引數
4、相關函式
(1)、.issubclass 判斷子類與父類 (類與類之間的關係)
issubclass在判斷子父關係時候,只要在一條繼承鏈上,有繼承關係即可
1).issubclass(子類,父類)
2).issubclass(子類,(父類1,父類2,父類3 ... ))
(2)、isinstance 判斷物件的型別 (物件與類之間關係)
1).isinstance(物件,類)
2)isinstance(物件,(類1,類2,類3)
四 、多型
1、基本概念及使用例子
多型 : 不同的子類物件,呼叫相同的父類方法,產生不同的執行結果
特徵 : 繼承 重寫 針對於物件
1 class Soldier(): 2 # 攻擊方法 3 def attack(self): 4 pass 5 6 # 撤退方法 7 def back(self): 8 pass 9 10 11 class Army(Soldier): 12 def attack(self): 13 print("手撕鬼子,包子手雷") 14 15 def back(self): 16 print("飛簷走壁,日行八百,夜行一千") 17 18 class Navy(Soldier): 19 def attack(self): 20 print("扔魚叉,勤撒網,往回拉鬼子") 21 22 def back(self): 23 print("潛水,划水,水遁,下水憋氣30個小時") 24 25 class AirForce(Soldier): 26 def attack(self): 27 print("射導彈,扔手雷") 28 29 def back(self): 30 print("契機跳傘,落地成盒") 31 32 # 建立陸軍士兵 33 objArmy = Army() 34 # 建立海軍士兵 35 objNavy = Navy() 36 # 建立空軍士兵 37 objAirForce = AirForce() 38 39 # 各就位準備 40 lst = [objArmy,objNavy,objAirForce] 41 42 strvar = """ 43 各就位準備,將軍請下令: 44 1.全體出擊 45 2.全體撤退 46 3.陸軍上,其他兵種撤退 47 """ 48 49 num = input(strvar) 50 for i in lst: 51 # print(i) 52 if num == "1": 53 i.attack() 54 elif num == "2": 55 i.back() 56 elif num == "3": 57 # 判斷物件型別是陸軍 58 if isinstance(i,Army): 59 i.attack() 60 else: 61 i.back() 62 else: 63 print("風大太,我聽不見~") 64 break 65View Code
五、魔術方法
定義:系統自動呼叫的方法,按照觸發機制呼叫
1、__init__構造方法
觸發時機:例項化物件,初始化的時候觸發
功能:為物件新增成員
引數:引數不固定,至少一個self引數
返回值:無
(1) 基本使用-無引數的
class MyClass(): def __init__(self): self.name = "~李琦~" print("構造方法被觸發了... ") # 例項化物件 obj = MyClass() print(obj.name)
(2)帶有引數的構造方法
class MyClass(): def __init__(self,name): self.name = name # 在例項化物件時,給與構造方法實參 obj1 = MyClass("朱培峰") obj2 = MyClass("黃常見") print(obj1.name) print(obj2.name)
(3)類可以是一個,物件可以是多個,不同的物件之間資料彼此隔離
1 class Children(): 2 3 # 構造方法 4 def __init__(self,name,skin): 5 # 為物件新增成員 6 self.name = name 7 self.skin = skin 8 # 公有成員方法(繫結到物件) 9 def cry(self): 10 print("小孩一生產出來,就會哇哇哇的哭") 11 12 # 公有成員方法(繫結到物件) 13 def eat(self): 14 print("小孩一生產出來,就會吃奶奶") 15 16 # 私有成員方法(繫結到物件) 17 def __laugh(self): 18 print("小孩一生產出來,就仰天長笑,老子終於出來了.") 19 20 # 面向物件的寫法(讓物件操作一切) 推薦 21 def info1(self): 22 print("小孩的姓名是{},小孩的膚色是{}".format(self.name , self.skin) ) 23 24 # 面向過程寫法(普通的函式傳參) 25 def info2(self,name,skin): 26 print("小孩的姓名是{},小孩的膚色是{}".format(name ,skin) ) 27 28 29 wanggangdan = Children("王剛單","綜色") 30 wanggangdan.info1() 31 wanggangdan.info2("王鋼單","白色") 32 wanggangdan.cry() 33 34 wangtiechui = Children("王鐵錘","黑色") 35 wangtiechui.info1() 36 wangtiechui.eat() 37 38 wangbaoqiang = Children("王寶強","綠色") 39 wangbaoqiang.info1() 40 # wangbaoqiang.__laugh() errorView Code
2、__new__ 魔術方法
觸發時機:例項化類生成物件的時候觸發(觸發時機在__init__之前)
功能:控制物件的建立過程
引數:至少一個cls接受當前的類,其他根據情況決定
返回值:通常返回物件或None
1.基本使用
1 class OtherClass(): 2 pty = 200 3 obj2 = OtherClass() 4 5 class MyClass(): 6 pty = 1 7 def __new__(cls): 8 print("__new__方法被觸發 ... ") 9 print(cls) 10 print("<===========>") 11 12 # 返回本類物件 (借父生子) 13 # 類.方法(cls) 14 # return object.__new__(cls) 15 # 不返回物件 16 # return None 17 # 返回其他類物件 18 return obj2 19 20 obj = MyClass() 21 print(obj) 22 print(obj.pty)View Code
2.__new__ 和 __init__ 的觸發時機
__new__ 是在造物件時觸發
__init__ 有物件之後,初始化物件的時候自動觸發
先有物件,在初始化;
3.__new__ 和 __init__ 引數需要一一對應
1 class MyClass(): 2 3 def __new__(cls,name): 4 print(333) 5 return object.__new__(cls) 6 def __init__(self,name): 7 print(444) 8 self.name = name 9 10 obj = MyClass("李琦") 11 print(obj.name) 12 13 # 在__new__中加上收集引數,以不變應萬變 14 class MyClass(): 15 16 def __new__(cls,*args,**kwargs): 17 print(333) 18 return object.__new__(cls) 19 def __init__(self,name,sex,age): 20 print(444) 21 self.name = name 22 self.sex = sex 23 self.age = age 24 obj = MyClass("朱培峰","女性","100") 25 print(obj.name) 26 print(obj.sex) 27 print(obj.age)View Code
4.注意點
如果沒有創建出物件,不會觸發構造方法 ...
如果返回的不是本類物件,不會觸發構造方法 ...
3、單態(例)模式
同一個類,無論例項化多少次,都有且只有一個物件
作用: 可以減少記憶體空間的浪費,提升程式碼執行效率
場景: 如果不需要在建立物件時,在類外額外為當前物件新增成員,就可以使用單態模式;
(1) 基本使用
1 class SingleTon(): 2 # 類中私有成員屬性 3 __obj = None 4 5 def __new__(cls): 6 print(cls) # <class '__main__.SingleTon'> 7 # 類.私有成員屬性 8 if cls.__obj is None: 9 # 儲存建立的物件在私有成員__obj當中 10 # 類.私有成員屬性 = 值(物件) 11 cls.__obj = object.__new__(cls) 12 # 返回該物件 13 return cls.__obj 14 15 obj1 = SingleTon() 16 obj2 = SingleTon() 17 obj3 = SingleTon() 18 print(obj1) 19 print(obj2) 20 print(obj3)View Code
程式碼解析:
obj1 = SingleTon() 觸發__new__魔術方法 if cls.__obj is None: 條件滿足,建立物件賦值給私有成員__obj return 當前建立的物件
obj2 = SingleTon() 觸發__new__魔術方法 return cls.__obj
obj3 = SingleTon() 觸發__new__魔術方法 return cls.__obj
(2) 注意點
1 class SingleTon(): 2 __obj = None 3 def __new__(cls,*args,**kwargs): 4 if cls.__obj is None: 5 cls.__obj = object.__new__(cls) 6 return cls.__obj 7 8 def __init__(self,name): 9 self.name = name 10 11 obj1 = SingleTon("王永娟") 12 obj2 = SingleTon("荷葉") 13 print(obj1.name) 14 print(obj2.name) 15 16 print(obj1,obj2) 17 print(obj1 is obj2) ##相等 同一地址View Code
4、__del__ 魔術方法(析構方法)
觸發時機:當物件被記憶體回收的時候自動觸發[1.頁面執行完畢回收所有變數 2.所有物件被del的時候]
功能:物件使用完畢後資源回收
引數:一個self接受物件
返回值:無
1.基本使用
1 # 1.基本使用 2 class LangDog(): 3 # 構造方法 4 def __init__(self,name): 5 self.name = name 6 7 # 析構方法 8 def __del__(self): 9 print("析構方法被觸發 ... ") 10 11 # 1.頁面執行完畢回收所有變數,自動觸發 12 obj1 = LangDog("小白土狗") 13 print(obj1.name) 14 # 2.所有物件被del的時候,自動觸發 15 # print("<==========start==========>") 16 # del obj1 17 # print("<==========end==========>") 18 # 3.注意點 19 """當一個數據沒有任何變數引用的時候,才會真正的被記憶體釋放掉;""" 20 obj2 = obj1 21 obj3 = obj1 22 print(obj2 is obj3) 23 print(obj1,obj2,obj3) 24 print("<==========start==========>") 25 del obj1 26 del obj2 27 del obj3 28 print("<==========end==========>")View Code
2.模擬檔案操作
1 import os 2 class ReadFile(): 3 4 def __new__(cls,filename): 5 # 判斷檔案是否存在,在建立物件 6 if os.path.exists(filename): 7 return object.__new__(cls) 8 else: 9 print("抱歉,該檔案不存在") 10 11 def __init__(self,filename): 12 # 開啟檔案 13 self.fp = open(filename,mode="r",encoding="utf-8") 14 15 def readfile(self): 16 # 讀取檔案 17 data = self.fp.read() 18 return data 19 20 def __del__(self): 21 # 關閉檔案 22 self.fp.close() 23 24 obj = ReadFile("ceshi1.txt") 25 # obj = ReadFile("ceshi1.txt234242234423") 檔案不存在,不會建立物件 26 res = obj.readfile() 27 print(res)View Code
5、__call__ 魔術方法
觸發時機:把物件當作函式呼叫的時候自動觸發
功能: 模擬函式化操作
引數: 引數不固定,至少一個self引數
返回值: 看需求
(1) 基本用法
class MyClass(): def __call__(self): print("__call__ 方法被觸發 ... ") obj = MyClass() obj()
(2) 模擬洗衣服的過程
1 class Wash(): 2 def __call__(self,something): 3 print("正在{}".format(something)) 4 self.step1() 5 self.step2() 6 self.step3() 7 return "洗完了" 8 9 def step1(self): 10 print("脫衣服,把衣服扔進洗衣機") 11 12 def step2(self): 13 print("扔點藍月亮,洗衣粉,洗衣皁,金紡... ") 14 15 def step3(self): 16 print("穿上去,等於晾乾") 17 18 obj = Wash() 19 20 # 方法一 21 # obj.step1() 22 # obj.step2() 23 # obj.step3() 24 25 # 方法二 26 res = obj("洗衣服") 27 print(res)View Code
(3) 模擬int操作
1 import math 2 class MyInt(): 3 def __call__(self,num): 4 5 # 判斷是否是布林型別,做轉換 6 if isinstance(num,bool): 7 if num == True: 8 return 1 9 else: 10 return 0 11 12 # 判斷是否是整型,做轉換 13 elif isinstance(num,int): 14 return num 15 16 # 判斷是否是浮點型,做轉換 17 elif isinstance(num,float): 18 # 方法一 19 """ 20 a,b = str(num).split(".") 21 return eval(a) 22 """ 23 24 # 方法二 25 """ceil floor""" 26 """ 27 if num >= 0: 28 return math.floor(num) 29 else: 30 return math.ceil(num) 31 """ 32 33 # 簡寫 34 return math.floor(num) if num >= 0 else math.ceil(num) 35 36 # 判斷是否是字串 37 elif isinstance(num,str): 38 # 獲取第一為是+或者-,後面全是純數字,可以轉換 39 if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal(): 40 # 判定符號 41 if num[0] == "+": 42 sign = 1 43 else: 44 sign = -1 45 # 計算資料 46 return self.calc(num[1:],sign) 47 48 elif num.isdecimal(): 49 return self.calc(num) 50 51 else: 52 return "抱歉,這個算不了" 53 54 def calc(self,num,sign=1): 55 # print("<========================>") 56 res = num.lstrip("0") 57 if res == "": 58 return 0 59 return eval(res) * sign 60 61 62 # int 整型 浮點型 布林型 純數字字串 63 myint = MyInt() 64 # 布林型 65 res = myint(False) 66 print(res) 67 # 整型 68 res = myint(199) 69 print(res) 70 # 浮點型 71 res = myint(5.77) 72 res = myint(-5.77) 73 print(res , type(res)) 74 75 # 字串 76 # res = myint("-00001111") 77 78 res = myint("asdfasdf") # -1111 ("-000000000000000000000000") 79 print("<============start============>") 80 print(res) 81 print("<============end============>") 82 83 """ 84 print(math.floor(3.15)) 85 print(int(3.15)) 86 87 print(math.ceil(-3.15)) 88 print(int(-3.15)) 89 90 91 print(math.floor(0)) 92 # print(int(0.13)) 93 94 """ 95 96 print(int("0000000000000000000012121121")) 97 print(int("+0000000000000000000012121121")) 98 print(int("-0000000000000000000012121121"))View Code
6、__str__ 魔術方法
觸發時機: 使用print(物件)或者str(物件)的時候觸發
功能: 檢視物件
引數: 一個self接受當前物件
返回值: 必須返回字串型別
1 class Cat(): 2 gift = "抓老鼠" 3 def __init__(self,name): 4 self.name = name 5 6 def cat_info(self): 7 return "小貓名字叫{},天賦是{}".format(self.name,self.gift) 8 9 def __str__(self): 10 return self.cat_info() 11 12 # (瞭解) __repr__ = __str__ 13 14 tom = Cat("湯姆") 15 # 第一種觸發方式 16 # print(tom) 17 # 第二種觸發方法 18 res = str(tom) 19 print(res) 20 21 22 res = repr(tom) 23 print(res)View Code
7、__repr__ 魔術方法
觸發時機: 使用repr(物件)的時候觸發
功能: 檢視物件,與魔術方法__str__相似
引數: 一個self接受當前物件
返回值: 必須返回字串型別
1 class Mouse(): 2 gift = "遛貓" 3 4 def __init__(self,name): 5 self.name = name 6 7 def mouse_info(self): 8 return "老鼠的名字{},天賦是{}".format(self.name,self.gift) 9 10 def __repr__(self): 11 return self.mouse_info() 12 13 14 jerry = Mouse("傑瑞") 15 res = repr(jerry) 16 print(res) 17 18 # 在列印或者str(物件) 仍然可以觸發__repr__ 19 # 原因: 系統在底層加入瞭如下語句: __str__ = __repr__ 20 print(jerry) 21 res = str(jerry) 22 print(res)View Code
8、__bool__ 魔術方法
觸發時機:使用bool(物件)的時候自動觸發
功能:強轉物件
引數:一個self接受當前物件
返回值:必須是布林型別
類似的還有如下等等(瞭解):
__complex__(self) 被complex強轉物件時呼叫
__int__(self) 被int強轉物件時呼叫
__float__(self) 被float強轉物件時呼叫
1 class MyClass(): 2 def __bool__(self): 3 return False 4 5 obj = MyClass() 6 # 強轉物件時自動觸發 7 print(bool(obj))View Code
9、_add__ 魔術方法 (與之相關的 __radd__ 反向加法)
觸發時機:使用物件進行運算相加的時候自動觸發
功能:物件運算
引數:二個物件引數
返回值:運算後的值
類似的還有如下等等(瞭解):
__sub__(self, other) 定義減法的行為:-
__mul__(self, other) 定義乘法的行為:
__truediv__(self, other) 定義真除法的行為:
1 class MyClass(): 2 def __init__(self,num): 3 self.num = num 4 5 # 物件 在加號的左邊,自動觸發__add__魔術方法 6 def __add__(self,other): 7 print(self) # a 8 print(other)# 5 9 return self.num + other # 15 10 11 # 物件 在加號的右邊,自動觸發__radd__魔術方法 12 def __radd__(self,other): 13 print(self) # b 14 print(other)# 3 15 return self.num + 2 * other 16 17 # 寫法一 18 a = MyClass(10) 19 res = a + 5 20 print(res) 21 22 # 寫法二 23 b = MyClass(5) 24 res = 3 + b 25 print(res) 26 27 # 寫法三 28 """ 29 先觸發add方法:self => a , other => b return self.num + other => return 10 + b => res = 10 + b 30 再觸發radd方法:self => b , other => 10 return 5 + 2 * 10 = 5 + 20 = 25 31 """ 32 res = a + b 33 print(res) 34 35 # 25 25 25View Code
10、__len__ 魔術方法
觸發時機:使用len(物件)的時候自動觸發
功能:用於檢測物件中或者類中某個內容的個數
引數:一個self接受當前物件
返回值:必須返回整型
1 class MyClass(): 2 pty1 = 1 3 pty2 = 2 4 __pty3 = 3 5 __pty4 = 3 6 7 def func1(): 8 pass 9 def func2(): 10 pass 11 def __func3(): 12 pass 13 14 def __len__(self): 15 # 基本寫法 16 """ 17 lst = [] 18 print(MyClass.__dict__) 19 dic = MyClass.__dict__ 20 for i in dic: 21 print(i,type(i)) 22 if not (i.startswith("__") and i.endswith("__")): 23 lst.append(i) 24 return len(lst) 25 """ 26 27 # 優化程式碼 28 return len([i for i in MyClass.__dict__ if not (i.startswith("__") and i.endswith("__"))]) 29 30 31 32 obj = MyClass() 33 res = len(obj) 34 print(res)View Code
觸發時機:把物件當作函式呼叫的時候自動觸發功能: 模擬函式化操作引數: 引數不固定,至少一個self引數返回值: 看需求