Python说文解字_杂谈09
1. 元类编程代码分析:
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 < :
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 < :
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=)
age = IntField(db_column="age",min_value=,max_value=) class Meta:
db_table = "" if __name__ == '__main__':
user = User(name = "bobby",age =)
# user.name = "bobby"
# user.age =
user.save()
解析1:数据描述符部分:
数据描述部分分为:数据描述和非数据描述:为了方便使用,我们通过共同继承一个Field类的方式直接用这个来,来进行数据描述和飞数据描述。
解析2:我们知道type来生成动态类后面跟随(name,bases,attrs),类名,基类,属性,三个部分。我们在new一个元类的时候对他进行拆包处理。
解析3:拆包过程我们对attrs属性分别重新定义属性当中的_meta和fields部分。
解析4:判断过程:
1.判断是否属于BaseModel这个子类,是的话返回元类
2.生成一个fields = { } 的空字典永安里记录。
3.循环遍历属性当中的项目得到key值和value值:这里得到
* key = __model__ , value =__main__。
* 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,Iterator a = {1,2}
b = iter(a)
print(isinstance(a,Iterator))
print(isinstance(a,Iterable))
print(isinstance(b,Iterator))
# False
# True
# True
最新文章
- Objective-C NSData与实现NSCoding协议进行序列化和反序列化
- [问题2014A05] 复旦高等代数 I(14级)每周一题(第七教学周)
- AspxGridView
- java 的 (PO,VO,TO,BO,DAO,POJO) 解释
- [转]Oracle关于null的处理
- 看雪 安卓 dex文件
- 第十一章、认识与学习 BASH Bash Shell 的操作环境
- 读取oracle页面或者进程卡住不动(死锁)
- C#线程等待句柄
- hadoop2.6.0集群搭建
- [HNOI2012]排队
- Jsp的table导出Excel
- tarjan求强连通分量
- 微擎系统jssdk系统快速签名变量
- python3_字符串
- wordpress学习(五)----插件
- 理解 Redis(5) - 哈希值
- screen命令使用
- java反射知识点总结
- 多个 Word 文档合并为一个
热门文章
- 2、MYSQL 基本数据库命令及约束
- es和数据类型
- l5213. 玩筹码
- (转)让一个进程启动时Windbg自动Attach上去
- 百度杀毒停止下载,个人PC杀毒软件真的走到尽头了吗?
- 【转】R函数-diag()函数
- redis报错MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist
- 11.swoole学习笔记--进程信号触发器
- 二、环境安装:yarn
- 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-indent-right