1. 程式人生 > >Python3學習筆記——類

Python3學習筆記——類

world 賦值語句 學習 特殊成員 name odin attribute delattr AR

#!/usr/bin/env python
#-*- coding:utf-8 -*-
#面向對象(類+對象)
三大特性:封裝、繼承、多態
類的成員:
    字段:
        普通字段:保存在對象(實例)中,執行只能通過對象訪問
        靜態字段:保存在類中,執行時可以通過對象訪問,也可以通過類訪問
    方法:
        普通方法:保存在類中,由對象調用
        靜態方法:@staticmethod,保存在類中,通過類可以直接調用,且不需要self參數
        類方法:@classmethod,保存在類中,由類直接調用,需要一個cls參數,代指當前類
        
類的創建和使用:
class 類名: def 方法名(self,參數): print("hello") 實例名=類名() 實例名.方法名(參數) # 1.類的定義: class Bar: #叫Bar的類 def foo(self): #叫foo的方法 print(hello) # 2.類的執行 obj = Bar() #創建實例(對象)--執行方法的中間人 obj.foo() # # 3.self參數 類在創建的過程中會在內存中開辟一個屬於類的空間,當創建一個實例的時候也會創建屬於實例的空間, 當實例需要執行類中的方法,回去找類空間相應的方法,方法中的self參數,接收的就是實例本身。 所以self代指調用方法的對象(實例) 例1:
class Bar: def foo(self,arg): print(self,arg) obj = Bar() print(obj) obj.foo(hello) <__main__.Bar object at 0x000001D1995E4470> <__main__.Bar object at 0x000001D1995E4470> hello 例2: class Bar: def foo(self,arg): print(self,self.name,arg) #②self表示實例本身,self.name:從方法中讀取實例中的元素,
obj = Bar() obj.name = "Tom" #①在實例的內存空間中添加新的元素 obj.foo(hello) <__main__.Bar object at 0x000001EB3F6645F8> Tom hello # 4.構造方法 obj = Bar() #作用:1.創建對象;2.通過對象執行類中的一個特殊方法 例1: class Bar: def __init__(self): """ 構造方法 """ print(創建對象時自動執行構造方法) obj = Bar() 例2: class Bar: def __init__(self,name,age): self.n = name self.a = age def foo(self): print(self.n,self.a) obj = Bar("Tom",10) obj.foo() # 5.類的三大特性之“繼承” 5.1:父類與子類 class Father: #父類(基類) def __init__(self): pass def bar(self): pass class Son(Father): #子類(派生類) def foo(self): pass obj = Son() obj.bar() 5.2:類的重寫 class F: def f1(self): print(F.f1) def f2(self): print(F.f2) class S(F): def s1(self): print(S.s1) def f2(self): #重寫父類方法,其本質是在執行f2的方法時,在S類中已經找到,不會再向上(即父類)去找 print(S.f2) obj = S() obj.f2() 5.3:supper(子類名,self).父類方法 父類名.父類方法(self) class F: def f1(self): print(F.f1) def f2(self): print(F.f2) class S(F): def s1(self): print(S.s1) def f2(self): super(S,self).f2() #先執行父類的方法,再執行自己的方法 F.f2(self) # 另一種寫法,推薦使用supper寫法 print(S.f2) obj = S() obj.f2() 5.4:多繼承 ①左側優先 ②一條道做到黑 ③有共同的父類,最後在父類中找 例1: class F: def bar(self): print(F.bar) class F1(F): def boo(self): print(F1.bar) class F2: def bar(self): print(F2.bar) class S(F1,F2): #從下往上找 pass obj = S() obj.bar() --------- F.bar 例2: class F1: def bar(self): print(F1.bar) class F2: def bar(self): print(F2.bar) class S(F2,F1): #從左往右找 pass obj = S() obj.bar() --------- F2.bar 例3: class Base: def bar(self): print(Base.bar) class F(Base): def foo(self): print(F.bar) class F1(F): def foo(self): print(F1.bar) class F2(Base): def bar(self): print(F2.bar) class S(F1,F2): pass obj = S() obj.bar() #有共同的父類,最後在父類中找 --------- F2.bar # 6.類的三大特性之多態 Python原生多態。 # 7.類的成員之字段 class Bar: #靜態字段:屬於類, city = "Beijing" def __init__(self,name): #普通字段:屬於對象,只能通過對象(實例)訪問 self.name = name #普通方法 def foo(self): print(self.name) obj = Bar(Tom) #通過對象訪問普通字段 print(obj.name) #直接通過類訪問靜態字段 print(Bar.city) ------- Tom Beijing # 8.類的成員之方法 class Bar: # 普通方法 def foo(self): print("Bar.foo") # 靜態方法 @staticmethod def show(): # print("Bar.show") # 靜態方法 @staticmethod def person(name,age): print(name,age) # 類方法 @classmethod def classmd(cls): # cls是類名, print(Bar.classmd) print(cls) # 普通方法,通過對象調用 obj = Bar() obj.foo() # 靜態方法,通過類可以直接調用 Bar.show() Bar.person(Tom,18) # 類方法,通過類可以直接調用 Bar.classmd() --------- Bar.show Tom 18 Bar.classmd <class __main__.Bar> # 應用場景: # 對象中需要保存一些值,執行某功能的時候需要使用對象中的值 --> 普通方法 # 不需要對象中的值 --> 靜態方法 # 9.類的成員之屬性 class Bar: def __init__(self): pass # 屬性 @property def foo(self): return 1 @foo.setter def foo(self,val): print(val,"setter") @foo.deleter def foo(self): print("delete") obj = Bar() obj.foo=123 #執行賦值語句將執行@foo.setter下對應的方法 del obj.foo #執行@foo.deleter下對應的方法 ---------- 123 setter delete 例1: class Page: def __init__(self,page): try: p = int(page) except Exception as e: p = 1 self.page = p @property def start(self): val = (self.page-1) * 10 return val @property def end(self): val = self.page * 10 return val li = [] for i in range(1000): li.append(i) while True: p = input("請輸入頁碼:") if p == "q": break obj = Page(p) print(li[obj.start:obj.end]) 例2:屬性的另一種表示方法 class Bar: def f1(self): return 1 def f2(self,val): print(f2:,val) def f3(self): print("f3:del") per = property(fget=f1,fset=f2,fdel=f3,doc="註釋") obj = Bar() print(obj.per) obj.per = 123 del obj.per ---------- 1 f2: 123 f3:del # 10.成員修飾符 ***子類在繼承父類時,父類中的私有字段子類不能繼承*** 例:公有成員和私有成員 #!/usr/bin/env python # -*- coding: utf-8 -*- class Bar: __city = "Beijing" #靜態字段的私有化 def __init__(self,name,age): self.name = name self.__age = age #私有字段,外部不能直接訪問 def foo(self): #方法可以訪問私有字段,通過方法間接訪問私有字段 print(self.__age) def __show(self): # 私有方法,外部不能直接訪問 return "hello world" def func(self): #間接訪問私有方法 return self.__show() obj = Bar(Tom,18) print(obj.name) obj.foo() # 通過方法間接訪問私有字段 #間接訪問私有方法 r = obj.func() print (r) # 11.特殊成員 11.1 __call__方法 class Bar: def __init__(self): print("init") def __call__(self): print("call") obj = Bar() obj() #對象加括號自動執行__call__方法 11.2 __str____int__ class Bar: def __init__(self): pass def __int__(self): return 111 def __str__(self): return "str" obj = Bar() print(obj,type(obj)) r = int(obj) #int 加對象,自動執行對象的int方法,並將返回值賦值給int對象 print(r) r = str(obj) print(r) #str 加對象,自動執行對象的str方法,並將返回值賦值給str對象 ------------ str <class __main__.Bar> 111 str 11.3 例:__str_ class Bar: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return "%s:%s" %(self.name,self.age) obj = Bar("Tom",18) print(obj) ----------- Tom:18 11.4 __del__ 析構方法:對象銷毀的時候執行 class Bar: def __init__(self): pass def __del__(self): print("析構方法") obj = Bar() 11.5 __dict__ 將字段中的成員以字段的形式返回 class Bar: """註釋""" def __init__(self,name,age): self.name = name self.age = age obj = Bar(Tom,18) #將字段中的成員以字段的形式返回 print(Bar.__dict__) print(obj.__dict__) --------- {__module__: __main__, __init__: <function Bar.__init__ at 0x0000013DAD733AE8>, __weakref__: <attribute __weakref__ of Bar objects>, __doc__: 註釋, __dict__: <attribute __dict__ of Bar objects>} {name: Tom, age: 18} 11.6 __getitem____setitem____delitem__ class Bar: """註釋""" def __init__(self): pass def __getitem__(self,item): return item + 10 def __setitem__(self,k,v): print(k,v) def __delitem__(self,val): print(delete:,val) obj = Bar() print(obj[2]) obj[name]=Tom del obj[del] ---------------- 12 name Tom delete: del 11.7 __iter__ 如果類中有__iter__方法,其對象就是一個可叠代對象; 對象名.__iter__()的返回值是叠代器 class Bar: def __iter__(self): return iter([11,22,33]) obj = Bar() for i in obj: print(i) #for循環執行obj對象的類中的__iter__方法,並獲取其叠代器;循環上一步中返回的對象 # 12.mateclass # 13.反射 #通過字符串操作對象中的成員 class Bar: def __init__(self,name,age): self.name = name self.age = age def foo(self): print("hello world") obj = Bar("Tom",18) b = "name" #利用b取出obj中name的值 # 方法1: print(obj.__dict__[b]) # 方法2: # getattr() 去什麽東西裏面獲取什麽內容 s = getattr(obj,b) print(s) f = getattr(obj,foo) print(f) f() #getattr 判斷是否有某個成員 print(hasattr(obj,foo)) #setattr setattr(obj,k1,v1) #新設置的值存在對象中 print(obj.k1) #delattr delattr(obj,name) print(obj.name) # 從類中取成員 class Bar: city = "Beijing" def __init__(self,name,age): self.name = name self.age = age def foo(self): print("hello world") print(getattr(Bar,city)) # 從模塊中取成員 import module getattr(module,func) getattr(module,Bar) # 例:反射的應用 #!/usr/bin/env python # -*- coding: utf-8 -*- while True: inp = input("請輸入要訪問的URL:") if inp == "q": break class Bar: def f1(self): return "首頁" def f2(self): return "新聞" def f3(self): return "博客" obj = Bar() if hasattr(obj,inp): f = getattr(obj,inp) print(f()) else: print("404") # 14.單例模式 應用場景:數據庫連接池 例: class Bar: __v = None @classmethod def get_instance(cls): if cls.__v: return cls.__v else: cls.__v = Bar() return cls.__v # 不用再使用Bar()創建實例 obj1 = Bar.get_instance() print(obj1) obj2 = Bar.get_instance() print(obj2) obj3 = Bar.get_instance() print(obj3) ---------------- <__main__.Bar object at 0x0000026D865B4A20> <__main__.Bar object at 0x0000026D865B4A20> <__main__.Bar object at 0x0000026D865B4A20>

Python3學習筆記——類