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的更多相关文章

  1. Python说文解字_杂谈05

    1. isinstance和type: is和==符号,is指的是内存地址,是不是一个对象,ID知否相同 集成链 class A: pass class B(A): pass b = B() prin ...

  2. Python说文解字_杂谈08

    1. Python变量到底是什么? Python和Java中的变量本质不一样,python的变量实质是一个指针 int str,便利贴 a = 1 # 1. a贴在1上面 # 2. 它的过程是先生成对 ...

  3. Python说文解字_杂谈07

    1. 深入dict from collections.abc import Mapping,MutableMapping # dict 属于mapping类型 a = {} print(isinsta ...

  4. Python说文解字_杂谈01

    1. Python在Ubuntu下面下载Python 2. 安装依赖包 sudo apt-get update sudo apt-get install build-essential python- ...

  5. Python说文解字_杂谈06

    1. 序列类型的分类: 容器类型:list.tuple,deque 扁平序列:str.bytes.bytearray.array.array 可变序列:list.dequte.bytearray.ar ...

  6. Python说文解字_杂谈04

    1. 鸭子类型: 当你看到一只鸟走来像鸭子,游泳起来像鸭子,叫起来也像鸭子,他么他就可以叫做鸭子.任何可迭代的对象.一样的方法,可以用可迭代的话,就可以迭代的组合打印.__getitem__可以塞到任 ...

  7. Python说文解字_杂谈03

    1. 我们从前面的知识得到,所有的类都要继承自object这个基类(超类),另外我们知道“继承”可以继承类的属性和方法.我们起始通过type创建类的时候,自然而然的也会从ojbect继承他的一些属性和 ...

  8. Python说文解字_杂谈02

    1. Py中三个中啊哟的概念type.object和class的关系. type生成了int生成了1 type->class->obj type用来生成类对象的 object是最顶层的基类 ...

  9. Python说文解字_详解元类

    1.深入理解一切接对象: 1.1 什么是类和对象? 首先明白元类之前要明白什么叫做类.类是面向对象object oriented programming的重要概念.在面向对象中类和对象是最基本的两个概 ...

随机推荐

  1. linux安装postgresql数据库

    本文提供数据库安装脚本,有部分需要优化,就是脚本中的方法执行存在前后依赖,但是代码里面没有对上一个执行结果进行判断,如果提供的路径和安装包没有问题,脚本能够正常执行 #!/bin/bash # ins ...

  2. Java 类的属性

    章节 Java 基础 Java 简介 Java 环境搭建 Java 基本语法 Java 注释 Java 变量 Java 数据类型 Java 字符串 Java 类型转换 Java 运算符 Java 字符 ...

  3. poj 1854 Evil Straw Warts Live 变成回文要几次

    Evil Straw Warts Live Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 1799   Accepted: ...

  4. 配置thinkphp对mysql线上线下切换不同环境的配置 - (mysql-thinkphp) (1)

    1.先打印出配置项的信息,在Index控制器下面的index->index里面设置 namespace app\index\controller; class Index { public fu ...

  5. webservice调试(XML参数)

    <![CDATA[ <?xml version="1.0" encoding="UTF-8"?><MsgText> <use ...

  6. maven集成SSM项目,jetty部署运行——搭建maven项目部署jetty试运行(一)

    今天闲来没事采用maven集成一个SSM框架来复习复习,下面开始我的复习之旅,慢慢来,不着急,哈哈,不忙时候敲两下,整起来. 工具为Eclipse,首先需要建立一个maven工程,file右键new- ...

  7. SpringBoot 系列教程之事务隔离级别知识点小结

    SpringBoot 系列教程之事务隔离级别知识点小结 上一篇博文介绍了声明式事务@Transactional的简单使用姿势,最文章的最后给出了这个注解的多个属性,本文将着重放在事务隔离级别的知识点上 ...

  8. 本机无oracle,远程连接

    描述 本机无oracle,通过PLSQL Developer程序,连接虚拟机中的oracle11gR2 1 下载instant-client 需要和服务端版本对应 下载相应的instant-clien ...

  9. Windows平台整合SpringBoot+KAFKA__第3部分_代码部分(结束)

    重要的地方说下,算是给自己提醒,也给阅读者凑合着看看吧: (1)序列化.反序列化: 注意看这个文章 https://www.jianshu.com/p/5da86afed228 很多网上的例子都是 推 ...

  10. centos7下使用yum安装ifconfig工具

    步骤1:搜索安装包 步骤2:使用yum安装 至此,ifconfig工具安装完毕,希望对你有帮助~