python--面向過程 VS 面向對象
編程範式
編程:程序 員 用特定的語法+數據結構+算法組成的代碼來告訴計算機如何執行任務的過程
程序:是程序員為了得到一個任務結果而編寫的一組指令的集合
編程範式:實現一個任務的方式有很多種不同的方式, 對這些不同的編程方式的特點進行歸納總結得出來的編程方式類別
兩種最重要的編程範式分別是面向過程編程和面向對象編程。
面向過程編程(Procedural Programming)
Procedural programming uses a list of instructions to tell the computer what to do step-by-step.
基本設計思路就是程序一開始是要著手解決一個大的問題,然後把一個大問題分解成很多個小問題或子過程,這些子過程再執行的過程再繼續分解直到小問題足夠簡單到可以在一個小步驟範圍內解決。
這樣做的問題也是顯而易見的,就是如果你要對程序進行修改,對你修改的那部分有依賴的各個部分你都也要跟著修改
所以我們一般認為, 如果你只是寫一些簡單的腳本,去做一些一次性任務,用面向過程的方式是極好的,但如果你要處理的任務是復雜的,且需要不斷叠代和維護 的, 那還是用面向對象最方便了。
面向對象編程
OOP編程是利用“類”和“對象”來創建各種模型來實現對真實世界的描述,使用面向對象編程的原因一方面是因為它可以使程序的維護和擴展變得更簡單
面向對象的幾個核心特性:
Class 類
一個類即是對一類擁有相同屬性的對象的抽象、藍圖、原型。在類中定義了這些對象的都具備的屬性(variables(data))、共同的方法
模板,一個類建一個模板
#建一個類 class Role(object): #類名 n = 1 #類變量 name = ‘class‘ n_list = [] def __init__(self,name,role,weapon,life_value=100,money=15000): self.name = name #r1.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money= money def shot(self): #類的方法(功能 動態屬性) print("shooting...") def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gun_name): print("just bought %s" %gun_name) print(Role.n) #實例化:把一個類變成一個對象的過程 r1 = Role(‘python‘,‘police‘,‘AK47‘) #實例化-初始化一個類-生成一個對象 r1.name = ‘A‘ #更改實例變量 r1.bullet_prove = True #給實例加一個新的屬性 print(r1.weapon) del r1.weapon #刪除實例變量 r1.n = ‘change‘ #改變類變量 在r1的內存中加了一個變量n print(Role.n) r1.n_list.append("from r2") print(Role.n,r1.name,r1.bullet_prove) r2 = Role(‘java‘,‘terrorist‘,‘B22‘) #生成一個角色 得到一個對象又叫類的實例 r2.name = ‘B‘ print(Role.n,r2.name) #name先找實例本身變量再找類變量 print(r2.n,r1.n) #改變r1的n r2的n不改變 Role.n = ‘ABC‘ #會影響r2 print(r1.n,r2.n) #實例化一個類傳參數只能通過__init__ def __init__(self): #名稱:構造函數 #作用:實例化時做一些類的初始化的工作 self.name #賦給實例 實例變量(靜態屬性) 作用域:實例本身
類變量的用途:大家共用的屬性,節省開銷
class Person: cn = "china" def __init__(self,name,age,addr): self.name = name p1 = Person(‘python‘,‘33‘,‘shanghai‘)
析構函數:在實例釋放或銷毀的時候執行的,通常用於做一些結尾工作(如:關閉一些數據庫連接打開的臨時文件)。
class Role(object): #類名 def __init__(self,name,role,weapon,life_value=100,money=15000): self.name = name #r1.name = name self.role = role self.weapon = weapon self.life_value = life_value self.money = money def __del__(self): print("%s die..."%self.name) def shot(self): #類的方法(功能 動態屬性) print("shooting...") def got_shot(self): print("ah...,I got shot...") def buy_gun(self,gun_name): print("%s just bought %s" %(self.name,gun_name)) r1 = Role(‘python‘,‘police‘,‘AK47‘) r1.buy_gun("AK47") del r1 r2 = Role(‘java‘,‘police‘,‘mb5‘) r2.got_shot()
私有方法,私有屬性(只能自己訪問)
class Role(object): #類名 def __init__(self,name,role,weapon,life_value=100,money=15000): self.name = name #r1.name = name self.role = role self.weapon = weapon #self.life_value = life_value self.__life_value = life_value #變成私有屬性 self.money = money def __del__(self): print("%s die..."%self.name) def show_status(self): print("name:%s life_value:%s"%(self.name,self.__life_value)) def shot(self): #類的方法(功能 動態屬性) print("shooting...") def __got_shot(self): #私有方法 print("ah...,I got shot...") def buy_gun(self,gun_name): print("%s just bought %s" %(self.name,gun_name)) r1 = Role(‘python‘,‘police‘,‘AK47‘) r1.buy_gun("AK47") print(r1.show_status()) r2 = Role(‘java‘,‘police‘,‘mb5‘) r2.got_shot()
Object 對象
一個對象即是一個類的實例化後實例,一個類必須經過實例化後方可在程序中調用,一個類可以實例化多個對象,每個對象亦可以有不同的屬性
Encapsulation 封裝
在類中對數據的賦值、內部調用對外部用戶是透明的,這使類變成了一個膠囊或容器,裏面包含著類的數據和方法
Inheritance 繼承
一個類可以派生出子類,在這個父類裏定義的屬性、方法自動被子類繼承
#class People: 經典類 class People(object): #新式類 def __init__(self,name,age): self.name = name self.age = age def eat(self): print("%s is eating..." %self.name) def sleep(self): print("%s is sleeping..."%self.name) def talk(self): print("%s is talking..."%self.name) class Man(People): def __init__(self,name,age,money): #重構子類 People.__init__(self,name,age) #調用父類方法一 super(Man,self).__init__(name,age) #調用父類方法二 新式類寫法 self.money = money #money在子類實現 print("%s chushihua money"%self.money) def drink(self): print("%s is drink..."%self.name) def sleep(self): #先執行父類再執行子類 父類重構 People.sleep(self) #需要加self print("man is sleeping...") class Woman(People): def get_birth(self): print("%s is baby..."%self.name) m1 = Man("A",33,888) m1.eat() #繼承父類 m1.drink() m1.sleep() w1 = Woman("B",33) w1.get_birth() #多繼承 #class People: 經典類 class People(object): #新式類 def __init__(self,name,age): self.name = name self.age = age def eat(self): print("%s is eating..." %self.name) def sleep(self): print("%s is sleeping..."%self.name) def talk(self): print("%s is talking..."%self.name) class Relation(): def make_friend(self,obj): print("%s is makeing friends with %s"%(self.name,obj.name)) class Man(People,Relation): def __init__(self,name,age,money): #重構子類 People.__init__(self,name,age) #調用父類方法一 super(Man,self).__init__(name,age) #調用父類方法二 新式類寫法 self.money = money #money在子類實現 print("%s chushihua money"%self.money) def drink(self): print("%s is drink..."%self.name) def sleep(self): #先執行父類再執行子類 父類重構 People.sleep(self) #需要加self print("man is sleeping...") class Woman(People,Relation): def get_birth(self): print("%s is baby..."%self.name) m1 = Man("A",33,888) w1 = Woman("B",33) m1.make_friend(w1)
新式類和經典類的區別主要在多繼承上面。
新式類和經典類的繼承順序
廣度優先(pthon3經典類和新式類統一都是按廣度優先繼承的)
深度優先(pthon2中經典類是按深度優先繼承,新式類是按廣度優先繼承的class A(object))
#新式類和經典類繼承順序 class A: def __init__(self): print("A") class B(A): pass # def __init__(self): # print("B") class C(A): def __init__(self): print("C") class D(B,C): pass # def __init__(self): # print("D") obj = D()
繼承程序練習
class School(object): def __init__(self,name,addr): self.name = name self.addr = addr self.students = [] self.teachers = [] self.staffs = [] def enroll(self,stu_obj): print("為學員%s 辦理註冊手續"%stu_obj.name) self.students.append(stu_obj) def hire(self,staff_obj): self.staffs.append(staff_obj) print("雇傭新員工%s"%staff_obj.name) class SchoolMember(object): def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex def tell(self): pass class Teacher(SchoolMember): def __init__(self,name,age,sex,salary,coures): super(Teacher,self).__init__(name,age,sex) self.salary = salary self.course = coures def tell(self): print(‘‘‘ ---info of Teacher:%s--- name:%s Age:%s Sex:%s Salary:%s Course:%s ‘‘‘%(self.name,self.name,self.age,self.sex,self.salary,self.course)) def Teach(self): print("%s is teaching course [%s]"%(self.name,self.course)) class Student(SchoolMember): def __init__(self,name,age,sex,stu_id,grade): super(Student,self).__init__(name,age,sex) self.stu_id = stu_id self.grade = grade def tell(self): print(‘‘‘ ---info of Student:%s--- name:%s Age:%s Sex:%s Stu_id:%s Grade:%s ‘‘‘%(self.name,self.name,self.age,self.sex,self.stu_id,self.grade)) def pay_tuition(self,amount): print("%s has pay tuition for $%s"%(self.name,amount)) school = School("Python IT","shanghai") t1 = Teacher(‘A‘,33,‘M‘,8888,‘python‘) t1 = Teacher(‘B‘,33,‘M‘,6666,‘linux‘) s1 = Student("S1",22,‘M‘,‘001‘,‘python‘) s1 = Student("S2",23,‘F‘,‘002‘,‘python‘) t1.tell() s1.tell() school.hire(t1) school.enroll(s1) print(school.students) print(school.staffs) school.staffs[0].Teach() for stu in school.students: stu.pay_tuition(5000)
Polymorphism 多態
多態是面向對象的重要特性,簡單點說:“一個接口,多種實現”,指一個基類中派生出了不同的子類,且每個子類在繼承了同樣的方法名的同時又對父類的方法做了不同的實現,這就是同一種事物表現出的多種形態
多態性(polymorphisn)是允許你將父對象設置成為和一個或更多的他的子對象相等的技術,賦值之後,父對象就可以根據當前賦值給它的子對象的特性以不同的方式運作。簡單的說,就是一句話:允許將子類類型的指針賦值給父類類型的指針
Python多態示例:
class Animal(object): def __init__(self, name): # Constructor of the class self.name = name def talk(self):# Abstract method, defined by convention only raise NotImplementedError("Subclass must implement abstract method") class Cat(Animal): def talk(self): print(‘%s: 喵喵喵!‘ %self.name) class Dog(Animal): def talk(self): print(‘%s: 汪!汪!汪!‘ %self.name) def func(obj): #一個接口,多種形態 obj.talk() c1 = Cat(‘A‘) d1 = Dog(‘B‘) func(c1) func(d1)
python--面向過程 VS 面向對象