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
Python说文解字_杂谈09的更多相关文章
- Python说文解字_杂谈05
1. isinstance和type: is和==符号,is指的是内存地址,是不是一个对象,ID知否相同 集成链 class A: pass class B(A): pass b = B() prin ...
- Python说文解字_杂谈08
1. Python变量到底是什么? Python和Java中的变量本质不一样,python的变量实质是一个指针 int str,便利贴 a = 1 # 1. a贴在1上面 # 2. 它的过程是先生成对 ...
- Python说文解字_杂谈07
1. 深入dict from collections.abc import Mapping,MutableMapping # dict 属于mapping类型 a = {} print(isinsta ...
- Python说文解字_杂谈01
1. Python在Ubuntu下面下载Python 2. 安装依赖包 sudo apt-get update sudo apt-get install build-essential python- ...
- Python说文解字_杂谈06
1. 序列类型的分类: 容器类型:list.tuple,deque 扁平序列:str.bytes.bytearray.array.array 可变序列:list.dequte.bytearray.ar ...
- Python说文解字_杂谈04
1. 鸭子类型: 当你看到一只鸟走来像鸭子,游泳起来像鸭子,叫起来也像鸭子,他么他就可以叫做鸭子.任何可迭代的对象.一样的方法,可以用可迭代的话,就可以迭代的组合打印.__getitem__可以塞到任 ...
- Python说文解字_杂谈03
1. 我们从前面的知识得到,所有的类都要继承自object这个基类(超类),另外我们知道“继承”可以继承类的属性和方法.我们起始通过type创建类的时候,自然而然的也会从ojbect继承他的一些属性和 ...
- Python说文解字_杂谈02
1. Py中三个中啊哟的概念type.object和class的关系. type生成了int生成了1 type->class->obj type用来生成类对象的 object是最顶层的基类 ...
- Python说文解字_详解元类
1.深入理解一切接对象: 1.1 什么是类和对象? 首先明白元类之前要明白什么叫做类.类是面向对象object oriented programming的重要概念.在面向对象中类和对象是最基本的两个概 ...
随机推荐
- Unity VFX踩坑
先挖个坑,要实现如下效果,这几个Demo都来自Unity日本分布技美总监Keijiro Takahashi,效果过于酷炫,请收下膝盖.. PS:先缓缓,VFX暂时还不支持安卓 Keijiro Taka ...
- Card Stacking 队列模拟
题目链接:https://ac.nowcoder.com/acm/contest/993/ABessie is playing a card game with her N-1 (2 <= N ...
- GDOI#345. 送礼物「JSOI 2015」01分数规划+RMQ
题目描述 JYY和CX的结婚纪念日即将到来,JYY来到萌萌开的礼品店选购纪念礼物.萌萌的礼品店很神奇,所有出售的礼物都按照特定的顺序都排成一列,而且相邻的礼物之间有一种神秘的美感.于是,JYY决定从中 ...
- MQTT 协议学习:007-Keep Alive 连接保活 与 对应报文(PINGREQ、PINGRESP)
背景 keep alive 是 CONNECT 报文中可变头的一部分. 我们提到过 Broker 需要知道 Client 是否非正常地断开了和它的连接,以发送遗愿消息.实际上 Client 也需要能够 ...
- 微信公众号开发 获取openid时报错40029 invalid code 问题的解决
{"errcode":40029,"errmsg":"invalid code, hints: [ req_id: aELCyY4ce-WOFLAa ...
- 【测试】性能测试及性能测试工具Loadrunner
性能测试简介 软件系统的性能包括很多方面,有执行效率,资源占用,系统稳定性,安全性,兼容性,可靠性,可扩展性等.这些都是可以衡量一个软件系统性能好坏的指标.而性能测试是指通过自动化测试工具去模拟多种正 ...
- TP框架数据模型
1.TP框架的数据模型需要建在Model文件夹下: 1.数据模型 与控制器相似,但是每个数据模型控制一张数据表. 2.数据模型可写可不写,如果不写 则沿用父类数据模型. 2.访问数据库: 1.更改数据 ...
- Vulkan SDK 之Render Pass
Create a Render Pass A render pass describes the scope of a rendering operation by specifying the co ...
- VUE- 异步等待方法嵌套
VUE- 异步等待方法嵌套 vue在一个方法执行完后执行另一个方法用Promise来实现.Promise是ES6的新特性,用于处理异步操作逻辑,用过给Promise添加then和catch函数,处理成 ...
- (20)sopel算法
基础知识的理论,主要看这个博客:https://blog.csdn.net/github_38140310/article/details/68959931 然后代码展示: #include &quo ...