精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

帶你了解Python面向對象編程

開發 后端
面向對象編程中,將函數和變量進一步封裝成類,類才是程序的基本元素,它將數據和操作緊密地連結在一起,并保護數據不會被外界的函數意外地改變。類和和類的實例(也稱對象)是面向對象的核心概念,是和面向過程編程、函數式編程的根本區別。

史上最全Python面向對象編程

面向對象編程和函數式編程(面向過程編程)都是程序設計的方法,不過稍有區別。

面向過程編程:

1. 導入各種外部庫

2. 設計各種全局變量

3. 寫一個函數完成某個功能

4. 寫一個函數完成某個功能

5. 寫一個函數完成某個功能

6. 寫一個函數完成某個功能

7. 寫一個函數完成某個功能

8. ......

9. 寫一個main函數作為程序入口

在多函數程序中,許多重要的數據被放置在全局數據區,這樣它們可以被所有的函數訪問。每個函數都可以具有它們自己的局部數據,將某些功能代碼封裝到函數中,日后便無需重復編寫,僅調用函數即可。從代碼的組織形式來看就是根據業務邏輯從上到下壘代碼 。

面向對象編程:

1. 導入各種外部庫

2. 設計各種全局變量

3. 決定你要的類

4. 給每個類提供完整的一組操作

5. 明確地使用繼承來表現不同類之間的共同點

6. 根據需要,決定是否寫一個main函數作為程序入口

面向對象編程中,將函數和變量進一步封裝成類,類才是程序的基本元素,它將數據和操作緊密地連結在一起,并保護數據不會被外界的函數意外地改變。類和和類的實例(也稱對象)是面向對象的核心概念,是和面向過程編程、函數式編程的根本區別。

并不是非要用面向對象編程,要看你的程序怎么設計方便,但是就目前來說,基本上都是在使用面向對象編程。

類的基本用法

面向對象是通過定義class類來定義,這么說面向對象編程就是只使用class類,在class類中有封裝,繼承的功能,并且還可以構造要傳入的參數,方便控制。

