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