一、面對對象思想
(1)大家肯定聽過
Python 中”一切皆對象“的說法,但可能並不了解它的具體含義,只是在學習的時候聽說 Python 是面向對象的編程語言,本節將向大家詳細介紹 Python 面向對象的含義。
- 面向對象編程是在面向過程編程的基礎上發展來的,它比面向過程編程具有更強的靈活性和擴展性。
- 面向對象編程(Object-oriented Programming,簡稱 OOP),是一種封裝代碼的方法。其實,在前面章節的學習中,我們已經接觸了封裝
- 代碼封裝,其實就是隱藏實現功能的具體代碼,僅留給用戶使用的接口,就好像使用計算機,用戶只需要使用鍵盤、鼠標就可以實現一些功能,而根本不需要知道其內部是如何工作的。
- 面向對象編程,也是一種封裝的思想,它可以更好地模擬真實世界里的事物(將其視為對象),並把描述特征的數據和代碼塊(函數)封裝到一起。
(2)為什么說”一切皆對象“
a = 2 print(id(a)) print(type(a)) b = 3 print(id(b)) print(type(b)) b = 2 print(id(b) #輸出結果如下 1441688672 <class 'int'> 1441688704 <class 'int'> 1441688672
- 如上述代碼中,實際上整形數據2、3其實都是 integer class(整形類的一個實例對象),而 a、b只不過是這些對象的一個標簽,可以簡單理解為2、3是兩個人,而a、b分別是他們的名字。就算把3的名字給了2這個人,那2這個人也是不會變的。這里的變指的是他們在內存中的地址,也就是上面例子中的 id() 。
二、類的理解
- 類:用來描述具有相同的屬性和方法的對象的集合。可以理解是一個模板,通過它可以創建出無數個具體實例。
- 對象:類並不能直接使用,通過類創建出的實例(又稱對象)才能使用。這有點像汽車圖紙和汽車的關系,圖紙本身(類)並不能為人們使用,通過圖紙創建出的一輛輛車(對象)才能使用。
- 對象和類的關系:類和對象的關系就像模具和鑄件的關系,類的實例化的結果就是對象,而對象的抽象體就是類。
- 屬性:類中的所有變量稱為屬性。例如下面的 Student 類中的 self.name 和 self.score
- 方法:類中的所有函數通常稱為方法。不過,和函數所有不同的是,類方法至少要包含一個 self 參數(后續會做詳細介紹)。類方法無法單獨使用,只能和類的對象一起使用。
類和實例
面向對象最重要的概念就是類(Class)和實例(Instance),必須牢記類是抽象的模板,比如 Student類,而實例是根據類創建出來的一個個具體的“對象”,每個對象都擁有相同的方法,但各自的數據可能不同。
仍以 Student 類為例,在 Python 中,定義類是通過 class 關鍵字:
class Student(object): pass
class 后面緊接着是類名,即 Student,類名通常是大寫開頭的單詞,緊接着是(object),表示該類是從哪個類繼承下來的,繼承的概念我們后面再講,通常,如果沒有合適的繼承類,就使用 object類,這是所有類最終都會繼承的類。
1.類定義:
- class定義類
- class 后面加 類名稱 加 () 加 :
2.類名稱定義規范:
- 不要以純數字命名
- 不要以python中保留字符(關鍵字)來命名
- 不要以文件名命名
- 不能出現特殊字符
- 要簡短且見名知義
- 當類名稱中有多個單詞時,應采用駝峰式(每個單詞首字母大寫) --> XinFangShuo()
定義好了 Student 類,就可以根據 Student 類創建出 Student 的實例,創建實例是通過類名+()實現的:
bart = Student()
可以看到,變量 bart 指向的就是一個 Student 的實例,而 Student 本身則是一個類。
由於類可以起到模板的作用,因此,可以在創建實例的時候,把一些我們認為必須綁定的屬性強制填寫進去。通過定義一個特殊的__init__方法,在創建實例的時候,就把 name,score 等屬性綁上去:
class Student(object): def __init__(self, name, score): self.name = name self.score = score
注意:特殊方法“__init__”前后分別有兩個下划線!!!
注意到__init__方法的第一個參數永遠是 self,表示創建的實例本身,因此,在__init__方法內部,就可以把各種屬性綁定到 self,因為 self 就指向創建的實例本身。
有了__init__方法,在創建實例的時候,就不能傳入空的參數了,必須傳入與__init__方法匹配的參數,但 self 不需要傳,Python 解釋器自己會把實例變量傳進去:
bart = Student('Bart Simpson', 59)
和普通的函數相比,在類中定義的函數只有一點不同,就是第一個參數永遠是實例變量 self,並且調用時,不用傳遞該參數。除此之外,類的方法和普通函數沒有什么區別,所以,你仍然可以用默認
參數、可變參數、關鍵字參數和命名關鍵字參數。
class Four(): #類的定義 def sub(self,x,y): return x + y """ class Dog(): def __init__(self,name,age): self.name = name self.age = age def sit(self): print (self.name.title() + ' ' + "is now sitting") def roll_over(self): print (self.name.title() + ' ' + "is now roll over") my_dog = Dog('willie',6) #參數實例化 # your_dog = Dog('lucy',3) my_dog.sit() my_dog.roll_over() """ """ class Four_operations(): def __init__(self,a,b): self.a = int(a) self.b = int(b) def add(self): return self.a + self.b def reduce(self): return self.a - self.b def ride(self): return self.a * self.b def Except(self): return self.a / self.b operation = Four_operations('12','4') print (operation.add()) print (operation.reduce()) print (operation.ride()) print (operation.Except()) """
class ReadWrite(): """ txt文件讀取類 """ def __init__(self,filepath): self.filepath = filepath def read(self,index=0): with open(self.filepath) as book: return book.read().splitlines()[index] def write(self,body): with open(self.filepath,"w") as book: book.write(body) ReadWrite("d:\\test1.txt").write("大家好,我是鄭迎!") print (ReadWrite("d:\\test1.txt").read())
#coding=utf-8 mysql = {"zhangsan":"123456","lisi":"234567","wangwu":"345678"} class LoginRegister(): """ 登錄注冊函數封裝實現如下: 1.登錄mysql中的賬號密碼成功 2.密碼錯誤則重新輸入密碼 3.賬號錯誤調用注冊方法進行注冊,注冊成功后調用登錄方法登錄已注冊的賬號 """ def login(self): user = input("username:") if user in mysql.keys(): for i in range(3): pwd = input("password:") if pwd == mysql.get(user): print ("Login ok") break else: print ("密碼輸錯三次,將鎖定賬號!") else: print ("Please register first!") LoginRegister().register() def register(self): user = input("Input you username:") while True: pwd = input("Input you password:") repwd = input("Input you password again:") if repwd == pwd: mysql.setdefault(user,pwd) print ("Register ok,sign in now!") LoginRegister().login() break else: print ("兩次密碼不一致,請重新輸入!") LoginRegister().login()
三、類的封裝/調用
調用類下的方法,必需通過類的的實例/類名()進行調用
- 當類中初始化方法__init__中存在參數時,則在實例化時,需要往實例括號中傳入參數
- 當類中無初始化方法或者__init__中不存在參數時,則在實例化時,不需要往實例括號中傳入參數,而在調用方法時再進行傳參
class Four(): def sub(self,x,y): return x + y print Four().sub(2,3) class Four_operations(): def __init__(self,a,b): self.a = int(a) self.b = int(b) def add(self): return self.a + self.b def reduce(self): return self.a - self.b def ride(self): return self.a * self.b def Except(self): return self.a / self.b operation = Four_operations('12','4') #實例化 print (operation.add()) print (operation.reduce()) print (operation.ride()) print (operation.Except())
四、面向對象和面向過程
- 面向過程:吃(狗,屎)
- 優點:流程化,分步驟實現,效率高,代碼短小精悍
- 缺點:思考難道大,代碼復用率低,擴展差,難維護
def eat(dog,food): return "{} love to eat {}.".format(dog,food) print(eat("XiaoHei","shit")) #結果如下 XiaoHei love to eat shit.
- 面向對象:狗.吃(屎)
- 優點:結構化,模塊化,易擴展,可繼承,可覆蓋,易維護
- 缺點:程序臃腫,性能低
class Dog(): def eat(self,food): return "Dogs love to eat {}.".format(food) print(Dog().eat("shit")) #結果如下 Dogs love to eat shit.