首先我是辣雞,而後這個問題的確有點意思python
首先,類是一個集合,包含了數據,操做描述的一個抽象集合web
你能夠首先只把類當作一個容器來使用ide
class Cycle: def __init__(self,r): self.pi=3.14 self.r=r a=Cycle(4) b=Cycle(7)
你看,咱們定義了一個 Cycle 類,咱們如今只是將它當作一個數據集合來用,咱們利用其實例之間彼此數據隔離的特性來保證具體的實例數據彼此不污染。好了你如今想問,爲何咱們要用數據集合來放數據函數
好了,咱們來看看沒有類以前咱們會怎麼樣,假設咱們如今要計算圓的面積學習
''' 遇到問題沒人解答?小編建立了一個Python學習交流QQ羣:579817333 尋找有志同道合的小夥伴,互幫互助,羣裏還有不錯的視頻學習教程和PDF電子書! ''' def square(r,pi): return pi * (r**2) PI=3.14 a_r=4 a_square=square(a_r,PI) b_r=7 b_square=square(b_r,PI)
看起來沒有問題,好了,如今問題來了,假如,你如今要計算不少圓的面積,那麼你是否是發現,不斷的用變量命來隔離數據方式變得愈來愈髒了。並且你發現是否是有不少冗餘的代碼優化
好了咱們這麼改一改code
class Cycle: def __init__(self,r): self.pi=3.14 self.r=r def square(value): if not isinstance(value,Cycle): raise ValueError("value muse be Cycle instace") value.square=value.pi * (value.r**2) a=Cycle(4) b=Cycle(7) square(a) square(b)
好了,你有沒有以爲如今清晰了一點。視頻
好了,如今咱們如今還能夠改一下對象
''' 遇到問題沒人解答?小編建立了一個Python學習交流QQ羣:579817333 尋找有志同道合的小夥伴,互幫互助,羣裏還有不錯的視頻學習教程和PDF電子書! ''' class Cycle: def __init__(self,r): self.pi=3.14 self.r=r def square(self,value): return self.pi * (self.r**2)
好了,如今你可能迷惑了,咱們爲啥要把 square 函數放在類中?繼承
好了,我如今要計算長方形,原型,梯形各類各樣二維幾何圖形的面積,這樣該怎麼寫???
你想了想咱們以前說的將類做爲數據容器,你想了想寫了以下的代碼
class Rectangle: def __init__(self,length,height): self.length=length self.height=height class Cycle: def __init__(self,r): self.pi=3.14 self.r=r def rec_square(value): if not isinstance(value,Rectangle): raise ValueError("value muse be Rectangle instace") value.square=value.length * value.height def cycle_square(value): if not isinstance(value,Cycle): raise ValueError("value muse be Cycle instace") value.square=value.pi * (value.r**2)
你想想,這樣是否是感受若是計算需求愈來愈多,代碼是否是仍是會愈來愈髒?
若是咱們將函數放在類裏,而且用繼承的特性,咱們能夠寫出這樣的代碼
''' 遇到問題沒人解答?小編建立了一個Python學習交流QQ羣:579817333 尋找有志同道合的小夥伴,互幫互助,羣裏還有不錯的視頻學習教程和PDF電子書! ''' class Geometry: def get_square(self): raise NotImplementedError class Rectangle(Geometry): def __init__(self,length,height): self.length=length self.height=height def get_square(self): return self.length*self.height class Cycle(Geometry): def __init__(self,r): self.pi=3.14 self.r=r def get_square(self): return self.pi * (self.r**2) def square(value): if not isinstance(value,Geometry): raise ValueError("value muse be Geometry instace") value.square=value.get_square()
你看,咱們如今只須要給用戶暴露一個統一的接口,用戶(用戶也以是咱們本身)不須要關心怎麼樣選擇正確的函數,他只須要調用統一的 square 函數,就能夠獲取到具體的面積,是否是輕鬆不少了??
因此,類,它是對數據,操做的一種封裝,這個封裝的意義在於咱們能夠去更好的優化代碼結構。
好了再舉一個例子,咱們能夠用類來控制訪問權限
class People: def __init__(self,website): self.__favorite_website="1024.com" def bad_or_not(self): return self.__favorite_website=="1024.com"
你看,咱們用 private 變量,來確保外部無法直接訪問一些敏感數據(實際上 Python 裏 private 並不嚴格,hook 一下仍是能夠訪問的)
好,在舉一個例子
''' 遇到問題沒人解答?小編建立了一個Python學習交流QQ羣:579817333 尋找有志同道合的小夥伴,互幫互助,羣裏還有不錯的視頻學習教程和PDF電子書! ''' class People: def __init__(self,website): self.__favorite_website="1024.com" def bad_or_not(self): return self.__favorite_website=="1024.com" @property def favorite_website(self): return self.__favorite_website @favorite_website.setter def favorite_website(self,value): if value=="1024.com": raise ValueError("你不能去草榴,兄弟,你養分不足") self.__favorite_website=value
你看,咱們如今很方便的實如今設置數據值的時候,對其過濾。
撤了這麼多,回到你的問題
首先A君說的沒毛病,但我想知道僅僅使用函數錘子,螺絲刀來完成一個項目比使用Class工廠+函數錘子來完成一個項目的效率會更低麼?
理由是什麼?大神在何時會考慮使用Class來提升代碼的「執行效率」和代碼的「可讀性」。迴歸實際狀況,我不少時候都是調用同一個函數/方法去輸出某個結果。
至今還想不出爲何調用Class會更方便?(PS:本人大菜鳥,寫了上千行代碼了,但仍然搞不懂什麼狀況下須要用到Class類。也曾嘗試在本身的代碼中強行加入Class輸出結果
但感受不靈活,並且要寫的代碼明顯多了也不便於理解。求大神舉例,碾壓個人無知!)。C君說大型項目不使用Class調用對象會累死,到底這個「累死」體如今哪裏?
首先一個問題,我整個答案裏所寫的這些代碼,不用面向對象這一套能不能實現?
很明顯,能。
可是實現的乾淨麼?我的以爲不乾淨。
項目規格上去後,咱們若是按照傳統的方式進行開發,務必要多重檢查,確保本身不會手抖調用了錯誤的東西。而 OOP 這一套思想,其實就是經過利用合適的代碼結構和封裝,某種程度上來說是減小咱們犯錯的可能。
同時,如今開發基本都不是一我的的單打獨鬥,你寫的代碼可能會被其他人使用與維護。咱們有個前提,要假設使用維護你代碼的人都是傻逼。咱們要適當的封裝代碼,優化結構,讓使用者儘量的少犯錯、
因此最後,不管是各個語言的變量命名規則也好,仍是 OOP 這一套範式也好。其本質是在自由度與可讀性可維護性之間的一種相對較優的妥協,這種妥協根本的目的就在於經過規範化的操做與封裝,減小團隊開發維護的成本,優化開發體驗。
另外,關於開發這一套還有個老生常談的問題過分封裝。我我的的觀點是在你知道什麼是 過分封裝 以前,你不必考慮這個問題,按照教科書和開源代碼裏的結構,去不斷封裝優化你的代碼。
面向對象 更容易使用 ,缺點就是 換一個開發人,難維護,很難理解前面人的思惟,出了錯很差找位置