標籤:伺服器 實現機制 也會 機制 nts 方式 歐美 練習 執行
本節內容一、編程範式
編程指的是寫程式、敲代碼,就是指程式員用特定的文法、資料結構和演算法編寫的代碼,目的是來告訴電腦如何執行任務的。
在編程的世界裡最常見的兩大流派是:面向過程與物件導向。“功夫的流派沒有高低之分,只有習武的人才有高低之分“,在編程世界裡更是這樣,面向過程與物件導向在不同的情境下都各有優劣,誰好誰壞不能一概而論。
二、面向過程的程式設計
核心是“過程”二字,“過程”指的是解決問題的步驟,即先幹什麼再幹什麼......,基於面向過程設計程式就好比在設計一條流水線,是一種機械式的思維方式。
優點:複雜問題簡單化。
# 寫一個資料遠程備份程式, #分三步,本機資料打包,上傳至雲端服務器,測試備份檔案可用性import osdef data_backup(folder): print("找到備份目錄: %s" %folder) print(‘正在備份......‘) zip_file=‘/tmp/backup20181103.zip‘ print(‘備份成功,備份檔案為: %s‘ %zip_file) return zip_filedef cloud_upload(file): print("\nconnecting cloud storage center...") print("cloud storage connected.") print("upload file...%s...to cloud..." %file) link=‘http://www.xxx.com/bak/%s‘ %os.path.basename(file) print(‘close connection.....‘) return linkdef data_backup_test(link): print("\n下載檔案: %s , 驗證檔案是否無損" %link)def main(): #步驟一:本機資料打包 zip_file = data_backup("c:\\users\\alex\歐美100G高清無碼") #步驟二:上傳至雲端服務器 link=cloud_upload(zip_file) #步驟三:測試備份檔案的可用性 data_backup_test(link)if __name__ == ‘__main__‘: main()面向過程的例子
缺點:擴充性極差。
應用情境:
面向過程的程式設計思想一般用於那些功能一旦實現之後就很少需要改變的情境, 如果你只是寫一些簡單的指令碼,去做一些一次性任務,用面向過程的方式是極好的,著名的例子有Linux內核,git,以及Apache HTTP Server等。但如果你要處理的任務是複雜的,且需要不斷迭代和維護 的, 那還是用物件導向最方便了。
三、物件導向的程式設計
核心是“對象”二字,要理解對象為何物,必須把自己當成上帝,在上帝眼裡,世間存在的萬物皆為對象,不存在的也可以創造出來,與面向過程機械式的思維方式形成鮮明對比,物件導向更加註重對現實世界而非流程的類比,是一種“上帝式”的思維方式。
優點:可擴充性高。
缺點:編程的複雜度遠高於面向過程。
應用情境:當然是應用於需求經常變化的軟體中,一般需求的變化都集中在使用者層,互連網應用,企業內部軟體,遊戲等都是物件導向的程式設計大顯身手的好地方。
四、類與對象
對象是特徵與技能的結合體,而類是一系列對象相似的特徵與技能的結合體。
在現實世界中:肯定是先有對象,再有類;
在程式中:要先定義 類,後產生對象。
定義類
按照上述步驟,我們來定義一個類(我們站在學校的角度去看,在座的各位都是學生)
>>>在現實世界中,先有對象,再有類
對象1:李坦克 特徵: 學校=實中 姓名=李坦克 性別=男 年齡=18 技能: 學習 吃飯 睡覺對象2:王大炮 特徵: 學校=實中 姓名=王大炮 性別=女 年齡=38 技能: 學習 吃飯 睡覺對象3:牛榴彈 特徵: 學校=實中 姓名=牛榴彈 性別=男 年齡=78 技能: 學習 吃飯 睡覺現實中的實中的學生類 相似的特徵: 學校=實中 相似的技能: 學習 吃飯 睡覺
>>>在程式中,務必保證:先定義(類),後使用類(用來產生對象)
#在Python中程式中的類用class關鍵字定義,而在程式中特徵用變數標識,技能用函數標識,因而類中最常見的無非是:變數和函數的定義class SchoolStudent: school=‘實中‘ def learn(self): print(‘is learning‘) def eat(self): print(‘is eating‘) def sleep(self): print(‘is sleeping‘)
注意:
①類中可以有任意的python代碼,這些代碼在類的定義階段就會執行,因而會產生新的名稱空間,用來存放類的變數名與函數名,通過SchoolStudent.__dict__ 就可以查看。
②類中定義的名字,都是類的屬性,點是訪問類屬性的文法。
類的使用
類屬性的 增 刪 改 查
SchoolStudent.school #查SchoolStudent.school=‘University‘ #改SchoolStudent.x=1 #增del SchoolStudent.x #刪
調用類,也成為執行個體化,得到程式中的對象
s1=SchoolStudent()s2=SchoolStudent()s3=SchoolStudent()#如此,s1、s2、s3都一樣了,而這三者除了相似的屬性之外還各種不同的屬性,這就用到了__init__
__init__ 方法
#注意:該方法是在對象產生之後才會執行,只用來為對象進行初始化操作,可以有任意代碼,但一定不能有傳回值# __init__ 方法用來為對象定製對象專屬的特徵class LuffyStudents: school = ‘luffycity‘ # 上下對應 stu1, ‘hyp‘, 22, ‘man‘ def __init__(self, name, age, sex): self.Name = name self.Age = age self.Sex = sex # 相當於 #stu1.Name = ‘hyp‘ #stu1.Age = 22 #stu1.Sex = ‘man‘ def learn(self): print(‘ is learning‘) def eating(self): print(‘ is eating‘)# 後產生對象stu1 = LuffyStudents(‘hyp‘, 22, ‘man‘)print(stu1)"""加上__init__ 方法後,執行個體化的步驟: 1.先產生一個Null 物件 stu1 2.LuffyStudents.__init__(stu1, ‘hyp‘, 22, ‘man‘) print(LuffyStudents.__init__) --> 返回的是 類的函數屬性"""# # 查# print(stu1.__dict__)# print(stu1.Name)## # 改# stu1.Name = ‘lcy‘# print(stu1.__dict__)# print(stu1.Name)## # 刪除# del stu1.Name# print(stu1.__dict__)## # 增加# stu1.class_name = ‘全棧開發‘# print(stu1.__dict__)"""# --> 先產生Null 物件,然後再調__init__,並傳參數 LuffyStudents.__init__(stu2,‘lcy‘, 22, ‘女‘)"""stu2=LuffyStudents(‘lcy‘, 22, ‘女‘)
對象的使用
#執行__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‘)補充:
①站的角度不同,定義出的類是截然不同的;
②現實中的類並不完全等於程式中的類,比如現實中的公司類,在程式中有時需要拆分成部門類,業務類等;
③有時為了編程需求,程式中也可能會定義現實中不存在的類,比如策略類,現實中並不存在,但是在程式中卻是一個很常見的類。
五、類的屬性尋找與Binder 方法類的屬性:
分為 資料屬性 和 函數屬性。
1、類 的 資料屬性 是所有對象共有的,指向的是 同一個記憶體位址。
#類的資料屬性是所有對象共用的,id都一樣print(id(SchoolStudent.school))print(id(s1.school)) #4377347328print(id(s2.school)) #4377347328print(id(s3.school)) #4377347328
2、類的函數屬性 是綁定給 對象 用的,稱為綁定到對象的方法
#類的函數屬性是綁定給對象使用的,obj.method稱為Binder 方法,記憶體位址都不一樣print(SchoolStudent.learn) #<function SchoolStudent.learn at 0x1021329d8>print(s1.learn)# 結果:<bound method SchoolStudent.learn of #<__main__.SchoolStudentobject at 0x1021466d8>>print(s2.learn) # 結果:<bound method SchoolStudent.learn of <__main__.SchoolStudentobject at 0x102146710>>print(s3.learn) # 結果:<bound method SchoolStudent.learn of <__main__.SchoolStudentobject at 0x102146748>>#ps:id是python的實現機制,並不能真實反映記憶體位址,如果有記憶體位址,還是以記憶體位址為準
注意:在obj.name會先從obj自己的名稱空間裡找name,找不到則去類中找,類也找不到就找父類...最後都找不到就拋出異常!
Binder 方法
先定義 類 並執行個體化出三個對象
class SchoolStudent: school=‘實中‘ 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=SchoolStudent(‘李坦克‘,‘男‘,18)s2=SchoolStudent(‘王大炮‘,‘女‘,38)s3=SchoolStudent(‘牛榴彈‘,‘男‘,78)
類中定義的函數(沒有被任何裝飾器修飾的)是類的函數屬性,類可以使用,但必須遵循函數的參數規則,有幾個參數就要傳幾個參數。
SchoolStudent.learn(s1) #李坦克 is learningSchoolStudent.learn(s2) #王大炮 is learningSchoolStudent.learn(s3) #牛榴彈 is learnings1.learn() #等同於SchoolStudent.learn(s1)s2.learn() #等同於SchoolStudent.learn(s2)s3.learn() #等同於SchoolStudent.learn(s3)
類中定義的函數(沒有被任何裝飾器裝飾的),其實主要是給對象使用的,而且是綁定到對象的,雖然所有對象指向的都是相同的功能,但是綁定到不同的對象就是不同的Binder 方法。
強調:
①綁定到對象的方法的特殊之處在於,綁定給誰就由誰來調用,誰來調用,就會將‘誰’本身當做第一個參數傳給方法,即自動傳值(方法__init__也是一樣的道理)
②綁定到對象的方法的這種自動傳值的特徵,決定了在類中定義的函數都要預設寫一個參數self,self可以是任意名字,但是約定俗成地寫出self。
類即類型
python 中 一切皆對象,且python3 中 類與類型是一個概念,類型就是類 。
#類型dict就是類dict>>> list<class ‘list‘>#執行個體化的到3個對象l1,l2,l3>>> l1=list()>>> l2=list()>>> l3=list()#三個對象都有Binder 方法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>#操作Binder 方法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 Student: school = ‘luffycity‘ # 資料 屬性 count = 0 def __init__(self, name, age, sex): # 類 屬性 # self.count += 1 self.name = name self.age = age self.sex = sex Student.count += 1 # 實現共有的屬性 累加 # 有幾個執行個體化對象,就會累加幾次 def learn(self): # 函數 屬性 print(‘%s is learning ‘ %self.name)# 執行個體化出三個對象stu1 = Student(‘hyp‘, ‘male‘, 18)stu2 = Student(‘lcy‘, ‘female‘, 17)stu3 = Student(‘alex‘, ‘male‘, 28)# 只把計數的方法,反映給了 每個對象 專屬的特徵,不能實現累加print(stu1.count)print(stu2.count)print(stu3.count)print(stu1.__dict__)print(stu2.__dict__)print(stu3.__dict__)#print(Student.count)"""練習題二:模仿王者榮耀定義兩個英雄類要求: 英雄需要有 暱稱、攻擊力、生命值 等屬性; 執行個體化出兩個英雄對象; 英雄之間可以互毆,被毆打的一方掉血,血量小於0則判定為死亡。"""class Geren: camp = ‘Demacia‘ def __init__(self, nickname, life_value, aggersivity): self.nickname = nickname self.life_value = life_value self.aggersivity = aggersivity def attack(self, enemy): enemy.life_value -= self.aggersivityclass Riven: camp = ‘Demacia‘ def __init__(self, nickname, life_value, aggersivity): self.nickname = nickname self.life_value = life_value self.aggersivity = aggersivity def attack(self, enemy): enemy.life_value -= self.aggersivityg1 = Geren(‘草叢倫‘, 100, 30)r1 = Riven(‘銳雯‘,80,50)g1.attack(r1)
小練習
Python全棧開發之路 【第七篇】:物件導向編程設計與開發