python:物件導向和類

來源:互聯網
上載者:User

標籤:變數   connect   erro   count   pdb   程式   等等   int   多繼承   


面向過程和物件導向編程思想:
物件導向--Object Oriented Programming,簡稱oop,是一種程式設計思想。在說物件導向之前,先說一下什麼是編程範式,編程範式你按照什麼方式來去編程,去實現一個功能。舉個例子,你要做飯,
可以用電磁爐,也可以用瓦斯灶。不同的編程範式本質上代表對各種類型的任務採取的不同的解決問題的思路,兩種最重要的編程範式分別是面向過程編程和物件導向編程。
提到物件導向,就不得不提到另一種編程思想,面向過程;什麼是面向過程呢,面向過程的思想是把一個項目、一件事情按照一定的順序,從頭到尾一步一步地做下去,先做什麼,後做什麼,一直到結束。這
種思想比較好理解,其實這也是一個人做事的方法,我們之前編程的思想也都是使用這種思想。這種編程思想,只要前面有一個步驟變了,那麼後面的就也要變,後面維護起來比較麻煩,這樣的編程思想,我
們在寫一些簡單的小程式、只執行一次的指令碼時可以使用。而物件導向呢,物件導向的思想是把一個項目、一件事情分成更小的項目,或者說分成一個個更小的部分,每一部分負責什麼方面的功能,最後再由
這些部分組合而成為一個整體。這種思想比較適合多人的分工合作,就像一個大的機關,分各個部門,每個部門分別負責某樣職能,各個部門可以充分發揮自己的特色,只要符合一定前提就行了。
舉個例子:比如剛才說的一個大的機關,要做某一個項目,從面向過程的思想來說,應該是這樣分析的,先怎麼樣,再怎麼樣,最後怎麼樣。第一樣應該如何完成,第二樣應該如何完成等等。等到每一步驟都
完成,項目也就完成了。而物件導向的思想則應該是這樣想的,這個項目是由幾個部分組成的,我們就做好分工,成立一個部門來做一個部分的功能,另一個部門來做另一個部分。各個部門可以不用理解其他
部門的事,只要完成自己那一部分的事情就OK了。

物件導向的特性:類,對象,執行個體化
類:class
類,對比現實世界來說就是一個種類,一個模型。
一個類即是對一類擁有相同屬性的對象的抽象、藍圖、原型。
在類中定義了這些對象的都具備的屬性(variables(data))、共同的方法。
對象:object
對象,也叫執行個體,也就是指模型造出來的具體的東西。
一個對象即是一個類的執行個體化後執行個體,一個類必須經過執行個體化後方可在程式中調用,一個類可以執行個體化多個對象,每個對象亦可以有不同的屬性,就像人類是指所有人,每個人是指具體的對象,
人與人之前有共性,亦有不同。
執行個體化:
初始化一個類,造了一個對象。把一個類變成一個具體的對象的過程,叫做執行個體化。
屬性:
比如說汽車的顏色、品牌、排量;即變數
功能:
比如汽車有導航、聽歌、跑等的功能;即函數
class BuyCar(object):
#新式類
pass
class BuyCar2:
#經典類
pass
#python3裡面經典類和新式類沒有任何的區別,寫的時候一般用新式類

#建立類
class BuyCar(object): #object是基類
def sale(self): #類裡面函數預設加上self,不寫會報錯
#self代表執行個體化之後的這個對象,為了節省記憶體而設計的
print(‘賣車‘)
def insurance(self):
print(‘買保險‘)
def check(self):
print(‘驗車‘)
def card(self):
print(‘選牌‘)
def pay(self):
print(‘付款‘)
def done(self):
print(‘完成‘)
#類不能是直接用;能用的是執行個體或對象

#執行個體化:
me=BuyCar() #這個過程就是執行個體化對象,me是執行個體,也叫對象
#如果是函數名加括弧,就是調用函數
#如果是類名加括弧,就是執行個體化對象
me.sale()
me.check()
me.card() #執行個體化後,對象就可以調用類裡面的方法(即函數)

