1、定義
類:具備相同屬性和能力的一類事物python
對象:類的具體表現api
語法:ide
# 構建 class LearnPython(object): """ 類名必須首字母大寫,駝峯體 """ country = "China" # 靜態變量 def __init__(self, name, location): # 動態方法 self.name = name self.location = location def read(self): pass # 類 # 查看類擁有的全部屬性與方法 print(LearnPython.__dict__) # {'__module__': '__main__', '__doc__': '\n 類名必須首字母大寫,駝峯體\n ', 'country': 'China', '__init__': <function LearnPython.__init__ at 0x000001E81E75E8C8>, 'read': <function LearnPython.read at 0x000001E81E75E510>, '__dict__': <attribute '__dict__' of 'LearnPython' objects>, '__weakref__': <attribute '__weakref__' of 'LearnPython' objects>} # 實例化 obj = LearnPython("Elvin", "北京") # 查看實例全部的屬性 print(obj.__dict__) # {'name': 'Elvin', 'location': '北京'} # 查看實例擁有的方法【能力】 print(obj.read()) # Elvin在北京看故宮 # 對屬性值的更改 obj.name = "LiLei" del obj.name print(obj.__dict__)
2、實例化及建立對象的過程函數
一旦執行ClassName()類實例化動做,自動執行類中的new()方法,當前類中沒有的則去基類object中執行new(cls,*args,**kwargs),建立一個對象空間,返回給ClassName(),指針
而後執行init方法,將對象空間傳給self,init方法爲這個對象空間初始化封裝屬性,code
最後將封裝好的屬性返回給ClassName()對象
3、類與對象的小結繼承
類名: 一、類名查看類中全部的變量(字段),方法(函數):類名.__dict__ 二、類名對靜態變量進行操做 方法1、類名.__dict__["變量名"] 只能查,報錯不能增刪改 **不用** 方法2、類名.變量名 可增刪改查 *****經常使用****** 三、類名對動態方法(函數)進行操做 類名.__dict__["方法名"] 或 類名.方法名 都只能查,不能增刪改 類調用函數必須給self賦值,哪怕賦的值是無用的,否則根據函數位置參數定義,就會因缺乏參數報錯 對象: 一、對象查看對象中全部的屬性:對象名.__dict__ (由於對象沒有創建本身的方法,故此時只能返回屬性的字典) 二、對象對對象自己的屬性的操做 方法一、對象名.屬性 能夠增刪改查 方法二、對象名.__dict__[屬性名] 能夠增刪改查 ******不用***** 三、對象對類中靜態字段的操做 3.一、對類靜態變量(字段)的操做:只能查,不能增刪改 3.二、對類方法的操做:只能引用,不能增刪改 self 是位置參數,默認接收的是對象的對象空間,約定俗成叫self 在類的非__init__方法中,也能夠給對象添加一些屬性,但如要使用這些屬性,前提必須先執行這個方法 類一旦建立了,就會執行裏面的代碼塊,若是裏面有print語句,就會執行,不像函數要調用才執行 類 只能操做本身的屬性及方法,沒法操做對象的屬性和方法,由於每一個對象的屬性都是本身獨有的 類屬性的補充 一、查看類的屬性和方法 dir(類名) ----->返回名字列表 類名.__dict__ ----->返回一個字典 二、特殊的類屬性 類名.__name__ # 類的名字 類名.__doc__ # 類的文檔字符串 類名.__base__ # 類的第一個父類名(繼承中從左到右) 類名.__bases__ # 類的全部父類 -----> 返回一個元組 類名.__dict__ # 類的全部屬性與方法 類名.__module__ # 類定義所在的模塊 【在類所在的腳本中執行和 print(__name__) 同樣都是固定的名字:__main__】 類名.__class__ # 實例對應的類(僅新式類中)
4、類與對象的命令空間接口
建立一個類就會建立一個類的名稱空間,用來存儲類中定義的全部名字,這些名字稱爲類的屬性 靜態屬性就是直接在類中定義的變量(靜態變量或者叫靜態字段) 動態屬性就是定義在類中的方法 類的靜態屬性是共享給全部對象的 類的動態屬性是綁定到全部對象的 建立一個對象/實例就會建立一個對象/實例的名稱空間(開始裏面只有對應類對象的指針,以便找到類的__init__()方法來傳空間地址及封裝對象屬性),存放對象/實例的名字,稱爲對象/實例的屬性 對象的查詢順序:先從對象空間去找,對象的空間沒有此變量或者方法,經過對象中的類對象指針去類中尋找. 類的查詢順序: 直接從類自己找.它沒法查找對象的屬性,由於是不一樣的命名空間 不管建立多少個對象,都是獨立開闢的命名空間,各個空間互相不能查找,干擾
class Test: count = 0 def __new__(cls, *args, **kwargs): cls.count += 1 return object.__new__(cls) def __init__(self): pass print(Test.count)
5、類的三大特性內存
繼承
Python中一個類能夠繼承一個或多個父類,父類稱爲基類,子類稱爲派生類
做用:代碼重用,規範接口,統一調用【規範調用方式,調用者不用關心實現】
class A: pass class B: pass class C(A,B): pass # 上面就是基本的一個繼承關係,C類分別繼承了A,B類的全部屬性和方法,C類實現的實例均可以訪問 # 但有一點,若是子類和父類都有相同的方法,優先執行子類本身的方法 # 全部的類,都繼承基類Object類 # 查看繼承關係 C.__bases__ # 查看是否爲某個類的對象【開發中常用】 instance(obj,cls) 如:instance("china",str) # 查看是否爲某個類的子類 issubclass(cls,fater_cls) # 接口類 定義一個抽象類,爲一組子類定義一個通用的api,使調用方式統一,且接口類是不能夠實例化的 from abc import ABCMeta, abstractmethod class Payment(metaclass=ABCMeta): @abstractmethod def pay(self, money): """經過裝飾器,標識爲抽象方法,全部子類都需實現本方法""" return # a = Payment() # Can't instantiate abstract class Payment with abstract methods pay class UnionPay(Payment): def __init__(self, year): self.year = year def pay(self, money): """若是這裏不實現此方法,就沒法實例化""" print("222") u = UnionPay("2021") # Can't instantiate abstract class UnionPay with abstract methods pay
封裝
隱藏對象的屬性和實現細節,僅提供公共訪問方式,咱們實例化調用init就是一種封裝
私有屬性
Python中將在類中以雙劃線開頭定義的變量或方法,稱爲私有屬性或方法,僅提供給類內部調用
class Test(object): def __init__(self, action): self.action = action def __smoke(self): """此方法僅僅用於類內部調用""" print(f"class want ro {self.action}") def wash(self): print(self.__smoke()) print(f"wash your {self.action}") t = Test("face") t.wash() t.somke() # AttributeError: 'Test' object has no attribute 'somke'
靜態屬性、靜態方法、類方法
class Test(object): __TYPE = "python小白養成記" def __init__(self, action): self.__action = action @property def do(self): return f"I can do:{self.__action}" @do.setter def do(self, v): """改變do返回的值""" self.__action = v @do.deleter def do(self): print("delete instance property is ok") @staticmethod def show_action(): """靜態方法:實現普通方法,不需調用實例屬性和方法""" print("just a ordinary function") @classmethod def action(cls): """類方法""" return cls.__TYPE def __repr__(self): return f"just print the object instance:{self.__action}" t = Test("eat") # 靜態屬性property 將類中方法實現的能力,調用時以屬性的方式調用 print(t.do) # I can do:eat t.do = "kiss" print(t.do) # I can do:kiss del t.do # Exception: can't delete instance property # 靜態方法 staticmethod 類中實現的方法,非實例方法,第一個參數不是self,就至關於普通方法 t.show_action() # 類方法,調用方爲類,雖然對象也能夠調用,但不建議 t.action()
多態
python天生多態,一類事物有多種狀態,相同的需求不一樣的對象接收時執行不一樣的行爲,但響應的接口是一致的
如:list、dict、set三種不一樣的對象,要刪除元素,都實現了pop方法,雖然他們內部執行的邏輯不一樣,這就是pop的多種狀態
反射【很是重要】
官方定義:程序能夠訪問、檢測和修改它自己狀態或行爲的一種能力
小白解析:經過字符串的形式操做對象的屬性【Python中的哲學:一切皆對象】
hasattr(obj,name) 對象是否有某個屬性
getattr(obj,name,default=None) 獲取對象的某個屬性,若是沒有則返回默認值
setattr(obj,name,value) 爲對象設置一個屬性name,其值爲value
delattr(obj,name) 刪除對象的某個屬性,若是該屬性不存在則拋出異常
# 示例: class Test(object): def __init__(self, code, desc): self.code = code self.desc = desc def biz(self): return dict(code=self.code, desc=self.desc) obj = Test(0, "success") # 判斷 print(hasattr(obj, "code")) # True # 獲取 fun = getattr(obj, "biz", "沒有該屬性時返回的值,不配置時爲None") print(fun()) # {'code': 0, 'desc': 'success'} # 設置新屬性 setattr(obj, "data", lambda self: dict(self.biz())) print(obj.data(obj)) # {'code': 0, 'desc': 'success'} # 刪除屬性 delattr(obj, "code") # 查看對象的全部屬性 print(obj.__dict__) # {'desc': 'success', 'data': <function <lambda> at 0x000001E0835DE8C8>} # py文件也是對象,驗證test.py文件中是否有某個方法 import test if hasattr(test,"func"): ret = getattr(test,"func")("args") print(ret)
常見的魔法方法
__new__(cls) 對象的構造方法 __init__(self) 對象的初始化方法 __call__(self,*args,**kwargs) 類的實例化對象如函數通常調用,obj=A(),obj(a,b) __del__(self) 析構方法,釋放內存,動用del obj時使用,Python內部自動觸發內存回收機制 __repr__(self) 友好的以字符串顯示對象,而不是一個內存地址空間,調用repr()方法 __str__(self) 友好的以字符串顯示對象,調用srt()方法 __dir__(self) 顯示對象的方法與屬性,調用dir() __getattr__(self,name) 定義調用方試圖獲取一個不存在屬性時的動做 __setattr__(self,name,value) 定義當一個屬性被設置時的行爲 __delattr__(self,name) 定義當一個屬性被刪除時的行爲 __getitem__(self,key) 定義獲取容器指定元素的行爲,至關於self[key] __setitem__(self, key, value) 定義設置容器中指定元素的行爲,至關於 self[key] = value __delitem__(self, key) 定義刪除容器中指定元素的行爲,至關於 del self[key] __enter__(self) 1. 定義當使用 with 語句時的初始化行爲 2. __enter__ 的返回值被 with 語句的目標或者 as 後的名字綁定 __exit__(self, exc_type, exc_value, traceback) 1. 定義當一個代碼塊被執行或者終止後上下文管理器應該作什麼 2. 通常被用來處理異常,清除工做或者作一些代碼塊執行完畢以後的平常工做