類
屬性
實例變量 每一個實例的變量
類變量 全部實例共享的變量,共享內存,13億人都是實例的花 國際都是中國,只用存一份
私有屬性 __var
方法
構造方法 __init__(self)初始化實例,執行的初始化動做
析構方法 實例銷燬時釋放時自動執行的方法(默認有析構函數,只不過什麼都沒幹),寫了的話至關於重構析構方法
私有方法html
面向過程的程序設計:核心是過程二字,過程指的是解決問題的步驟,即先幹什麼再幹什麼......面向過程的設計就比如精心設計好一條流水線,是一種機械式的思惟方式。python
優勢是:複雜度的問題流程化,進而簡單化(一個複雜的問題,分紅一個個小的步驟去實現,實現小的步驟將會很是簡單)linux
缺點是:一套流水線或者流程就是用來解決一個問題,生產汽水的流水線沒法生產汽車,即使是能,也得是大改,改一個組件,牽一髮而動全身。c++
應用場景:一旦完成基本不多改變的場景,著名的例子有Linux內核,git,以及Apache HTTP Server等。git
面向對象的程序設計:核心是對象二字,(要理解對象爲什麼物,必須把本身當成上帝,上帝眼裏世間存在的萬物皆爲對象,不存在的也能夠創造出來。面向對象的程序設計比如如來設計西遊記,如來要解決的問題是把經書傳給東土大唐,如來想了想解決這個問題須要四我的:唐僧,沙和尚,豬八戒,孫悟空,每一個人都有各自的特徵和技能(這就是對象的概念,特徵和技能分別對應對象的數據屬性和方法屬性),然而這並很差玩,因而如來又安排了一羣妖魔鬼怪,爲了防止師徒四人在取經路上被搞死,又安排了一羣神仙保駕護航,這些都是對象。而後取經開始,師徒四人與妖魔鬼怪神仙交互着直到最後取得真經。如來根本不會管師徒四人按照什麼流程去取),對象是特徵與技能的結合體,基於面向對象設計程序就比如在創造一個世界,你就是這個世界的上帝,存在的皆爲對象,不存在的也能夠創造出來,與面向過程機械式的思惟方式造成鮮明對比,面向對象更加註重對現實世界的模擬,是一種「上帝式」的思惟方式。shell
優勢是:解決了程序的擴展性。對某一個對象單獨修改,會馬上反映到整個體系中,如對遊戲中一我的物參數的特徵和技能修改都很容易。數據庫
缺點:編程
1. 編程的複雜度遠高於面向過程,不瞭解面向對象而當即上手基於它設計程序,極容易出現過分設計的問題。一些擴展性要求低的場景使用面向對象會徒增編程難度,好比管理linux系統的shell腳本就不適合用面向對象去設計,面向過程反而更加適合。app
2. 沒法向面向過程的程序設計流水線式的能夠很精準的預測問題的處理流程與結果,面向對象的程序一旦開始就由對象之間的交互解決問題,即使是上帝也沒法準確地預測最終結果。因而咱們常常看到對戰類遊戲,新增一個遊戲人物,在對戰的過程當中極容易出現陰霸的技能,一刀砍死3我的,這種狀況是沒法準確預知的,只有對象之間交互才能準確地知道最終的結果。函數
應用場景:需求常常變化的軟件,通常需求的變化都集中在用戶層,互聯網應用,企業內部軟件,遊戲等都是面向對象的程序設計大顯身手的好地方
面向對象的程序設計並非所有。對於一個軟件質量來講,面向對象的程序設計只是用來解決擴展性。
類即類別、種類,是面向對象設計最重要的概念,對象是特徵與技能的結合體,而類則是一系列對象類似的特徵與技能的結合體
那麼問題來了,先有的一個個具體存在的對象(好比一個具體存在的人),仍是先有的人類這個概念,這個問題須要分兩種狀況去看
在現實世界中:先有對象,再有類
世界上確定是先出現各類各樣的實際存在的物體,而後隨着人類文明的發展,人類站在不一樣的角度總結出了不一樣的種類,如人類、動物類、植物類等概念
也就說,對象是具體的存在,而類僅僅只是一個概念,並不真實存在
在程序中:務必保證先定義類,後產生對象
這與函數的使用是相似的,先定義函數,後調用函數,類也是同樣的,在程序中須要先定義類,後調用類
不同的是,調用函數會執行函數體代碼返回的是函數體執行的結果,而調用類會產生對象,返回的是對象
按照上述步驟,咱們來定義一個類(咱們站在老男孩學校的角度去看,在座的各位都是學生)
#在程序中,務必保證:先定義(類),後使用(產生對象) PS: 1. 在程序中特徵用變量標識,技能用函數標識 2. 於是類中最多見的無非是:變量和函數的定義 #程序中的類 class OldboyStudent: school='oldboy' def learn(self): print('is learning') def eat(self): print('is eating') def sleep(self): print('is sleeping') #注意: 1.類中能夠有任意python代碼,這些代碼在類定義階段便會執行 2.於是會產生新的名稱空間,用來存放類的變量名與函數名,能夠經過OldboyStudent.__dict__查看 3.對於經典類來講咱們能夠經過該字典操做類名稱空間的名字(新式類有限制),但python爲咱們提供專門的.語法 4.點是訪問屬性的語法,類中定義的名字,都是類的屬性 #程序中類的用法 .:專門用來訪問屬性,本質操做的就是__dict__ OldboyStudent.school #等於經典類的操做OldboyStudent.__dict__['school'] OldboyStudent.school='Oldboy' #等於經典類的操做OldboyStudent.__dict__['school']='Oldboy' OldboyStudent.x=1 #等於經典類的操做OldboyStudent.__dict__['x']=1 del OldboyStudent.x #等於經典類的操做OldboyStudent.__dict__.pop('x') #程序中的對象 #調用類,或稱爲實例化,獲得對象 s1=OldboyStudent() s2=OldboyStudent() s3=OldboyStudent() #如此,s一、s二、s3都同樣了,而這三者除了類似的屬性以外還各類不一樣的屬性,這就用到了__init__ #注意:該方法是在對象產生以後纔會執行,只用來爲對象進行初始化操做,能夠有任意代碼,但必定不能有返回值 class OldboyStudent: ...... def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex ...... s1=OldboyStudent('李坦克','男',18) #先調用類產生空對象s1,而後調用OldboyStudent.__init__(s1,'李坦克','男',18) s2=OldboyStudent('王大炮','女',38) s3=OldboyStudent('牛榴彈','男',78) #程序中對象的用法 #執行__init__,s1.name='牛榴彈',很明顯也會產生對象的名稱空間 s2.__dict__ {'name': '王大炮', 'age': '女', 'sex': 38} s2.name #s2.__dict__['name'] s2.name='王三炮' #s2.__dict__['name']='王三炮' s2.course='python' #s2.__dict__['course']='python' del s2.course #s2.__dict__.pop('course')
class OldboyStudent: school='oldboy' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def learn(self): print('%s is learning' %self.name) #新增self.name def eat(self): print('%s is eating' %self.name) def sleep(self): print('%s is sleeping' %self.name) s1=OldboyStudent('李坦克','男',18) s2=OldboyStudent('王大炮','女',38) s3=OldboyStudent('牛榴彈','男',78)
#類變量的用途?你們公用的屬性
#析構函數:在實例釋放、銷燬的時候執行的,一般用於作一些收尾工做,如關閉一些數據庫鏈接,打開的臨時文件
#封裝
#繼承
#多態
class Role(object):
n = 123 #類變量
n_list = []
name = '我是類name'#實例變量沒有的話,會找類變量
def __init__(self,name,role,weapon,life_value=100,money=10000):#
#構造函數
#在實例化時作一些類的初始化的工做
self.name = name#r1.name=name賦給實例,實例變量,又叫靜態屬性。動態的傳入,吧變量存到self至關於r1,不然函數中的name=name局部變量隨函數結束就消失了存不下來
self.role = role#實例變量,做用域就是實例自己
self.weapon = weapon
self.__life_value = life_value
self.money = money
def shot(self):#類的方法,動態屬性(也算一個屬性,執行過程),功能,仍是在類中
print("%s 射擊"%(self.name))
def got_shot(self):
self.__life_value -= 50
print("life_value:%s"%(self.__life_value))
def show_status(self):
print("name:%s life_value:%s"%(self.name,self.__life_value))
def buy_gun(self,gun_name):
print("%s buy a %s"%(self.name,gun_name))
def who_weapon(self):
print("%s has weapon %s"%(self.name,self.weapon))
def __del__(self):#傳不了參數,在實例結束的時候自動執行的
print("%s 完全死了。。。"%(self.name))
print(Role.n)#類的變量存在類的內存中,不用實例化就能打印
Role('alex','police','ak47').shot()#用完了就會銷燬的
Role('alex','police','ak47').shot()#新造的,和上一個不同,內存中的地址不一樣
r1 = Role('alex','police','ak47')#Role('r1','alex','police','ak47')吧一個類變成一個具體對象的過程叫實例化 ,又叫初始化一個類,造了一個對象,賦值給一個變量,在內存中生成。開闢一塊內存,存入屬性
r1.name = 'ronghui'#在外面能夠從新賦值給self.name
r1.bullet_prove = True#對於已經實例化的對象,能夠加新的屬性。至關於self.bullet_prove = bullet_prove
r1.buy_gun('ak47')#內部轉成Role.buy_gun(r1) def buy_gun(self)必須有self,誰調用這個類,誰就是self
r1.n_list.append('from r1')
r2 = Role('jack','terrorist','B22') #生成一個角色
r2.shot()#Role.shot
r2.n_list.append('from r2')
print(Role.name,r1.name,r2.name,r1.bullet_prove)
print(r2.weapon)
#del r2.weapon #刪除一個屬性
r2.who_weapon()
r1.n = '改類變量'#在r1的內存里加了個 n='改類變量' 默認找r1中的n
print(r1.n)#實際上是在r1的內存中建立了個新的變量n
print(r2.n)#r2沒有n,因此去類變量中找
Role.n = 'ABC'
print(r1.n,r2.n)#r1永遠是本身的實例變量,r2沒有實例變量n,因此只能去找類變量
print(r1.n_list,r2.n_list,Role.n_list)
r3 = Role('chenronghua','police','M4A1')
r3.got_shot()
r3.show_status()
類中定義的函數(沒有被任何裝飾器裝飾的)是類的函數屬性,類可使用,但必須遵循函數的參數規則,有幾個參數須要傳幾個參數
OldboyStudent.learn(s1) #李坦克 is learning OldboyStudent.learn(s2) #王大炮 is learning OldboyStudent.learn(s3) #牛榴彈 is learning
類中定義的函數(沒有被任何裝飾器裝飾的),其實主要是給對象使用的,並且是綁定到對象的,雖然全部對象指向的都是相同的功能,可是綁定到不一樣的對象就是不一樣的綁定方法
強調:綁定到對象的方法的特殊之處在於,綁定給誰就由誰來調用,誰來調用,就會將‘誰’自己當作第一個參數傳給方法,即自動傳值(方法__init__也是同樣的道理)
s1.learn() #等同於OldboyStudent.learn(s1) s2.learn() #等同於OldboyStudent.learn(s2) s3.learn() #等同於OldboyStudent.learn(s3)
注意:綁定到對象的方法的這種自動傳值的特徵,決定了在類中定義的函數都要默認寫一個參數self,self能夠是任意名字,可是約定俗成地寫出self。
類即類型
提示:python的class術語與c++有必定區別,與 Modula-3更像。
python中一切皆爲對象,且python3中類與類型是一個概念,類型就是類
#類型dict就是類dict >>> list <class 'list'> #實例化的到3個對象l1,l2,l3 >>> l1=list() >>> l2=list() >>> l3=list() #三個對象都有綁定方法append,是相同的功能,但內存地址不一樣 >>> l1.append <built-in method append of list object at 0x10b482b48> >>> l2.append <built-in method append of list object at 0x10b482b88> >>> l3.append <built-in method append of list object at 0x10b482bc8> #操做綁定方法l1.append(3),就是在往l1添加3,絕對不會將3添加到l2或l3 >>> l1.append(3) >>> l1 [3] >>> l2 [] >>> l3 [] #調用類list.append(l3,111)等同於l3.append(111) >>> list.append(l3,111) #l3.append(111) >>> l3 [111]
class Garen: #定義英雄蓋倫的類,不一樣的玩家能夠用它實例出本身英雄; camp='Demacia' #全部玩家的英雄(蓋倫)的陣營都是Demacia; def __init__(self,nickname,aggressivity=58,life_value=455): #英雄的初始攻擊力58...; self.nickname=nickname #爲本身的蓋倫起個別名; self.aggressivity=aggressivity #英雄都有本身的攻擊力; self.life_value=life_value #英雄都有本身的生命值; def attack(self,enemy): #普通攻擊技能,enemy是敵人; enemy.life_value-=self.aggressivity #根據本身的攻擊力,攻擊敵人就減掉敵人的生命值。
class Riven: camp='Noxus' #全部玩家的英雄(銳雯)的陣營都是Noxus; def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻擊力54; self.nickname=nickname #爲本身的銳雯起個別名; self.aggressivity=aggressivity #英雄都有本身的攻擊力; self.life_value=life_value #英雄都有本身的生命值; def attack(self,enemy): #普通攻擊技能,enemy是敵人; enemy.life_value-=self.aggressivity #根據本身的攻擊力,攻擊敵人就減掉敵人的生命值。
實例出倆英雄
>>> g1=Garen('草叢倫') >>> r1=Riven('銳雯雯')
>>> g1.life_value 455 >>> r1.attack(g1) >>> g1.life_value 401
class Garen:
camp='Demacia'
def __init__(self,nickname,
aggressivity=58,
life_value=455,
money=100,
armor=10):
self.nickname=nickname
self.aggressivity=aggressivity
self.life_value=life_value
self.money=money
self.armor=armor
def attack(self,enemy):
damage_value=self.aggressivity-enemy.armor
enemy.life_value-=damage_value
def tell(self):
print('英雄屬性 nickname:%s aggressivity:%s life_value:%s money:%s armor:%s'%(self.nickname, self.aggressivity,self.life_value,self.money,self.armor))
class Riven:
camp='netuox'
def __init__(self,nickname,
aggressivity=60,
life_value=300,
money=1000,
armor=20):
self.nickname=nickname
self.aggressivity=aggressivity
self.life_value=life_value
self.money=money
self.armor=armor
def attack(self,enemy):
damage_value=self.aggressivity-enemy.armor
enemy.life_value-=damage_value
def tell(self):
print('英雄屬性 nickname:%s aggressivity:%s life_value:%s money:%s armor:%s'%(self.nickname, self.aggressivity,self.life_value,self.money,self.armor))
class BlackCleaver:
def __init__(self,price=500,aggressivity=10000,life_value=10000):
self.price = price
self.aggressivity = aggressivity
self.life_value = life_value
def update(self,obj):
obj.money -= self.price
obj.aggressivity += self.aggressivity
obj.life_value += self.life_value
obj.tell()
def fire(self,obj): #這是該裝備的主動技能,噴火,燒死對方
obj.life_value-=1000 #假設火燒的攻擊力是1000
g1 = Garen('草叢倫')
r1 = Riven('瑞文文')
b1 = BlackCleaver()
r1.b1=b1
r1.b1.fire(g1)
print(g1.life_value)
if r1.money > b1.price:
b1.update(r1)
r1.attack(g1)
print(g1.life_value)