案例一

  1. import sys 
  2. import time 
  3. reload(sys) 
  4. sys.setdefaultencoding('utf-8'
  5.  
  6. class studetn: 
  7.     # 定義一個類名為studetn 
  8.     def __init__(self,idx): 
  9.     # 定義初始化構造,這里使用init,還有別的屬性比如reversed,iter之類的 
  10.         self.idx=idx 
  11.         # 初始化變量,方便繼承 
  12.     def runx(self): 
  13.     # 定義運行函數,從上面繼承變量 
  14.         print self.idx 
  15.         # 打印出idx的值,或者做一些別的處理 
  16.         time.sleep(1) 
  17. a=studetn('a'
  18. a.runx() 
  19. # 這是類的調用,一定要記得類的使用方法,首先傳入參數,類賦值給一個變量a 
  20. # 然后調用這個類下面定義的函數 

一些專業術語概念,既然有面向對象編程這個高大上的定義了,自然要搭配一些高大上的概念。

  1. 類(Class): 用來描述具有相同屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。其中的對象被稱作類的實例。
  2. 實例:也稱對象。通過類定義的初始化方法,賦予具體的值,成為一個”有血有肉的實體”。
  3. 實例化:創建類的實例的過程或操作。
  4. 實例變量:定義在實例中的變量,只作用于當前實例。
  5. 類變量:類變量是所有實例公有的變量。類變量定義在類中,但在方法體之外。
  6. 數據成員:類變量、實例變量、方法、類方法、靜態方法和屬性等的統稱。
  7. 方法:類中定義的函數。
  8. 靜態方法:不需要實例化就可以由類執行的方法
  9. 類方法:類方法是將類本身作為對象進行操作的方法。
  10. 方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對父類的方法進行改寫,這個過程也稱override。
  11. 封裝:將內部實現包裹起來,對外透明,提供api接口進行調用的機制
  12. 繼承:即一個派生類(derived class)繼承父類(base class)的變量和方法。
  13. 多態:根據對象類型的不同以不同的方式進行處理。

類與實例

  1. # -*- coding: utf-8 -*- 
  2. # @Time    : 2018/5/3 0003 17:02 
  3. # @Author  : Langzi 
  4. # @Blog    : www.langzi.fun 
  5. # @File    : 面向對象2.py 
  6. # @Software: PyCharm 
  7. import sys 
  8. import time 
  9. import requests 
  10. reload(sys) 
  11. sys.setdefaultencoding('utf-8'
  12.  
  13. class cc: 
  14.     ccc = 'ccc' 
  15.     # cc就是類名 如果想要繼承別的類 就class cc(threading) 意思就是從threading繼承 
  16.     def __init__(self,a,b,c): 
  17.         self.a=a 
  18.         self.b=b 
  19.         self.c=c 
  20.         # 定義構造的過程就是實例化 
  21.     def runx(self): 
  22.         print self.a*10 
  23.         print self.b*5 
  24.         print self.c*2 
  25.     def runy(self): 
  26.         print requests.get('http://www.langzi.fun').headers 
  27. e = cc('AAA','CCC','EEE'
  28. e.runx() 
  29. e.runy() 
  30. # 這兩個就是調用類里面的方法 
  31. print e.c 
  32. #實例變量指的是實例本身擁有的變量。每個實例的變量在內存中都不一樣。 
  33. print e.ccc 
  34. #類變量,在類里面找到定義的變量。 
  35. 調用類的三種方法 

調用類的三種方法

實例方法

 

  1. # -*- coding: utf-8 -*- 
  2. # @Time    : 2018/5/3 0003 17:16 
  3. # @Author  : Langzi 
  4. # @Blog    : www.langzi.fun 
  5. # @File    : 面向對象3.py 
  6. # @Software: PyCharm 
  7. import sys 
  8. import time 
  9. import requests 
  10. reload(sys) 
  11. sys.setdefaultencoding('utf-8'
  12.  
  13. class dd: 
  14.     def __init__(self,url): 
  15.         self.url=url 
  16.     def runx(self): 
  17.         print requests.get(self.url).status_code 
  18.  
  19. a = dd('http://www.langzi.fun'
  20. a.runx() 
  21. # 這種調用方法就是實例方法 

靜態方法

靜態方法由類調用,無默認參數。將實例方法參數中的self去掉,然后在方法定義上方加上@staticmethod,就成為靜態方法。它屬于類,和實例無關。建議只使用類名.靜態方法的調用方式。(雖然也可以使用實例名.靜態方法的方式調用)

  1. # -*- coding: utf-8 -*- 
  2. # @Time    : 2018/5/3 0003 17:21 
  3. # @Author  : Langzi 
  4. # @Blog    : www.langzi.fun 
  5. # @File    : 面向對象4.py 
  6. # @Software: PyCharm 
  7. import sys 
  8. import requests 
  9. reload(sys) 
  10. sys.setdefaultencoding('utf-8'
  11. class ff: 
  12.     @staticmethod 
  13.     def runx(): 
  14.         print requests.get('http://www.langzi.fun').status_code 
  15. ff.runx() 
  16. #這里就直接調用了類的變量,只在類中運行而不在實例中運行的方法 

經常有一些跟類有關系的功能但在運行時又不需要實例和類參與的情況下需要用到靜態方法. 比如更改環境變量或者修改其他類的屬性等能用到靜態方法. 這種情況可以直接用函數解決, 但這樣同樣會擴散類內部的代碼,造成維護困難。

類方法

類方法由類調用,采用@classmethod裝飾,至少傳入一個cls(代指類本身,類似self)參數。執行類方法時,自動將調用該方法的類賦值給cls。建議只使用類名.類方法的調用方式。(雖然也可以使用實例名.類方法的方式調用)

實際案例

如果要構造一個類,接受一個網站和這個網站的狀態碼,然后打印出來。就像這樣:

  1. import sys 
  2. import requests 
  3. reload(sys) 
  4. sys.setdefaultencoding('utf-8'
  5. class gg: 
  6.     def __init__(self,url,stat): 
  7.         self.url=url 
  8.         self.stat=stat 
  9.     def outer(self): 
  10.         print self.url 
  11.         print self.stat 
  12. a = gg('langzi',200) 
  13. a.outer() 

這樣就是使用實例方法,雖然可以實現,但是有的時候傳入的參數并不是(‘langzi’,200)這樣的格式,而是(‘langzi-200’)這樣的,那該怎么做?首先要把這個拆分,但是要使用實例方法實現起來很麻煩,這個時候就可以使用類方法。

  1. # -*- coding: utf-8 -*- 
  2. # @Time    : 2018/5/3 0003 17:27 
  3. # @Author  : Langzi 
  4. # @Blog    : www.langzi.fun 
  5. # @File    : 面向對象5.py 
  6. # @Software: PyCharm 
  7. import sys 
  8. import requests 
  9. reload(sys) 
  10. sys.setdefaultencoding('utf-8'
  11. class gg: 
  12.     url = 0 
  13.     stat = 0 
  14.     # 因為使用classmethod后會傳入新的變量,所以一開始是需要自己先定義類變量 
  15.     def __init__(self,url=0,stat=0): 
  16.     # 這里按照正常的定義構造函數 
  17.         self.url=url 
  18.         self.stat=stat 
  19.     @classmethod 
  20.     # 裝飾器,立馬執行下面的函數 
  21.     def split(cls,info): 
  22.         # 這個函數接受兩個參數,默認的cls就是這個類的init函數,info就是外面傳入進來的 
  23.         url,stat=map(str,info.split('-')) 
  24.         # 這里轉換成了格式化的結構 
  25.         data = cls(url,stat) 
  26.         # 然后執行這個類***個方法,這個類構造函數需要傳入兩個參數,于是就傳入了兩個參數 
  27.         return data 
  28.         # 這里就直接返回了函數結果 
  29.     def outer(self): 
  30.         print self.url 
  31.         print self.stat 
  32.  
  33. r = gg.split(('langzi-200')) 
  34. r.outer() 
  35. # 這里是調用類方法,與調用實例方法一樣 

類的特性

封裝

封裝是指將數據與具體操作的實現代碼放在某個對象內部,外部無法訪問。必須要先調用類的方法才能啟動。

案例

 

  1. class cc: 
  2.     ccc = 'ccc' 
  3.     # cc就是類名 如果想要繼承別的類 就class cc(threading) 意思就是從threading繼承 
  4.     def __init__(self,a,b,c): 
  5.         self.a=a 
  6.         self.b=b 
  7.         self.c=c 
  8. print e.ccc 
  9. #類變量,在類里面找到定義的變量。 
  10. print ccc 
  11. # 這里會報錯,這就是封裝。類中的函數同理。 

繼承

當我們定義一個class的時候,可以從某個現有的class繼承,新的class稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Base class、Super class)。

比如,我們已經編寫了一個名為Animal的class,有一個run()方法可以直接打印:

  1. class Animal(object): 
  2.     def run(self): 
  3.         print 'Animal is running...' 

當我們需要編寫Dog和Cat類時,就可以直接從Animal類繼承:

 

  1. class Dog(Animal): 
  2.     pass 
  3. class Cat(Animal): 
  4.     pass 

繼承有什么好處?***的好處是子類獲得了父類的全部功能。由于Animial實現了run()方法,因此,Dog和Cat作為它的子類,什么事也沒干,就自動擁有了run()方法:

  1. dog = Dog() 
  2. dog.run() 
  3. cat = Cat() 
  4. cat.run() 

當子類和父類都存在相同的run()方法時,我們說,子類的run()覆蓋了父類的run(),在代碼運行的時候,總是會調用子類的run()。這樣,我們就獲得了繼承的另一個好處:多態。

多態

要理解多態的好處,我們還需要再編寫一個函數,這個函數接受一個Animal類型的變量:

 

  1. def run_twice(animal): 
  2.     animal.run() 
  3.     animal.run() 

當我們傳入Animal的實例時,run_twice()就打印出:

 

  1. run_twice(Animal()) 
  2. 運行結果: 
  3. Animal is running... 
  4. Animal is running... 

當我們傳入Dog的實例時,run_twice()就打印出:

 

  1. run_twice(Dog()) 
  2. 運行結果: 
  3. Dog is running... 
  4. Dog is running... 

當我們傳入Cat的實例時,run_twice()就打印出:

 

  1. run_twice(Cat()) 
  2. 運行結果: 
  3. Cat is running... 
  4. Cat is running... 

看上去沒啥意思,但是仔細想想,現在,如果我們再定義一個Tortoise類型,也從Animal派生:

 

  1. class Tortoise(Animal): 
  2.     def run(self): 
  3.         print 'Tortoise is running slowly...' 

當我們調用run_twice()時,傳入Tortoise的實例:

 

  1. run_twice(Tortoise()) 
  2. 運行結果: 
  3. Tortoise is running slowly... 
  4. Tortoise is running slowly... 

你會發現,新增一個Animal的子類,不必對run_twice()做任何修改,實際上,任何依賴Animal作為參數的函數或者方法都可以不加修改地正常運行,原因就在于多態。

多態的好處就是,當我們需要傳入Dog、Cat、Tortoise……時,我們只需要接收Animal類型就可以了,因為Dog、Cat、Tortoise……都是Animal類型,然后,按照Animal類型進行操作即可。由于Animal類型有run()方法,因此,傳入的任意類型,只要是Animal類或者子類,就會自動調用實際類型的run()方法,這就是多態的意思:

對于一個變量,我們只需要知道它是Animal類型,無需確切地知道它的子類型,就可以放心地調用run()方法,而具體調用的run()方法是作用在Animal、Dog、Cat還是Tortoise對象上,由運行時該對象的確切類型決定,這就是多態真正的威力:調用方只管調用,不管細節,而當我們新增一種Animal的子類時,只要確保run()方法編寫正確,不用管原來的代碼是如何調用的。這就是著名的“開閉”原則:

對擴展開放:允許新增Animal子類;

對修改封閉:不需要修改依賴Animal類型的run_twice()等函數。

總結:繼承可以把父類的所有功能都直接拿過來,這樣就不必重零做起,子類只需要新增自己特有的方法,也可以把父類不適合的方法覆蓋重寫;

有了繼承,才能有多態。在調用類實例方法的時候,盡量把變量視作父類類型,這樣,所有子類類型都可以正常被接收;

舊的方式定義Python類允許不從object類繼承,但這種編程方式已經嚴重不推薦使用。任何時候,如果沒有合適的類可以繼承,就繼承自object類。

魔法方法

在上面有提到除了init之外還有iter,reverse的方法,這里就詳細說下除了init初始化還有哪些別的方法。

 

  1. __init__ :      構造函數,在生成對象時調用 
  2. __del__ :       析構函數,釋放對象時使用 
  3. __repr__ :      打印,轉換 
  4. __setitem__ :   按照索引賦值 
  5. __getitem__:    按照索引獲取值 
  6. __len__:        獲得長度 
  7. __cmp__:        比較運算 
  8. __call__:       調用 
  9. __add__:        加運算 
  10. __sub__:        減運算 
  11. __mul__:        乘運算 
  12. __div__:        除運算 
  13. __mod__:        求余運算 
  14. __pow__:        冪 

具體使用

1. doc

說明性文檔和信息。Python自建,無需自定義。

 

  1. class Foo: 
  2.     """ 描述類信息,可被自動收集 """ 
  3.     def func(self): 
  4.         pass 
  5. # 打印類的說明文檔  
  6. print(Foo.__doc__) 

2. init()

實例化方法,通過類創建實例時,自動觸發執行。

 

  1. class Foo: 
  2.     def __init__(self, name): 
  3.         self.name = name 
  4.         self.age = 18 
  5. obj = Foo(jack') # 自動執行類中的 __init__ 方法 

3. module__ 和 __class

module 表示當前操作的對象在屬于哪個模塊。

class 表示當前操作的對象屬于哪個類。

這兩者也是Python內建,無需自定義。

 

  1. class Foo: 
  2.     pass 
  3. obj = Foo() 
  4. print(obj.__module__) 
  5. print(obj.__class__) 

運行結果:

 

  1. main 

4. del()

析構方法,當對象在內存中被釋放時,自動觸發此方法。

注:此方法一般無須自定義,因為Python自帶內存分配和釋放機制,除非你需要在釋放的時候指定做一些動作。析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。

 

  1. class Foo: 
  2.     def __del__(self): 
  3.         print("我被回收了!"
  4.  
  5. obj = Foo() 
  6. del obj 

5. call()

如果為一個類編寫了該方法,那么在該類的實例后面加括號,可會調用這個方法。

注:構造方法的執行是由類加括號執行的,即:對象 = 類名(),而對于call() 方法,是由對象后加括號觸發的,即:對象() 或者 類()()

 

  1. class Foo: 
  2.     def __init__(self): 
  3.         pass 
  4.     def __call__(self, *args, **kwargs): 
  5.         print('__call__'
  6. obj = Foo()     # 執行 __init__ 
  7. obj()       # 執行 __call__ 

可以用Python內建的callable()函數進行測試,判斷一個對象是否可以被執行。

 

  1. callable(Student()) 

運行結果:

 

  1. True 

6. dict

列出類或對象中的所有成員!非常重要和有用的一個屬性,Python自建,無需用戶自己定義。

 

  1. class Province: 
  2.     country = 'China' 
  3.     def __init__(self, namecount): 
  4.         self.name = name 
  5.         self.count = count 
  6.     def func(self, *args, **kwargs): 
  7.         print('func') 
  8. # 獲取類的成員 
  9. print(Province.__dict__) 
  10. # 獲取 對象obj1 的成員  
  11. obj1 = Province('HeBei',10000) 
  12. print(obj1.__dict__) 
  13. # 獲取 對象obj2 的成員  
  14. obj2 = Province('HeNan', 3888) 
  15. print(obj2.__dict__) 

7. str()

如果一個類中定義了str()方法,那么在打印對象時,默認輸出該方法的返回值。這也是一個非常重要的方法,需要用戶自己定義。

下面的類,沒有定義str()方法,打印結果是:

 

  1. class Foo: 
  2.     pass 
  3. obj = Foo() 
  4. print(obj) 
  5. 定義了__str__()方法后,打印結果是:'jack'。 
  6. class Foo: 
  7.     def __str__(self): 
  8.         return 'jack' 
  9. obj = Foo() 
  10. print(obj) 

8、getitem__()、_setitem_()、__delitem()

取值、賦值、刪除這“三劍客”的套路,在Python中,我們已經見過很多次了,比如前面的@property裝飾器。

Python中,標識符后面加圓括號,通常代表執行或調用方法的意思。而在標識符后面加中括號[],通常代表取值的意思。Python設計了getitem()、setitem()、delitem()這三個特殊成員,用于執行與中括號有關的動作。它們分別表示取值、賦值、刪除數據。

也就是如下的操作:

 

  1. a = 標識符[] :   執行__getitem__方法 
  2. 標識符[] = a  :   執行__setitem__方法 
  3. del 標識符[] :   執行__delitem__方法 

如果有一個類同時定義了這三個魔法方法,那么這個類的實例的行為看起來就像一個字典一樣,如下例所示:

 

  1. class Foo: 
  2.     def __getitem__(self, key): 
  3.         print('__getitem__',key
  4.     def __setitem__(self, key, value): 
  5.         print('__setitem__',key,value) 
  6.     def __delitem__(self, key): 
  7.         print('__delitem__',key
  8. obj = Foo() 
  9. result = obj['k1']      # 自動觸發執行 __getitem__ 
  10. obj['k2'] = 'jack'      # 自動觸發執行 __setitem__ 
  11. del obj['k1']             # 自動觸發執行 __delitem__ 

9. iter()

這是迭代器方法!列表、字典、元組之所以可以進行for循環,是因為其內部定義了 iter()這個方法。如果用戶想讓自定義的類的對象可以被迭代,那么就需要在類中定義這個方法,并且讓該方法的返回值是一個可迭代的對象。當在代碼中利用for循環遍歷對象時,就會調用類的這個iter()方法。

普通的類:

 

  1. class Foo: 
  2.     pass 
  3. obj = Foo() 
  4. for i in obj: 
  5.     print(i) 
  6. # 報錯:TypeError: 'Foo' object is not iterable<br># 原因是Foo對象不可迭代 
  7. 添加一個__iter__(),但什么都不返回: 
  8. class Foo: 
  9.     def __iter__(self): 
  10.         pass 
  11. obj = Foo() 
  12. for i in obj: 
  13.     print(i) 
  14. # 報錯:TypeError: iter() returned non-iterator of type 'NoneType' 
  15. #原因是 __iter__方法沒有返回一個可迭代的對象 

返回一個個迭代對象:

 

  1. class Foo: 
  2.     def __init__(self, sq): 
  3.         self.sq = sq 
  4.     def __iter__(self): 
  5.         return iter(self.sq) 
  6. obj = Foo([11,22,33,44]) 
  7. for i in obj: 
  8.     print(i) 

***的方法是使用生成器:

 

  1. class Foo: 
  2.     def __init__(self): 
  3.         pass 
  4.     def __iter__(self): 
  5.         yield 1 
  6.         yield 2 
  7.         yield 3 
  8. obj = Foo() 
  9. for i in obj: 
  10.     print(i) 

10、len()

在Python中,如果你調用內置的len()函數試圖獲取一個對象的長度,在后臺,其實是去調用該對象的len()方法,所以,下面的代碼是等價的:

 

  1. len('ABC'
  2. 'ABC'.__len__() 

Python的list、dict、str等內置數據類型都實現了該方法,但是你自定義的類要實現len方法需要好好設計。

11. repr()

這個方法的作用和str()很像,兩者的區別是str()返回用戶看到的字符串,而repr()返回程序開發者看到的字符串,也就是說,repr()是為調試服務的。通常兩者代碼一樣。

 

  1. class Foo: 
  2.     def __init__(self, name): 
  3.         self.name = name 
  4.     def __str__(self): 
  5.         return "this is %s" % self.name 
  6.     __repr__ = __str__ 

12. add__: 加運算 _sub_: 減運算 _mul_: 乘運算 _div_: 除運算 _mod_: 求余運算 __pow: 冪運算

這些都是算術運算方法,需要你自己為類設計具體運算代碼。有些Python內置數據類型,比如int就帶有這些方法。Python支持運算符的重載,也就是重寫。

 

  1. class Vector: 
  2.    def __init__(self, a, b): 
  3.       self.a = a 
  4.       self.b = b 
  5.    def __str__(self): 
  6.       return 'Vector (%d, %d)' % (self.a, self.b) 
  7.    def __add__(self,other): 
  8.       return Vector(self.a + other.a, self.b + other.b) 
  9. v1 = Vector(2,10) 
  10. v2 = Vector(5,-2) 
  11. print (v1 + v2) 

13. author作者信息

 

  1. __author__ = "Jack" 
  2. def show(): 
  3.     print(__author__) 
  4. show() 

14. slots

Python作為一種動態語言,可以在類定義完成和實例化后,給類或者對象繼續添加隨意個數或者任意類型的變量或方法,這是動態語言的特性。例如:

 

  1. def print_doc(self): 
  2.     print("haha"
  3.  
  4. class Foo: 
  5.     pass 
  6.  
  7. obj1 = Foo() 
  8. obj2 = Foo() 
  9. # 動態添加實例變量 
  10. obj1.name = "jack" 
  11. obj2.age = 18 
  12. # 動態的給類添加實例方法 
  13. Foo.show = print_doc 
  14. obj1.show() 
  15. obj2.show() 

但是!如果我想限制實例可以添加的變量怎么辦?可以使slots限制實例的變量,比如,只允許Foo的實例添加name和age屬性。

  1. def print_doc(self): 
  2.     print("haha"
  3. class Foo: 
  4.     __slots__ = ("name""age"
  5.     pass 
  6. obj1 = Foo() 
  7. obj2 = Foo() 
  8. # 動態添加實例變量 
  9. obj1.name = "jack" 
  10. obj2.age = 18 
  11. obj1.sex = "male"       # 這一句會彈出錯誤 
  12. # 但是無法限制給類添加方法 
  13. Foo.show = print_doc 
  14. obj1.show() 
  15. obj2.show() 
  16. 由于'sex'不在__slots__的列表中,所以不能綁定sex屬性,試圖綁定sex將得到AttributeError的錯誤。 
  17. Traceback (most recent call last): 
  18.   File "F:/Python/pycharm/201705/1.py", line 14, in <module> 
  19.     obj1.sex = "male" 
  20. AttributeError: 'Foo' object has no attribute 'sex' 

需要提醒的是,slots定義的屬性僅對當前類的實例起作用,對繼承了它的子類是不起作用的。想想也是這個道理,如果你繼承一個父類,卻莫名其妙發現有些變量無法定義,那不是大問題么?如果非要子類也被限制,除非在子類中也定義slots,這樣,子類實例允許定義的屬性就是自身的slots加上父類的slots。

成員保護與訪問機制

有些對象你不想外部訪問,即使是通過調用類對象也無法訪問,那就請認真學完本章節。

私有成員

 

  1. class obj: 
  2.     def __init__(self,name): 
  3.         self.name=name 
  4.     def pri(self): 
  5.         print self.name 
  6.     __age = 18 
  7.     # 加上雙下劃線的就是私有變量,只能在類的內部訪問,外部無法訪問 
  8. a = obj('zhao'
  9. a.pri() 

運行結果:

 

  1. zhao 

如果要在類中調用這個私有成員,可以這么用

 

  1. class obj: 
  2.     def __init__(self,name): 
  3.         self.name=name 
  4.     def prin(self): 
  5.         print self.name 
  6.     __age = 18 
  7.     # 加上雙下劃線的就是私有變量,只能在類的內部訪問,外部無法訪問 
  8.     @classmethod 
  9.     # 如果要在類中調用,首先調用類方法 
  10.     def pri(cls): 
  11.         print cls.__age 
  12.         # 然后在使用 
  13. a = obj('zhao'
  14. a.prin() 
  15. obj.pri() 
  16. # 通過這樣直接調用類中的私有變量 

運行結果:

 

  1. zhao
  2. 18 

使用get-set-del方法操作私有成員

 

  1. class obj: 
  2.     def __init__(self,name): 
  3.         self.name=name 
  4.     def prin(self): 
  5.         print self.name 
  6.     __age = 18 
  7.     # 加上雙下劃線的就是私有變量,只能在類的內部訪問,外部無法訪問 
  8.     @classmethod 
  9.     # 如果要在類中調用,首先調用類方法 
  10.     def pri(cls): 
  11.         print cls.__age 
  12.         # 然后在使用 
  13.     @classmethod 
  14.     def set_age(cls,value): 
  15.         cls.__age = value 
  16.         return cls.__age 
  17.         # 這個用法就是改變__age的值 
  18.     @classmethod 
  19.     def get_age(cls): 
  20.         return cls.__age 
  21.         # 這個用法就是直接返回__age的值 
  22.     @classmethod 
  23.     def del_age(cls): 
  24.         del cls.__age 
  25.         # 這個用法就是直接刪除__age的值 
  26.  
  27. print obj.get_age() 
  28. # 這里是直接調用出__age的值  返回值18 
  29. print obj.set_age(20) 
  30. # 這里是直接改變__age的值  返回值20 
  31. obj.del_age() 
  32. # 這里是直接刪除__age的值 

思考: 既然是私有變量,不讓外部訪問,為何有要在后面調用又改變呢?因為可以對私有變量進行額外的檢測,處理,加工等等。比如判斷value的值,使用isinstance然后做if-else判斷。

使用私有變量可以對內部變量進行保護,外部無法改變,但是可以對它進行檢測處理。

這里引申一下私有成員的保護機制,使用__age對私有變量其實就是—>obj._obj__age的樣子進行保護,說白了你直接使用obj._obj__age就可以直接調用內部私有變量age了。

Propety裝飾器

把類的方法偽裝成屬性調用的方式,就是把類里面的一個函數,變成一個屬性一樣的東西~

一開始調用類的方法要使用圓括號,現在變成了屬性進行讀取設置存儲。

舉個例子來說明:

常用的調用方法

 

  1. class obj: 
  2.     def __init__(self,name,age): 
  3.         self.__name=name 
  4.         self.__age=age 
  5.         # 講這些設置成私有變量 
  6.     def get_age(self): 
  7.         return self.__age 
  8.     def set_age(self,value): 
  9.         if isinstance(value,int): 
  10.             self.__age=value 
  11.         else
  12.             raise ValueError('非整數類型'
  13.     def del_age(self): 
  14.         print 'delete over' 
  15. a = obj('langzi',18) 
  16. print a.get_age() 
  17. a.set_age(20) 
  18. print a.get_age() 

使用裝飾器

 

  1. class obj: 
  2.     def __init__(self,name,age): 
  3.         self.__name=name 
  4.         self.__age=age 
  5.         # 把這些設置成私有變量 
  6.     @property 
  7.     def age(self): 
  8.         return self.__age 
  9.     @age.setter 
  10.     def age(self,value): 
  11.         if isinstance(value,int): 
  12.             self.__age=value 
  13.         else
  14.             raise ValueError('非整數類型'
  15.     @age.deleter 
  16.     def age(self): 
  17.         print 'delete over' 
  18. a = obj('langzi',18) 
  19. # 使用這些裝飾器,可以使用類與對象的方法直接調用 
  20. print a.age 
  21. # 這里就是直接調用返回age的值 
  22. a.age=20 
  23. # 這里就是直接使用setter把值轉換 
  24. print a.age 
  25. del a.age 
  26. # 刪除age 

當然這種調用方法有些麻煩,每次都是一個一個去實例類與對象,有個更加簡單直觀的方法。

更加減半的使用property()函數

除了使用裝飾器的方式將一個方法偽裝成屬性外,Python內置的builtins模塊中的property()函數,為我們提供了第二種設置類屬性的手段。

 

  1. class People: 
  2.  
  3.     def __init__(self, name, age): 
  4.         self.__name = name 
  5.         self.__age = age 
  6.  
  7.     def get_age(self): 
  8.         return self.__age 
  9.  
  10.     def set_age(self, age): 
  11.         if isinstance(age, int): 
  12.             self.__age = age 
  13.         else
  14.             raise ValueError 
  15.  
  16.     def del_age(self): 
  17.         print("刪除年齡數據!"
  18.  
  19.     # 核心在這句 
  20.     age = property(get_age, set_age, del_age, "年齡")     
  21.  
  22.  
  23. obj = People("jack", 18) 
  24. print(obj.age) 
  25. obj.age = 19 
  26. print("obj.age:  ", obj.age) 
  27. del obj.ag 

通過語句age = property(get_age, set_age, del_age, “年齡”)將一個方法偽裝成為屬性。其效果和裝飾器的方法是一樣的。

property()函數的參數:

 

  1. ***個參數是方法名,調用 實例.屬性 時自動執行的方法 
  2. 第二個參數是方法名,調用 實例.屬性 = XXX時自動執行的方法 
  3. 第三個參數是方法名,調用 del 實例.屬性 時自動執行的方法 
  4. 第四個參數是字符串,調用 實例.屬性.__doc__時的描述信息。 

 

責任編輯:龐桂玉 來源: Python編程
相關推薦

2023-11-02 07:55:31

Python對象編程

2023-12-11 15:32:30

面向對象編程OOPpython

2023-01-10 09:06:17

2019-04-24 15:20:44

Shell腳本編程Linux

2017-04-21 09:07:39

JavaScript對象編程

2012-01-17 09:34:52

JavaScript

2010-11-17 11:31:22

Scala基礎面向對象Scala

2023-09-27 23:28:28

Python編程

2023-04-26 00:15:32

python面向對象java

2022-07-30 23:41:53

面向過程面向對象面向協議編程

2021-02-14 18:26:25

高并發大對象代碼

2012-12-13 11:01:42

IBMdW

2012-02-27 09:30:22

JavaScript

2010-02-26 14:40:15

Python應用程序

2023-02-16 09:55:24

對象編程OOP

2011-05-25 10:21:44

Javascript

2010-07-16 17:23:57

Perl面向對象編程

2011-06-28 11:06:16

Scala

2012-12-18 09:24:47

2010-07-13 17:18:29

Perl面向對象編程
點贊
收藏

51CTO技術棧公眾號

欧亚一区二区三区| 香蕉视频官网在线观看日本一区二区| 香蕉加勒比综合久久| 精品一区久久久久久| 一区二区传媒有限公司| 欧美性孕妇孕交| 欧美激情综合色综合啪啪| 欧美精品一区二区三区一线天视频| 国产深夜男女无套内射| av资源网在线观看| 成人免费福利片| 国产精品久久久av久久久| 国产国语老龄妇女a片| 尤物视频在线免费观看| 丁香天五香天堂综合| 国产精品va在线| 日韩激情一区二区三区| 日韩情爱电影在线观看| 欧美性猛交xxxx富婆弯腰| 一区二区三区四区在线视频| 狠狠人妻久久久久久综合麻豆| 视频一区国产视频| 国外成人在线播放| 国产成人自拍网站| 国产一区二区三区四区| 精品国产不卡一区二区三区| 污视频网址在线观看| 蜜桃视频动漫在线播放| 91在线播放网址| 成人国产精品久久久| 国产一区二区视频免费| 亚洲美女毛片| 久久99久久久久久久噜噜| 国产精品一区二区亚洲| 国产伦精品一区二区三区视频 | 私拍精品福利视频在线一区| 欧美一区二区三区在| 中文字幕欧美人妻精品一区| 嗯啊主人调教在线播放视频 | 永久免费看av| 日本电影全部在线观看网站视频| 久久免费电影网| 精品一区二区国产| 少妇无码一区二区三区| 国产凹凸在线观看一区二区| 欧美成人在线网站| 三区四区在线观看| 国内黄色精品| 亚洲色图美腿丝袜| 手机av免费看| 色综合视频一区二区三区日韩| 色哟哟日韩精品| 一区二区精品在线观看| 成人18在线| 国产免费久久精品| 视频一区三区| 91在线视频| 亚洲欧洲精品一区二区三区 | 91手机在线播放| va婷婷在线免费观看| 亚洲黄色高清| 97久久精品国产| 亚洲男人第一av| 不卡av一区二区| 在线看日韩av| 亚洲区一区二区三| 亚洲影视一区| 欧美激情视频三区| xxxxxx国产| 久久精品国产亚洲夜色av网站 | 五月天精品视频| 欧美在线观看视频一区| 日韩亚洲精品视频| 欧美色图亚洲天堂| 精品亚洲成人| 亚洲国产精品va在线看黑人动漫| 国产午夜在线一区二区三区| 欧美成人一区在线观看| 亚洲人成电影在线| 一级性生活免费视频| 欧美激情日韩| 欧美一区第一页| 正在播放木下凛凛xv99| 国内精品第一页| 欧美中文在线观看| 欧美人妻精品一区二区三区| 在线免费高清一区二区三区| 日韩av三级在线观看| 一区不卡在线观看| 成人久久18免费网站麻豆 | 亚洲国产精品久久不卡毛片 | 免费在线视频观看| 亚洲女同在线| 国产在线视频欧美| 男人天堂综合网| 久久国产免费看| 99精彩视频在线观看免费| 亚洲天堂999| 国产成人免费xxxxxxxx| 欧美二区三区在线| 超碰在线观看免费版| 色综合欧美在线| 日韩欧美中文在线视频| 要久久爱电视剧全集完整观看| www.精品av.com| www.国产一区二区| 国产不卡免费视频| 亚洲精品乱码视频| 丁香高清在线观看完整电影视频| 91国在线观看| 国产十八熟妇av成人一区| 欧美大人香蕉在线| 日韩av第一页| 欧美一级片免费| 中文字幕五月欧美| 日本中文字幕片| 电影一区二区在线观看| 一区二区亚洲精品国产| 日韩精品一区二区不卡| 国产原创一区二区三区| 日韩高清av| 国产精品论坛| 欧美成人福利视频| 韩国一区二区三区四区| 欧美久久综合网| 欧美在线xxx| 黄色av网站免费在线观看| 1000精品久久久久久久久| 男女曰b免费视频| 全国精品免费看| 久久人人97超碰精品888| av中文字幕免费在线观看| 国产目拍亚洲精品99久久精品| 青青草原成人网| 国产精品22p| 欧美肥婆姓交大片| 国产精品久久婷婷| 国产精品久久久久国产精品日日| 国产成人无码一二三区视频| 粉嫩久久久久久久极品| 色综合老司机第九色激情| 国产精品无码免费播放| 亚洲欧洲成人自拍| 在线黄色免费看| 欧美xxxx中国| 成人午夜黄色影院| 成人片在线看| 欧美一区二区三区四区在线观看 | 国产精品吴梦梦| 国产福利片在线| 欧美在线不卡视频| 色撸撸在线视频| 久久成人精品无人区| 在线看视频不卡| 日韩成人在线观看视频| 欧美激情精品在线| 日本黄色一区二区三区| 亚洲成av人影院| 黄色国产在线观看| 久久久久.com| 亚洲欧美国产不卡| 国产人与zoxxxx另类91| 欧美乱人伦中文字幕在线| 亚洲精品国偷拍自产在线观看蜜桃| av在线播放一区二区三区| 日韩wuma| 亚洲国产伊人| 欧美国产日韩中文字幕在线| 秋霞av鲁丝片一区二区| 欧美丝袜一区二区| 国产真人做爰视频免费| 久久99精品国产91久久来源| 99re6这里有精品热视频| 成人自拍在线| 国产91在线播放精品91| 日韩三级影院| 欧美精品一区二区三区高清aⅴ | 久久久久麻豆v国产| 国产毛片精品一区| 日本亚洲导航| 日韩一区中文| 午夜精品国产精品大乳美女| 外国精品视频在线观看 | 午夜老司机福利| 国产日韩精品一区二区三区| 五月婷婷之婷婷| 亚洲网站啪啪| 深夜福利成人| 亚洲国产欧美在线观看| 日本久久91av| 日本小视频在线免费观看| 亚洲欧美日韩中文在线制服| 国产精品九九九九| 欧美性极品xxxx娇小| www.97视频| a在线播放不卡| 中日韩av在线播放| 亚洲少妇自拍| 久久精品在线免费视频| 久草成人在线| av一区二区三区在线观看| 成人看片网页| 97视频在线观看播放| 国产精品实拍| 国产一区二区三区在线观看视频 | 嫩草av久久伊人妇女超级a| 一区二区日韩欧美| 日韩福利一区二区三区| 欧美精品国产白浆久久久久| 91香蕉亚洲精品| 日韩网站中文字幕| 97视频在线播放| 牛牛在线精品视频| 91精品国产综合久久精品麻豆 | 欧美lavv| 国产精品xxx在线观看| 国产日韩欧美黄色| 欧美亚洲韩国| 68精品久久久久久欧美| 牛牛电影国产一区二区| 精品国产一区二区三区久久| 久蕉在线视频| 日韩电影视频免费| 亚洲精品国产一区二| 91麻豆精品国产自产在线| 特级西西444www大胆免费看| 亚洲国产成人在线| 久久精品一区二区免费播放 | 欧美日韩黄色一区二区| 人妻 日韩精品 中文字幕| 午夜精品成人在线| 久久久久久免费观看| 亚洲女同女同女同女同女同69| 极品尤物一区二区| 国产亚洲综合在线| 新91视频在线观看| 久久亚洲私人国产精品va媚药| av黄色一级片| 99re这里只有精品首页| 亚洲色图欧美日韩| 成人美女在线观看| 荫蒂被男人添免费视频| 成人h版在线观看| 黑森林av导航| 不卡一区二区三区四区| 麻豆精品国产传媒av| 成人精品免费网站| 呦呦视频在线观看| 99re8在线精品视频免费播放| 国产精品福利导航| 久久午夜色播影院免费高清| 四虎影成人精品a片| 国产视频一区在线播放| 超薄肉色丝袜一二三| 国产精品久久久久久久久免费相片| 五月婷婷欧美激情| 综合分类小说区另类春色亚洲小说欧美 | 99久久精品国产毛片| 人妻少妇精品视频一区二区三区| 91色porny在线视频| 亚洲色图 在线视频| 日本aⅴ免费视频一区二区三区 | 欧美在线观看不卡| 色婷婷一区二区| 中文字幕第一页在线播放| 欧美久久久久久久久久| 精品欧美在线观看| 亚洲精品美女久久久久| 黑人与亚洲人色ⅹvideos | 亚洲 欧美 国产 另类| 亚洲视频在线一区| 日本污视频在线观看| 日韩欧美中文字幕在线播放| 成人黄色片在线观看| 51精品视频一区二区三区| 亚洲国产精品视频在线| 日韩精品在线第一页| 在线播放麻豆| 欧美国产亚洲精品久久久8v| 天堂在线中文网官网| 成人高h视频在线| 另类ts人妖一区二区三区| 午夜精品视频在线观看一区二区 | 毛片av免费在线观看| 另类小说综合欧美亚洲| 日本少妇一级片| 久久精品夜色噜噜亚洲a∨| 中文字幕乱码在线人视频| hitomi一区二区三区精品| 在线观看日本黄色| 午夜精品免费在线| 亚洲一级在线播放| 精品视频中文字幕| a级网站在线播放| 欧美亚洲一区在线| 久久av网站| 亚洲a级在线播放观看| 私拍精品福利视频在线一区| 欧美日韩视频免费在线观看| 国产农村妇女精品一区二区| 三区视频在线观看| 麻豆精品视频在线观看免费| 风韵丰满熟妇啪啪区老熟熟女| 国产亚洲制服色| 久久久综合久久| 欧美日韩亚洲综合在线 | 欧美激情伊人电影| 成人国产精品入口免费视频| 日韩av免费网站| 999久久久精品一区二区| 亚洲欧美日韩精品综合在线观看 | 性色av一区二区三区免费| 日韩欧美精品一区二区综合视频| 国产精品二区二区三区| 91一区在线| 无码少妇一区二区三区芒果| 99久久免费精品高清特色大片| 国产精品嫩草影院俄罗斯| 色婷婷综合久久久中文一区二区| 丰满人妻妇伦又伦精品国产| 日韩有码在线播放| 麻豆精品蜜桃| 欧美黑人xxxxx| 一区二区三区四区五区精品视频| 精产国品一二三区| 亚洲丝袜另类动漫二区| 国产又粗又黄又爽| 有码中文亚洲精品| 在线观看精品| 免费看成人片| 亚洲欧美日韩专区| 五月开心播播网| 精品久久香蕉国产线看观看gif| www.狠狠干| 欧美大片在线看| 麻豆精品一区| 日本黄xxxxxxxxx100| 国精品**一区二区三区在线蜜桃| 国产精品av久久久久久无| 欧美丝袜一区二区| 九色网友自拍视频手机在线| 欧美一级片在线播放| 日韩系列在线| 亚洲精品无码久久久久久| 95精品视频在线| 欧美性猛交bbbbb精品| 亚洲欧美三级伦理| 美女色狠狠久久| 一区二区成人国产精品| 精品一区二区三区蜜桃| 青花影视在线观看免费高清| 欧美一级爆毛片| 丁香花视频在线观看| 精品999在线观看| 美女诱惑一区| 免费成人深夜天涯网站| 欧美三级中文字幕在线观看| 久草中文在线观看| 99re国产在线播放| 亚洲国产激情| 国产美女免费无遮挡| 欧美性xxxxxxxx| av网站免费在线观看| 北条麻妃高清一区| 国产精品色网| 免费黄在线观看| 欧美成人精品二区三区99精品| 国产丝袜视频在线播放| 就去色蜜桃综合| 看国产成人h片视频| 私库av在线播放| 日韩成人在线视频网站| 日本在线中文字幕一区二区三区| 一区二区91美女张开腿让人桶| 国产成人一区二区精品非洲| 欧美一二三区视频| 夜夜嗨av色综合久久久综合网 | 免费观看在线色综合| 岛国毛片在线观看| 亚洲精品大尺度| 国产精品美女午夜爽爽| 91网站在线观看免费| 久久婷婷综合激情| 国产99对白在线播放| 2019精品视频| 99久久99视频只有精品| 国产精品欧美激情在线观看| 国产精品免费久久久久| 亚洲美女性生活| 国产极品精品在线观看| 国精品一区二区三区| 嘿嘿视频在线观看| 精品少妇一区二区三区| 成人福利片在线| a级黄色一级片| 亚洲免费观看高清完整版在线| 天天干天天操av| 亚洲一区二区自拍| 日韩av一区二区在线影视| 国产精品 欧美 日韩|