# 構造方法、析構方法:
class Car(object):
wheel=4 #此處的wheel叫類變數,所有的執行個體都可以使用;直接self.wheel就可以使用
def __init__(self,colors,pls,pzs): #__init__是構造方法
#構造方法在執行個體化這個類的時候就會執行,其他的方法必須調用才能執行
#如果想在類初始化的時候給它傳一些參數,那就要在構造方法裡面寫參數
self.color=colors
#給執行個體化的對象添加屬性;此處的color pl pz 叫執行個體變數,區別於類變數
self.pl=pls
self.pz=pzs
def __del__(self):
#析構方法:作用是1.對象被銷毀時(del 執行個體化對象)執行
#2.程式運行完成之後執行,類的生命週期結束時調用解構函式,然後釋放記憶體
print(‘over...‘)
def driver(self):
print(‘汽車的顏色是:‘,self.color)
self.run()
#self在類裡面代表執行個體化的對象,直接點.可以點出來定義的屬性和方法
print(‘driver‘)
def run(self):
print(‘run‘)
your_car=Car(‘red‘,‘5.0‘,‘悍馬‘) #構造方法裡的傳參在執行個體化時直接填參數就可

例子:
import pymysql
class MyDbError(Exception):
def __str__(self):
return ‘資料庫連接錯誤‘
class MyDb(object):
def __init__(self,host,user,passwd,db,port=3306,charset=‘utf8‘):
try:
self.conn=pymysql.connect(
host=host,user=user,passwd=passwd,
db=db,port=port,charset=charset
)
except Exception as e:
raise MyDbError
#主動拋出異常,有raise的話,程式出異常就不會再往下進行
else:
self.cur=self.conn.cursor(cursor=pymysql.cursors.DictCursor)

def select(self,sql):
try:
self.cur.execute(sql)
except Exception as e:
return e
return self.cur.fetchall()
def other(self,sql):
try:
self.cur.execute(sql)
except Exception as e:
return e
self.conn.commit()
return self.cur.rowcount
#如果sql執行成功,返回影響的行數
def __del__(self):
self.cur.close()
self.conn.close() #這個類不用的時候,就執行析構方法,關閉資料庫

#私人變數和私人方法:
import xlrd
class ReadCase(object):
__name=‘hahaha‘
#類變數加倆底線是私人變數;只能在類裡面用,出了類就不行了
#比如出了這個類,執行個體化為r,r.__name是錯的,而且也點不出來
def __set(self):
self.money=259999
#函數名前加倆底線是私人方法
#只能在類裡面調用,出了類訪問不了
def __init__(self,f_name):
self.fname=f_name
def read_case(self):
book=xlrd.open_workbook(self.fname)
pass
r=ReadCase(‘a.xls‘)


封裝:
把一些功能的實現細節不對外暴露,類中對資料的賦值、內部調用對外部使用者是透明的,這使類變成了一個膠囊或容器,裡麵包含著類的資料和方法。

比如說造的一個人,你把他身體內部的什麼心肝脾肺腎都封裝起來了,其他人都看不到,你直接找這個人。

繼承:
一個類可以派生出子類,在這個父類裡定義的屬性、方法自動被子類繼承。比如說你繼承了你父親的姓。
python3中多繼承都是廣度優先,python2中經典類的多繼承是深度優先,新式類的多繼承是按照廣度優先的。
繼承是為了代碼的重用
eg1:
class Person(object):
def __init__(self,,name,sex):
self.name=name
self.sex=sex
def cry(self):
print(‘哭‘)
class Man(Person): #括弧裡填入Person,就是繼承了Person的屬性和方法
def work(self):
print(‘working...‘)
hn=Man(‘hn‘,‘nv‘) #執行個體化Man,因為繼承了Person,所以執行個體化時也得傳參
hn.name
hn.cry()
#執行個體化的Man,可以調用Person的方法和屬性
eg2:
class Children(Person,Man): #可以繼承多個類
pass
hh=Children(‘hh‘,‘nan‘)
hh.work()
hh.cry()
#多繼承,Person Man有的方法和屬性,Children都有
#多繼承,如果被繼承的幾個類裡有名字形同的函數,那繼承者繼承的方法是括弧裡排最前的類,這種在python3裡叫廣度優先
#在python2裡,如果是經典類的話,是深度優先;新式類的話,還是廣度優先


