Python使用描述器實現(xiàn)ORM模型的方法詳解
訪問或者修改描述器對象的屬性時無法觸發(fā)__setattr__等方法,只會觸發(fā)描述器類內(nèi)部的__set__,__get__,__delete__方法.
ORM模型:類名對應(yīng)表名,對象對應(yīng)的數(shù)據(jù)行,類屬性對應(yīng)數(shù)據(jù)行的各字段,有幾個表字段,就綁定幾個類屬性;往表中增加數(shù)據(jù)就是創(chuàng)建對象,每創(chuàng)建一個對象,就是增加一行數(shù)據(jù)記錄。
ORM框架的功能:
1.建立模型類和表之間的對應(yīng)關(guān)系,允許我們通過面向?qū)ο蟮姆绞讲僮鲾?shù)據(jù)庫。
2.根據(jù)設(shè)計的模型類生成數(shù)據(jù)庫中的表格。
3.通過方便的配置就可以進行數(shù)據(jù)庫的切換。
MySql的常用數(shù)據(jù)類型:
1.整數(shù):int,bit
2.小數(shù):decimal(decimal表示浮點數(shù),decimal(5,2)表示共計5位數(shù),小數(shù)占2位)
3.字符串:varchar(可變長度),char(不可變長度)
4.日期時間:date,time,datetime
5.枚舉類型:enum
模型類案例:
""" django的ORM模型字段 BooleanField: 布爾字段,True或False CharField(max_length=最大長度): 字符串,參數(shù)max_length表示最大字符個數(shù) IntegerField: 整數(shù) """ class TestReport(BaseTable): class Meat: verbose_name = '測試報告' db_table = "TestReport" report_name = models.CharField(max_length=40, null=False) start_at = models.CharField(max_length=40, null=True) status = models.BooleanField() testRun = models.IntegerField() successes = models.IntegerField() reports = models.TextField()
1.__set__方法:設(shè)置屬性
""" 只要一個類中出現(xiàn)了: __get__(self,instance,owner) __set__(self,instance,value) __delete__(self,instance) __set_name__(self,owner,name) 中的任意一個方法,這個類就不是一個普通的類了, 應(yīng)被稱為: 描述器類(應(yīng)用在ORM模型中) """ class Field(object): """ 只要一個類中出現(xiàn)了以下任意一個方法,這個類就是一個描述器類 """ def __get__(self, instance, owner): pass def __set__(self, instance, value): print('---set---方法被觸發(fā)了') def __delete__(self, instance): pass class Model(object): attr = Field() # attr是一個描述器對象,修改時無法觸發(fā)__setattr__等方法, # 只能觸發(fā)描述器類內(nèi)部的__set__方法 if __name__ == '__main__': m = Model() m.attr = 666 # 嘗試修改attr屬性 print(m.attr) # 輸出: ---set - --方法被觸發(fā)了 None
class Field(object): """ 只要一個類中出現(xiàn)了以下任意一個方法,這個類就是一個描述器類 """ def __get__(self, instance, owner): pass def __set__(self, instance, value): """ :param instance: 修改的對象 :param value: 修改的值 :return: """ print('---set---方法被觸發(fā)了') self.value = value print(self) # <__main__.Field object at 0x7fecc01f8a30> print(instance) # <__main__.Model object at 0x7fecc01f8a00> print(value) # 666 def __delete__(self, instance): pass class Model(object): attr = Field() # attr是一個描述器對象,修改時無法觸發(fā)__setattr__等方法, # 只能觸發(fā)描述器類內(nèi)部的__set__方法 if __name__ == '__main__': m = Model() print(m) # <__main__.Model object at 0x7fecc01f8a00>,與instance相同 m.attr = 666 # 嘗試修改attr屬性
2.__get__方法:訪問屬性
""" 只要一個類中出現(xiàn)了: __get__(self,instance,owner) __set__(self,instance,value) __delete__(self,instance) __set_name__(self,owner,name) 中的任意一個方法,這個類就不是一個普通的類了, 應(yīng)被稱為: 描述器類(應(yīng)用在ORM模型中) """ class Field(object): """ 只要一個類中出現(xiàn)了以下任意一個方法,這個類就是一個描述器類 """ def __get__(self, instance, owner): print('---get---方法被觸發(fā)了') def __set__(self, instance, value): """ :param instance: 修改的對象 :param value: 修改的值 :return: """ print('---set---方法被觸發(fā)了') self.value = value def __delete__(self, instance): pass class Model(object): attr = Field() # attr是一個描述器對象,修改時無法觸發(fā)__setattr__等方法, # 只能觸發(fā)描述器類內(nèi)部的__set__方法 if __name__ == '__main__': m = Model() m.attr = 666 # 嘗試修改attr屬性 print(m.attr) # 輸出: ---set - --方法被觸發(fā)了 ---get - --方法被觸發(fā)了 None
""" 只要一個類中出現(xiàn)了: __get__(self,instance,owner) __set__(self,instance,value) __delete__(self,instance) __set_name__(self,owner,name) 中的任意一個方法,這個類就不是一個普通的類了, 應(yīng)被稱為: 描述器類(應(yīng)用在ORM模型中) """ class Field(object): """ 只要一個類中出現(xiàn)了以下任意一個方法,這個類就是一個描述器類 """ def __get__(self, instance, owner): print('---get---方法被觸發(fā)了') print(instance) # <__main__.Model object at 0x7f80b81a09d0> print(owner) # <class '__main__.Model'> return self.value def __set__(self, instance, value): """ :param instance: 修改的對象 :param value: 修改的值 :return: """ print('---set---方法被觸發(fā)了') self.value = value def __delete__(self, instance): pass class Model(object): attr = Field() # attr是一個描述器對象,修改時無法觸發(fā)__setattr__等方法, # 只能觸發(fā)描述器類內(nèi)部的__set__方法 if __name__ == '__main__': m = Model() m.attr = 666 # 嘗試修改attr屬性 print(m.attr) # 666 # 輸出: ---set - --方法被觸發(fā)了 ---get - --方法被觸發(fā)了 < __main__.Model object at 0x7f80b81a09d0 > < class '__main__.Model'> 666
3.__delete__方法:刪除屬性
""" 只要一個類中出現(xiàn)了: __get__(self,instance,owner) __set__(self,instance,value) __delete__(self,instance) __set_name__(self,owner,name) 中的任意一個方法,這個類就不是一個普通的類了, 應(yīng)被稱為: 描述器類(應(yīng)用在ORM模型中) """ class Field(object): """ 只要一個類中出現(xiàn)了以下任意一個方法,這個類就是一個描述器類 """ def __get__(self, instance, owner): return self.value def __set__(self, instance, value): """ :param instance: 修改的對象 :param value: 修改的值 :return: """ print('---set---方法被觸發(fā)了') self.value = value def __delete__(self, instance): print('---delete---方法被觸發(fā)了') class Model(object): attr = Field() # attr是一個描述器對象,修改時無法觸發(fā)__setattr__等方法, # 只能觸發(fā)描述器類內(nèi)部的__set__方法 if __name__ == '__main__': m = Model() m.attr = 666 # 嘗試修改attr屬性 del m.attr # ---delete---方法被觸發(fā)了 print(m.attr) # None # 輸出: ---set - --方法被觸發(fā)了 ---delete - --方法被觸發(fā)了 666
""" 只要一個類中出現(xiàn)了: __get__(self,instance,owner) __set__(self,instance,value) __delete__(self,instance) __set_name__(self,owner,name) 中的任意一個方法,這個類就不是一個普通的類了, 應(yīng)被稱為: 描述器類(應(yīng)用在ORM模型中) """ class Field(object): """ 只要一個類中出現(xiàn)了以下任意一個方法,這個類就是一個描述器類 """ def __get__(self, instance, owner): print('---get---方法被觸發(fā)了') print(instance) # <__main__.Model object at 0x7f80b81a09d0> print(owner) # <class '__main__.Model'> return self.value def __set__(self, instance, value): """ :param instance: 修改的對象 :param value: 修改的值 :return: """ print('---set---方法被觸發(fā)了') self.value = value def __delete__(self, instance): print('---delete---方法被觸發(fā)了') print(instance) # <__main__.Model object at 0x7ff61806a160> self.value = None class Model(object): attr = Field() # attr是一個描述器對象,修改時無法觸發(fā)__setattr__等方法, # 只能觸發(fā)描述器類內(nèi)部的__set__方法 if __name__ == '__main__': m = Model() m.attr = 666 # 嘗試修改attr屬性 del m.attr # ---delete---方法被觸發(fā)了 print(m.attr) # None # 輸出: ---set - --方法被觸發(fā)了 ---delete - --方法被觸發(fā)了 < __main__.Model object at 0x7ff61806a160 > ---get - --方法被觸發(fā)了 < __main__.Model object at 0x7ff61806a160 > <class '__main__.Model'> None
4.描述器實現(xiàn)ORM模型:
""" 通過描述器實現(xiàn)ORM模型 """ class CharField(object): def __init__(self,max_length=20): self.max_length = max_length def __get__(self, instance, owner): return self.value def __set__(self, instance, value): # 首先判斷是否為空 if value is not None: # 再判斷是否是字符串 if isinstance(value, str): # 再判斷長度是否符合要求 if len(value) <= self.max_length: self.value = value else: raise TypeError('length need less than {}'.format(self.max_length)) else: raise TypeError('need a str') else: raise TypeError("can not be None") def __delete__(self, instance): self.value = None class IntegerField(object): def __get__(self, instance, owner): return self.value def __set__(self, instance, value): # 首先判斷是否為空 if value is not None: # 再判斷是否是整數(shù)int if isinstance(value, int): self.value = value else: raise TypeError('need a int') else: raise TypeError("can not be None") def __delete__(self, instance): self.value = None class UserModel(object): # 定義用戶信息的模型類 name = CharField(max_length=20) # 定義:name只能賦值為字符串 pwd = CharField(max_length=40) age = IntegerField() # 定義:age只能賦值為整數(shù) if __name__ == '__main__': user = UserModel() user.name = "春田" print(user.name) # 輸出: 春田 user.age = 130 print(user.age) # 輸出: 130 user.pwd = 'wsdgdgdrgerdsfs方式范德薩發(fā)阿瑟費薩法 sfa fda fsdf sdf fg' print(user.pwd) # 輸出: TypeError: length need less than 40
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Python獲取命令實時輸出-原樣彩色輸出并返回輸出結(jié)果的示例
今天小編就為大家分享一篇Python獲取命令實時輸出-原樣彩色輸出并返回輸出結(jié)果的示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07Python爬蟲之Selenium中frame/iframe表單嵌套頁面
這篇文章主要介紹了Python爬蟲之Selenium中frame/iframe表單嵌套頁面,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12淺談pandas中Dataframe的查詢方法([], loc, iloc, at, iat, ix)
下面小編就為大家分享一篇淺談pandas中Dataframe的查詢方法([], loc, iloc, at, iat, ix),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04Python數(shù)據(jù)分析numpy的Nan和Inf使用注意點詳解
這篇文章主要為大家介紹了Python數(shù)據(jù)分析numpy的Nan和Inf使用注意點,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08python之從文件讀取數(shù)據(jù)到list的實例講解
下面小編就為大家分享一篇python之從文件讀取數(shù)據(jù)到list的實例講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-04-04Python統(tǒng)計節(jié)假日剩余天數(shù)的腳本
過完春節(jié),盼著下一個節(jié)日,那么如何判斷距離節(jié)假日還有多少天呢?今天小編給大家介紹使用python腳本來解決這個問題,對Python統(tǒng)計節(jié)假日倒計時腳本感興趣的朋友一起看看吧2022-02-02python append、extend與insert的區(qū)別
這篇文章主要介紹了python append、extend與insert的區(qū)別的相關(guān)資料,初學(xué)者對這幾個概念經(jīng)常搞混,這里就幫大家理清楚,需要的朋友可以參考下2016-10-10