1. 程式人生 > >python3:通過例項講解元類實現_ORM01

python3:通過例項講解元類實現_ORM01

ORM全稱“Object Relational Mapping”,即物件-關係對映,就是把關係資料庫的一行對映為一個物件,也就是一個類對應一個表,這樣,寫程式碼更簡單,不用直接操作SQL語句。

明確下我們的需求:
我們要建立一個類,並把類對映到資料庫的一張表,並校驗資料庫每個欄位的取值.
目的:脫離SQL 語句.

class  User:
    name=CharField(db_column="",max_length=10)
    #定義表的列 name 欄位,db_columns是表列名稱,並用max_length 校驗欄位的長度
    age=IntField(db_column="",min_length=0,max_length=100)
    # 定義表的列 name 欄位,db_columns是表列名稱,並用max_length and min_length 校驗欄位的長度

    class Meta:
        db_table=""
    #新增Meta class 有兩個目的 ,1.新增表名稱 2.和表的列分開,這樣思路比較清晰

user=User()
#例項化User
user.name="Andy"   
#定義name
user.age=120
#定義age  

我們的需求是對錶的列進行校驗,當年齡是str和name是int 型別都需要報錯的,
顯然直接賦值的路是行不通的.
怎麼才能達到對屬性的值進行校驗呢,這就要用到前面章節講到的屬性描述符
不懂得可以翻翻看看我的這個章節講的很細.

開始補充我們的用例,( name=CharField(db_column="",max_length=10))
編寫CharField 類

class CharField:
    def __get__(self, instance, owner):
        pass
    def __set__(self, instance, value):
        pass

對set和 get 方法進行重寫

完成的屬性描述符程式碼請看下邊:

class CharField:
    def __init__(self,db_column,max_length=None):
        self.db_column=db_column
        self.max_length=max_length
        if max_length is not None:
            if not isinstance(max_length,int):
                print("最大值要是int型別")
            elif max_length<0:
                print("不能小於0")
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        if isinstance(value,str) and len(value)<self.max_length:
            self.value=value
        else:
            print("字串的長度不能大於最大值  和必須是string 型別")
class IntField:
    def __init__(self,db_column,max=None,min=None):
        self.min_length=min
        self.db_column=db_column
        self.max_length=max
        if max is not None:
            if not isinstance(max,int):
                print("最大值要是int型別")
            elif max<0:
                print("不能小於0")
        if min is not None:
            if not isinstance(max,int):
                print("最大值要是int型別")
            elif max<0:
                print("不能小於0")
        if max is not None and min is not None:
            if min>max:
                print("最大值怎麼可能大於最小值呢")

    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        if isinstance(value,int) and self.min_length<value<self.max_length:
            self.value=value
        else:
            print("請檢查年齡是否合法")
class  User:
    name=CharField(db_column="",max_length=10)
    #定義表的列 name 欄位,db_columns是表列名稱,並用max_length 校驗欄位的長度
    age=IntField(db_column="",min=0,max=100)
    # 定義表的列 name 欄位,db_columns是表列名稱,並用max_length and min_length 校驗欄位的長度

    class Meta:
        db_table=""
    #新增Meta class 有兩個目的 ,1.新增表名稱 2.和表的列分開,這樣思路比較清晰

user=User()
user.name=0   #字串的長度不能大於最大值  和必須是string 型別
user.age=1000  #請檢查年齡是否合法   
user.name="Andy"
user.age=10
print(user.name,user.age) # Andy 10

程式碼邏輯沒有問題,校驗是好的,儲存值也沒有問題.
上邊的重寫要注意:
1.set 校驗是針對設定的值
2.init 裡面的校驗是針對我們例項化的時候.這個要搞清楚,不然理解起來很費勁.

有了屬性描述符以後,下邊就是我們的重點 要寫metaclass 類

請關注下一章節的更新. 謝謝

第一時間知道更新,請關注我