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