裝飾器,都可以裝飾類內部的方法函數
classmethod :使該方法綁定給類來使用,稱爲類的綁定方法ui
staticmethod:使該方法變成了一個普通函數,即非綁定方法code
再來複習一下對象的綁定方法特殊之處對象
對象的綁定方法特殊之處:ip
- 由對象調用,會將對象當作第一個參數傳入該方法內存
類的綁定方法特殊之處:md5
- 由類來調用,會將類名當作第一個參數傳入該方法utf-8
上代碼字符串
import settings import uuid import hashlib class People: def __init__(self,name,age): self.name = name self.age = age # 將該方法裝飾成類的綁定方法 # 登陸認證,從配置文件中讀取用戶名密碼 @classmethod def login_auth(cls): obj = cls(settings.USER,settings.PWD) return obj # 將該方法裝飾成一個普通的函數,不會自動傳值,對象or類均可以調用 @staticmethod def create_id(): uuid_obj = uuid.uuid4() return hashlib.md5(str(uuid_obj).encode("utf-8")).hexdigest() def index(self): print("驗證經過,顯示主頁") # 用classmethod 裝飾過的方法返回一個對象 obj = People.login_auth() # 在該方法中經過讀取配置文件的參數實例化出一個對象 obj.index() # 將返回出去的對象調用其餘方法 # 調用 staticmethod 裝飾過的方法,即普通函數,由類調用,也能夠對象調用 print(People.create_id())
python中內置的函數,均傳入兩個參數(參數1,參數2)
isinstance:判斷一個對象是不是一個類的實例(判斷一個對象是不是已知類型)
issubclass:判斷一個類是不是另外一個類的子類。
class Foo: pass class Bar(Foo): pass # isinstance 判斷對象是不是類的實例 f = Foo() print(isinstance(f,Foo)) # True l = [1,2] print(isinstance(l,list)) # True # issubclass 判斷類是不是另外一個類的子類 print(issubclass(Bar,Foo)) # True
反射☞的是經過 「字符串」 對 對象或類的屬性進行操做
hasattr:經過字符串,判斷該字符串是不是對象或類的屬性
getattr:經過字符串,獲取對象或類的屬性
setattr:經過字符串,設置對象或類的屬性
delattr:經過字符串,刪除對象或類的屬性
上代碼
class People: country = "China" def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex # hasattr 傳兩個參數,判斷對象有沒有屬性 p1 = People("qinyj",18,"nan") print(hasattr(p1,"country")) # True # getattr 傳三個參數,也能夠傳兩個參數,若是屬性不存在報錯 p2 = People("qinyj",18,"nan") print(getattr(p2,"country","China")) # setattr 傳兩個參數,設置對象的屬性 p3 = People("qinyj",18,"nan") setattr(p3,"country","China") print(getattr(p3,"country",)) # delattr 傳兩個參數,刪除對象的屬性 p4 = People("qinyj",18,"nan") # delattr(p4,"country") # print(getattr(p4,"country",))
# 反射練習 class Movie: def input_cmd(self): print("請輸入命令") while True: cmd = input("請輸入執行的方法名").strip() # hasattr 與 getattr 連用實例 if hasattr(self,cmd): getattr(self,cmd)() def upload(self): print("電影開始上傳") def download(self): print("電影開始下載") m = Movie() m.input_cmd()
凡是在類內部定義,"__名字__
"的方法都稱之爲魔法方法,又稱類的內置方法
__init__
:初始化函數,在類調用時自動觸發
__str__
:打印對象的時候自動觸發
__del__
:刪除對象的名稱空間,最後才執行
__getattr__
:對象.屬性獲取屬性,沒有獲取到值自動觸發
__setattr__
:對象.屬性賦值的時候自動觸發
__call__
:在帝鄉被調用時自動觸發
__new__
:在__init__
前自動觸發,產生一個空的對象
class Foo(object): ''' 如下均是類的內置方法, ''' def __new__(cls, *args, **kwargs): print(cls) return object.__new__(cls) # 產生一個空的對象 def __init__(self): print("在類調用時觸發") def __str__(self): return "在打印對象的值時觸發" def __del__(self): print("最後執行該方法,刪除內存地址") def __getattr__(self, item): return "沒有獲取對象屬性時觸發" def __setattr__(self, key, value): print("設置對象屬性值時觸發") print(key,value) self.__dict__[key] = value def __call__(self, *args, **kwargs): print("調用對象時觸發") f = Foo() # 打印對象 print(f) # <class '__main__.Foo'> # 在類調用時觸發 # 在打印對象的值時觸發 # 最後執行該方法,刪除內存地址 # 獲取對象屬性x print(f.x) # <class '__main__.Foo'> # 在類調用時觸發 # 在打印對象的值時觸發 # 沒有獲取對象屬性時觸發 # 最後執行該方法,刪除內存地址 # 對象賦值新的屬性 f.x = "x" print(f.x) # <class '__main__.Foo'> # 在類調用時觸發 # 在打印對象的值時觸發 # 沒有獲取對象屬性時觸發 # 設置對象屬性值時觸發 # x x # x # 最後執行該方法,刪除內存地址 # 對象調用 f() # <class '__main__.Foo'> # 在類調用時觸發 # 在打印對象的值時觸發 # 沒有獲取對象屬性時觸發 # 設置對象屬性值時觸發 # x x # x # 調用對象時觸發 # 最後執行該方法,刪除內存地址 class MyFile: def __init__(self,file_name,mode="r",encoding="utf-8"): self.file_name = file_name self.mode = mode self.encoding = encoding def file_open(self): self.f = open(self.file_name,self.mode,encoding=self.encoding) def file_read(self): res = self.f.read() print(res) # 使用del內置函數,在最後執行,就會調用關閉文件操做 def __del__(self): self.f.close() print("文件關閉成功") f = MyFile("settings.py") f.file_open() f.file_read() print("程序結束,對象將被銷燬!")
單例模式指的是單個實例,實例指的是調用類產生的對象
實例化多個對象時會產生不一樣的內存地址,單例可讓全部調用者,在調用類產生對象的狀況下都指向同一分內存地址,例如,打開文件
單例模式目的:爲了減小內存佔用
class File: __instance = None # 單例模式1 # 使用類的綁定方法, @classmethod def singleton(cls,file_name): # 類中設置一個私有屬性__instance, # 在類本身調用完成產生一個對象,將這個對象賦值給類的這個屬性, # 若是這個類屬性有對象了,就說明已經實例化過了無需再次實例化,直接返回 # 外部調用者只需調用其方法便可使用單例模式操做對象 if not cls.__instance: obj = cls(file_name) cls.__instance = obj return cls.__instance # 單例模式2 # 使用__new__產生一個空的對象,至關於建立一個空的對象,調用時至關於多個變量指向這個對象 def __new__(cls, *args, **kwargs): if not cls.__instance: cls.__instance = object.__new__(cls) return cls.__instance ''' 實例化出來的對象內存地址同樣 <__main__.File object at 0x000000000295C668> <__main__.File object at 0x000000000295C668> <__main__.File object at 0x000000000295C668> ''' def __init__(self,file_name,mode="r",encoding="utf-8"): self.file_name = file_name self.mode = mode self.encoding = encoding def open(self): self.f = open(self.file_name,self.mode,encoding=self.encoding) def read(self): res = self.f.read() print(res) # def __del__(self): # self.f.close() f1 = File("settings.py") f2 = File("settings.py") f3 = File("settings.py") print(f1) print(f2) print(f3) # 以下:產生的三個對象 內存地址均不一樣 # <__main__.File object at 0x000000000298C6D8> # <__main__.File object at 0x000000000298C710> # <__main__.File object at 0x000000000298C6A0> # 讓其成爲單例模式調用 f1 = File.singleton("settings.py") f2 = File.singleton("settings.py") f3 = File.singleton("settings.py") print(f1) print(f2) print(f3) # 以下:產生的三個對象 內存地址均相同 # <__main__.File object at 0x0000000009F6F908> # <__main__.File object at 0x0000000009F6F908> # <__main__.File object at 0x0000000009F6F908>