多態(python不直接支援):
對不同類的對象發出相同的訊息將會有不同的行為。比如,你的老闆讓所有員工在九點鐘開始工作, 他只要在九點鐘的時候說:“開始工作”即可,而不需要對銷售人員說:“開始銷售工作”,
對技術人員說:“開始技術工作”, 因為“員工”是一個抽象的事物, 只要是員工就可以開始工作,他知道這一點就行了。至於每個員工,當然會各司其職,做各自的工作。
多態就是抽象化的一種體現,把一系列具體事物的共同點抽象出來, 再通過這個抽象的事物, 與不同的具體事物進行對話。
一種方法,多種實現。
eg1:
class My(object):
def say(self,msg):
print(msg)
def say(self,age,sex):
print(age,sex)
def say(self,addr,phone,money):
print(addr,phone,money)
#java裡,多態是這麼實現的,通過不同的參數,調用函數
#在python,裡函數名不能重複,不能這麼寫;但可以間接實現多態,見下面eg2
eg2
class Cat(object):
def speak(self):
print(‘喵喵喵‘)
class Dog(object):
def speak(self):
print(‘汪汪汪‘)
c=Cat()
d=Dog()
obj=[c,d]
for i in obj:
i.speak() #通過這種方法間接實現多態;但不經常用

重寫父類的構造方法、__str__方法
重寫父類的構造方法時,必須要先調用一下父類的構造方法,例子見下面:
class OpDb(object):
def __init__(self,ip,passwd,port,db):
self.ip=ip
self.passwd=passwd
self.port=port
self.db=db
import redis
class MyRedis(OpDb):
def set(self,k,v):
r=redis.Redis(host=self.ip,port=self.port,passwd=self.passwd,)
r.set(k,v)
class MySql(OpDb):
def __init__(self,ip,passwd,port,db,user,charset=‘utf8‘):
# MySql繼承父類OpDb,但它倆都有__init__方法,執行個體化MySql的時候,調用的是MySql自己的__init__方法
OpDb.__init__(self,ip,passwd,port,db)
#想用到父類OpDb的__init__這個方法的話,還得先要調用一下父類的這個方法
#如果此處不調用OpDb的__init__方法,就要寫上self.ip=ip self.passwd=passwd等,比較麻煩而且low
#super(OpDb,self).__init__(ip,passwd,port,db)
#super這個句子和上面調用父類OpDb的__init__方法的效果是一模一樣的,super這個比較進階一點
self.user=user
self.charset=charset
def __str__(self):
return "這個是執行sql的類"
Hn_Mysql=Mysql(‘192.168.1.1‘,‘123456‘,3306,‘test‘,‘root‘)
print(Hn_Mysql) #列印的結果不是Hn_Mysql的記憶體位址,而是"這個是執行sql的類",__str__方法就是這個用途

靜態方法、類方法:
class Stu(object):
country = ‘china‘ # 類變數
def __init__(self, name):
self.name = name
@staticmethod
def say():
# 靜態方法,加了staticmethod裝飾器的函數,括弧裡不用寫self了,和類本身沒有什麼關係了,就相當於在類裡面定義了一個方法而已
print(‘xxx‘)
@classmethod
def hello(cls):
# 這個叫類方法,和靜態方法不同的是,它可以使用類變數,必須要傳一個cls,代表的就是這個類
print(cls.country)
def hi(self):
# 這個是執行個體方法
print(self.name)
t = Stu(‘name‘)
Stu.hello()
Stu.say()
t.hi()
t.say()
t.hello()

python:物件導向和類

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.