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的重要概念.在面向对象中类和对象是最基本的两个概 ...
随机推荐
- R 《回归分析与线性统计模型》page140,5.1
rm(list = ls()) library(car) library(MASS) library(openxlsx) A = read.xlsx("data140.xlsx") ...
- jenkins#安装jenkins
1. 访问官网下载地址https://jenkins.io/zh/download/ 2. 选择自己的平台,然后按照文档进行操作: 主要按照文档来,下面是我按照文档按照的一个记录 #访问 https: ...
- 021、MySQL变量的使用,在MySQL中创建存储过程,并添加变量
#编写一个存储过程 CREATE PROCEDURE ShowDate ( ) BEGIN #变量定义 ); #变量赋值 set m_str1 = '曾经沧海难为水'; #输出当前时间 SELECT ...
- 吴裕雄--天生自然java开发常用类库学习笔记:RumTime类
public class RuntimeDemo01{ public static void main(String args[]){ Runtime run = Runtime.getRuntime ...
- 关于无法下载sklearn中的MNIST original数据集的问题
在使用Sklearn进行加载自带的数据集MNIST时,总是报错,代码及相应的错误显示如下: from sklearn.datasets import fetch_mldata mnist = fetc ...
- Java中用单例模式有什么好处?
Java Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在. 使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收( ...
- 《分布式消息中间件实践》P153
问题:我直接把作者的源码拷贝下来(包括xml,resource等,作者应该使用的是Eclipse,我复制到IDEA上),依赖加上.执行P153的步骤,报错如下: Exception in thread ...
- PLC与单片机执行指令区别
单片机执行指令方式与PLC执行指令方式对比 . 映射 对顺序功能图并行分支的理解. PLC与单片机都是顺序执行指令方式的. PLC执行指令分为3个阶段. PLC的一个指令周期包括 输入采样 程序执 ...
- oracle和mysql的一些区别
1.分页查询语句的区别 2.字符串拼接的区别,oracle不支持三个字符串的拼接,mysql支持三个字符串的拼接,在mybatis中,连接的是oracle数据库,字符串的拼接需要如下语句: <s ...
- Linux gcc(ar命令)打包库到另一个库中的另外一种方法
最近的项目中需要在Libcurl写一个wrapper,最好的办法是把我的wrapper和libcurl包在一起,做一个新的静态库 但是很遗憾,直接用以下命令产生的libmywrapper.a 是不能用 ...