Python說文解字_雜談09

 1. 元類編程代碼分析:sql

import numbers

class Field:
    pass

class IntField(Field):
    # 數據描述符:
    # 初始化
    def __init__(self,db_column=None,min_value=None,max_value=None):
        self._value = None
        self.min_value = min_value
        self.max_value = max_value
        self.db_column = db_column
        if min_value is not None:
            if not isinstance(min_value,numbers.Integral):
                raise ValueError("min_value must be int")
            elif min_value < 0:
                raise ValueError("min_value must be positive int")
        if max_value is not None:
            if not isinstance(max_value, numbers.Integral):
                raise ValueError("max_value must be int")
            elif max_value < 0:
                raise ValueError("max_value must be positive int")
        if min_value is not None and max_value is not None:
            if min_value > max_value:
                raise ValueError("min_value must be smaller than max_value")

    def __get__(self, instance, owner):
        return self._value

    def __set__(self, instance, value):
        if not isinstance(value,numbers.Integral):
            raise ValueError("int value need")
        if value < self.min_value or value > self.max_value:
            raise ValueError("value must between min_value and max_value")
        self._value = value

class CharField(Field):

    def __init__(self,db_column,max_length=None):
        self._value = None
        self.db_column = db_column
        if max_length is None:
            raise ValueError("you must specify max_length for charfield")
        self.max_length = max_length

    def __get__(self, instance, owner):
        return self._value

    def __set__(self, instance, value):
        if not isinstance(value,str):
            raise ValueError("string value need")
        if len(value) > self.max_length:
            raise ValueError("value len excess len of max_length")
        self._value = value

class ModelMetaClass(type):
    def __new__(cls, name,bases,attrs, **kwargs):
        if name == "BaseModel":
            return super().__new__(cls, name,bases,attrs, **kwargs)
        fields = {}
        for key,value in attrs.items():
            if isinstance(value,Field):
                fields[key] = value
        attrs_meta = attrs.get("Meta",None)
        _meta = {}
        db_table = name.lower()
        if attrs_meta is not  None:
            table = getattr(attrs_meta,"db_table",None)
            if table is not None:
                db_table = table
        _meta["db_table"] = db_table
        attrs["_meta"] = _meta
        attrs["fields"] = fields
        del attrs["Meta"]
        return super().__new__(cls, name,bases,attrs, **kwargs)

class BaseModel(metaclass=ModelMetaClass):
    def __init__(self, *args,**kwargs):
        for key,value in kwargs.items():
            setattr(self,key,value)
        return super().__init__()

    def save(self):
        fields = []
        values = []
        for key,value in self.fields.items():
            db_column = value.db_column
            if db_column is None:
                db_column = key.lower()
            fields.append(db_column)
            value = getattr(self,key)
            values.append(str(value))
        sql = "insert {db_table}({fields}) value({values})".format(db_table = self._meta["db_table"],fields=",".join(fields),values=",".join(values))

class User(BaseModel):
    name = CharField(db_column="name",max_length=10)
    age = IntField(db_column="age",min_value=1,max_value=100)

    class Meta:
        db_table = ""

if __name__ == '__main__':
    user = User(name = "bobby",age =28)
    # user.name = "bobby"
    # user.age = 28
    user.save()

 

 

  解析1:數據描述符部分:編程

    數據描述部分分爲:數據描述和非數據描述:爲了方便使用,咱們經過共同繼承一個Field類的方式直接用這個來,來進行數據描述和飛數據描述。app

  解析2:咱們知道type來生成動態類後面跟隨(name,bases,attrs),類名,基類,屬性,三個部分。咱們在new一個元類的時候對他進行拆包處理。spa

  解析3:拆包過程咱們對attrs屬性分別從新定義屬性當中的_meta和fields部分。code

  解析4:判斷過程:orm

  1.判斷是否屬於BaseModel這個子類,是的話返回元類blog

  2.生成一個fields = { } 的空字典永安裏記錄。繼承

  3.循環遍歷屬性當中的項目獲得key值和value值:這裏獲得ci

    * key = __model__ , value =__main__。get

    * key = __qualname__  value = 'user'

    *  key = name  value= <_main__.charfField>

    * 記錄一次:{'name': <__main__.CharField object at 0x0000028555A3CFD0>} (fields字典中)

    * 再記錄一次:<__main__.IntField object at 0x0000028555AD7198> (到字典中)

    另外:bases = tuple  fileds = { }   name = str‘User’

   4. db_table 把table的名字記錄到裏面:db_table:'user"取小寫

  5.最終把attrs的屬性值中的User改成user,age,name,_meta:{db_table},fields都該改了

  {'__module__': '__main__', '__qualname__': 'User', 'name': <__main__.CharField object at 0x0000028555A3CFD0>, 'age': <__main__.IntField object at 0x0000028555AD7198>, '_meta': {'db_table': ''}, 'fields': {'name': <__main__.CharField object at 0x0000028555A3CFD0>, 'age': <__main__.IntField object at 0x0000028555AD7198>}}

_meta = {'db_table': ''}

fields = {'name': <__main__.CharField object at 0x0000028555A3CFD0>, 'age': <__main__.IntField object at 0x0000028555AD7198>}

   總結:這麼作的目的就是在類造成以前,給類增長一些判斷的功能,再使用這些屬性的時候無需再添加了。讓這些類具備一些自然的屬性。

 

 2. Python的迭代協議:

  什麼是迭代器?

  迭代器是什麼?迭代器是訪問集合內元素的一種方式,通常是用來遍歷數據

  迭代器如下標的訪問方式不同,迭代器是不能反悔的,迭代器提供了一種惰性訪問的方式(惰性訪問,是在訪問數據的時候纔會生成或迭代)

  #[] list, __iter__

  # Iterable = __iter__  iterator = __next__ 

from collections.abc import Iterable,Iteratora = {1,2}b = iter(a)print(isinstance(a,Iterator))print(isinstance(a,Iterable))print(isinstance(b,Iterator))# False# True# True
相關文章
相關標籤/搜索