1. 類的成員:
1) 字段 : 普通字段、靜態字段;python
2) 方法 : 普通方法、靜態方法、類方法;編程
3) 屬性 : 普通屬性(獲取、設置、刪除);設計模式
2. 成員修飾符:app
1)公有的 任何 均可以調用;框架
2)私有的 僅類本身內部能夠調用;能夠用一個另類的方法調用,就是 obj._類名__私有(字段等),好吧,知道能這麼用就好了,最好忘了它。函數
3. 類的特殊成員:ui
__init__ 構造方法; spa
__dic__ 註釋文檔查看,函數下加引號寫的第一位置,會被此成員讀取;設計
__call__ 變量加括號執行call方法;指針
__str__ 將內存地址的內容,讀取成str內容;
__setitem__
......
4. 面向對象的其它內容:
-- isinstance 判斷一個對象是否屬於某個類;
-- issubclass 判斷一個類是否屬於某個類的子類;
-- 執行父類構造方法
-- 應用:
自定義類型,對字典進行補充,有序字典,源碼的擴展;
5. 設計模式之單例模式;
6. 異常處理:
try === except === = finally
1. 普通字段,實例:
class Foo: def __init__(self,name): self.name = name
代碼解析:
name就是普通字段,當Foo函數,被實例化時,如:obj = Foo('hailong') ,對象obj 就使用了name普通字段,普通字典默認被對象使用,因此普通字段是保存在對象裏的;
2. 靜態字段,實例:
class Province: country = "中國" # 靜態字段,保存在類裏,節省內存空間; def __init__(self,name): self.name = name country = Province.country tj = Province("天津") print(tj.country ,'\t',country)
代碼解析:
country是靜態字段,如上實例所示,靜態字段,類能夠調用,對象也能夠調用,其它語言裏是不容許的,之因此對象能夠調用靜態字段,是由於對象裏的類對象指針(對象去數據時,是先從本身自己找,找不到,經過類對象指針到類裏找)經過這種方式來訪問的;一般狀況下,咱們要使用類來調用靜態字段;
總結:
普通字段,用對象來訪問; 靜態字段,使用類來訪問,實在沒辦法時才用對象訪問;
當執行程序時,若是沒建立對象時,普通字段不會加載到內存,可是靜態字段默認會加載到內存;
1. 普通方法,實例:
class Province: country = "中國" def __init__(self,name): self.name = name def show(self): # 方法屬於類,是由對象調用的 print(self.name) tj = Province("天津") tj.show()
代碼解析:
方法屬於類,普通方法存在類裏,是由對象調用的;
2. 靜態方法,實例:
class Province: country = "中國" # 靜態字段,保存在類裏,節省內存空間; def __init__(self,name): self.name = name @staticmethod # 靜態方法,是由類調用的 def func(arg1,arg2): print(arg1,arg2) Province.func(123,'qcc')
代碼解析:
靜態方法是由類調用的,就是方法去掉self參數後,是用裝飾器staticmethod,傳參自定義,不須要建立對象,就能夠執行的方法。用於一些不通用的方法,這樣節省內存空間;
至關於Python的函數;
3. 類方法,實例:
class Province: country = "中國" # 靜態字段,保存在類裏,節省內存空間; def __init__(self,name): self.name = name @classmethod def f1(cls): print(cls) Province.f1()
代碼解析:
類方法是由類調用的,它有一個默認的形式參數cls,cls至關於類名;
1. 普通屬性,實例:
class Pager: def __init__(self,count_pager): self.count_pager = count_pager @property # 普通屬性 def all_pager(self): a1,a2=divmod(self.count_pager,10) if a2 == 0: return a1 return a1+1 p = Pager(101) print(p.all_pager) # 執行普通屬性,不用加括號了
代碼解析:
普通屬性,具備方法的訪問寫形式,具備字段的訪問形式。 至關於方法去掉括號,由對象調用;
2. 屬性操做(設置)實例:
class Pager: def __init__(self,count_pager): self.count_pager = count_pager @property def all_pager(self): a1,a2=divmod(self.count_pager,10) if a2 == 0: return a1 return a1+1 @all_pager.setter def all_pager(self,value): print(value) p = Pager(101) p.count_pager = 211 # 設置屬性,對屬性的方法進行setter; print(p.count_pager)
代碼解析:
對象生成後,count_pager 根據類參數定義一個值,當想要使用一個新值時,須要使用到設置屬性,給字段count_pager從新賦值,使用普通屬性方法setter裝飾器,從新給字段賦值;
3. 屬性操做(刪除)實例:
class Pager: def __init__(self,count_pager): self.count_pager = count_pager @property def all_pager(self): a1,a2=divmod(self.count_pager,10) if a2 == 0: return a1 return a1+1 @all_pager.setter def all_pager(self,value): print(value) @all_pager.deleter def all_pager(self): print("del all_pager") p = Pager(101) p.count_pager = 211 #設置方法,會調用all_pager.setter下的方法; print(p.count_pager) del p.all_pager # del 是個語法,會調用all_pager.deleter下的方法;
property的構造方法中有個四個參數
對象.屬性
時自動觸發執行方法對象.屬性 = XXX
時自動觸發執行方法del 對象.屬性
時自動觸發執行方法對象.屬性.__doc__
,此參數是該屬性的描述信息class Pager: def __init__(self,name): self.name = name def f1(self): return 123 def f2(self,value): print(value) def f3(self): print('del f1') # 還沒弄明白,具體怎麼用 foo = property(fget=f1,fset=f2,fdel=f3) obj = Pager('hailong') res = obj.foo print(res) obj.foo = 456 del obj.foo
代碼解析:
不用加裝飾器了,直接給靜態字段賦值,使用property,來完成屬性的功能;
由屬性的定義和調用要注意一下幾點:
注意:屬性存在乎義是:訪問屬性時能夠製造出和訪問字段徹底相同的假象
屬性由方法變種而來,若是Python中沒有屬性,方法徹底能夠代替其功能。
1. 公有的,實例:
class Province(object): def __init__(self,name): self.name = name hb = Province("河北") print(hb.name) #name是公有的,任何對象均可以調用;
代碼解析:
這個例子裏,name就是公共的,任何基於Province建立的對象都能使用;
2. 私有修飾符,實例(一):
class Province(object): def __init__(self,name): self.__name = name def f1(self): print(self.__name) hb = Province("河北") hb.f1() # print(hb.__name) # 報錯 AttributeError: 'Province' object has no attribute '__name'
代碼解析:
當把公有的,加上雙下劃線後,就變成私有的了,這時外部不能調用,只能是類裏的方法能夠調用;只有本身訪問能夠,不能被繼承;
實例(二):
class Province(object): __paw = 123 def __init__(self,name): self.__name = name def f1(self): print(Province.__paw) @staticmethod def f2(): print(Province.__paw) hb = Province("河北") hb.f1() # 經過變量調用使用了私有字段的方法; Province.f2() #直接用類調用,靜態方法裏的私有字段; hb.f2() # 也能夠成功,可是不建議這樣使用; Province.f1() # 不能夠在外部直接使用類裏的私有字段,報錯 TypeError: f1() missing 1 required positional argument: 'self'
上文介紹了Python的類成員以及成員修飾符,從而瞭解到類中有字段、方法和屬性三大類成員,而且成員名前若是有兩個下劃線,則表示該成員是私有成員,私有成員只能由類內部調用。不管人或事物每每都有不按套路出牌的狀況,Python的類成員也是如此,存在着一些具備特殊含義的成員,詳情以下:
1. del、call 和 str方法:
class Foo(object): instance = None def __init__(self,name,age): self.name=name self.age = age # 析構方法,系統垃圾回收以前執行這個方法; def __del__(self): pass # def __call__(self, *args, **kwargs): print("call") # def __str__(self): return "%s - %s" % (self.name,self.age) obj = Foo("hailong",23) obj1 = Foo("eric",23) print(obj) # 執行時,調用了str方法 res = str(obj1) # 執行時,調用了str方法 obj() # 變量加括號,執行call方法; Foo("hailong",23)() # 類執行,加括號執行call方法; print(obj1)
2. add 、 dict 方法:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __add__(self, other): temp = "%s - %d" % (self.name,other.age) return temp obj1= Foo("hailong",23) obj2= Foo('eric',19) res = obj1 + obj2 # 執行add方法; print(res) print(obj1.__dict__) # 返回obj1封裝的內容,字典格式輸出;
若是執行 類.__dict__ 會打印出類裏封裝的全部的成員,通常用於對象的封裝查看;
3. getitem、setitem和delitem方法:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __getitem__(self, item): return 123 def __setitem__(self, key, value): print(key,value) def __delitem__(self, key): print("del %s" % key) obj1= Foo("hailong",23) res = obj1['abc'] # 執行getitem方法 print(res,"----") obj1['k1'] = 122 # 執行了setitem方法 ,執行結果是k1 122 print(obj1.__dict__) # obj1沒有任何改變; del obj1['k1'] # 執行delitem方法,
對象後加括號執行call方法,加上中括號執行 getitem方法。。。
4. getitem 切片方法:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __getitem__(self, item): print(item.start) print(item.stop) print(item.step) return 123 def __setitem__(self, key, value): print(key,value) obj1= Foo("hailong",23) # res = obj1['abc'] # 字符串方法沒有切片start等位置屬性; res1 = obj1[0:4:2]
5. iter 迭代 方法:
用於迭代器,之因此列表、字典、元組能夠進行for循環,是由於類型內部定義了 __iter__
class Foo: def __init__(self,name,age): self.name = name self.age = age def __iter__(self): # iter方法 return iter([11,22,33,44]) # 可迭代類型; obj = Foo("hailong",23) for item in obj: print(item)
for循環,例子二:
class Foo: def __init__(self,name,age): self.name = name self.age = age def __iter__(self): yield 1 yield 2 obj = Foo("hailong",23) for item in obj: print(item)
6. __module__ 和 __class__
__module__ 表示當前操做的對象在那個模塊
__class__ 表示當前操做的對象的類是什麼
1. isinstance 和 issubclass 內置變量;
class Foo: pass class Func(Foo): pass obj = Foo() res = isinstance(obj,Foo) # obj 是 基於Foo類建立的,返回True; print(res) ret = issubclass(Func,Foo) # Func 類是 Foo類的一個子類,返回True; print(ret)
2. 執行父類構造方法;
如何執行,看實例:
class Foo: def f1(self): print("Foo.f1") class Func(Foo): def f1(self): super(Func,self).f1() print('Func.f1') obj = Func() res = obj.f1() # obj 執行的了本身的f1方法也執行了父類裏的f1方法,由於有super;
這個方法應用於:當想要使用其它程序的功能或框架裏的方法時,繼承框架或功能的類方法,使用super就能使用框架的功能了;
3. 有序字典:
class Mydict(dict): def __init__(self): self.li = [] super(Mydict,self).__init__() def __setitem__(self, key, value): self.li.append(key) super(Mydict,self).__setitem__(key,value) def __str__(self): temp_li = [] for key in self.li: value = self.get(key) temp_li.append("'%s':%s" %(key,value)) temp_str = "{" + ",".join(temp_li) + "}" return temp_str obj = Mydict() obj['k1'] = 123 obj['k2'] = 456 print(obj)
代碼解析:
繼承字典的類,將正常生成字典的key,添加到一個空列表,經過自定義類型對字典的生成過程從新定義,將無序存儲的字典,寫成一個列表,根據字符串拼接的方法,讀取成有序的字典;
用來建立單個實例,何時用? 無論獲取多少個實例,他們的內存地址是同樣的;
class Foo: instance = None def __init__(self,name): self.name = name @classmethod def get_instance(cls): if cls.instance: return cls.instance else: obj = cls('hailong') cls.instance = obj return obj obj1 = Foo.get_instance() obj2 = Foo.get_instance() # 無論獲取多少個實例,他們的內存地址是同樣的; print(obj1,obj2) # 兩個對象內存地址相同;
try --->except try內容若是不報錯,永遠不會執行except的內容;
一、異常基礎
在編程過程當中爲了增長友好性,在程序出現bug時通常不會將錯誤信息顯示給用戶,而是現實一個提示的頁面,通俗來講就是不讓用戶看見大黃頁!!!
try: pass except Exception,ex: pass
需求:將用戶輸入的兩個數字相加
while True: num1 = input('input num1:') num2 = input('input num2:') try: num1 = int(num1) num2 = int(num2) result = num1 + num2 try: print(result) except NameError as A: print(A) except Exception as E: print(E)
二、異常種類
python中的異常種類很是多,每一個異常專門用於處理某一項異常!!!
1) 經常使用異常:
AttributeError 試圖訪問一個對象沒有的樹形,好比foo.x,可是foo沒有屬性x IOError 輸入/輸出異常;基本上是沒法打開文件 ImportError 沒法引入模塊或包;基本上是路徑問題或名稱錯誤 IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊 IndexError 下標索引超出序列邊界,好比當x只有三個元素,卻試圖訪問x[5] KeyError 試圖訪問字典裏不存在的鍵 KeyboardInterrupt Ctrl+C被按下 NameError 使用一個還未被賦予對象的變量 SyntaxError Python代碼非法,代碼不能編譯(我的認爲這是語法錯誤,寫錯了) TypeError 傳入對象類型與要求的不符合 UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是因爲另有一個同名的全局變量, 致使你覺得正在訪問它 ValueError 傳入一個調用者不指望的值,即便值的類型是正確的
對於特殊處理或提醒的異常須要先定義,最後定義Exception來確保程序正常運行。
2)另外一種結構的異常:
try: # 主代碼塊 pass except KeyError as ex: # 異常時,執行該塊 pass else: # 主代碼塊執行完,執行該塊 pass finally: # 不管異常與否,最終執行該塊 pass
3) 主動拋出異常:
try: raise Exception('錯誤了。。。') except Exception as ex: print(ex)
4) 自定義異常:
class WupeiqiException(Exception): def __init__(self, msg): self.message = msg def __str__(self): return self.message try: raise WupeiqiException('個人異常') except WupeiqiException as e: print(e)
5)斷言
# assert 條件 assert 1 == 1 assert 1 == 2
條件成立執行,不成立就不執行;
________________________________________________________END____________________________________________________