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. JDK8~JDK11的新特性

    #JDK 1.8 新特性接口中的静态方法 只能由接口自己调用 接口中的默认方法 可以不被覆盖 #JDK 1.9 新特性(可能在JDK8中被忽略了,没来得及加)接口可以定义私有方法,但是只能让自己调用, ...

  2. Unable to execute dex:Multuple dex files define 解决方法

    困扰我两天的问题终于解决了,在网上查的方法无非有三种 一. Eclipse->Project->去掉Build Automatically->Clear ->Build Pro ...

  3. 016、Java中使用小数

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  4. 初识python 廖雪峰(慕课网)

    3-9 Python中的布尔类型 短路计算 True和False是布尔值,就像1,2,3是整数,“abc”是字符串一样. 做这个题,需要了解以下两点: 第一,在一个语句中,当and和or同时存在时,a ...

  5. C#最小化到托盘+双击托盘恢复+禁止运行多个该程序

    托盘程序的制作: 1.添加notifyIcon控件,并添加Icon,否则托盘没有图标(托盘右键菜单也可直接在属性里添加):2.响应Form的Resize或SizeChanged消息: // Hide ...

  6. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-star-empty

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  7. 使用Python绘制漫步图

    代码如下: import matplotlib.pyplot as plt from random import choice class RandomWalk(): def __init__(sel ...

  8. WFP之WFP简介

    ·过滤引擎是WFP的核心组成部分,过滤引擎分为两大层:用户态基础过滤引擎和内核态过滤引擎.基础过滤引擎会与内核过滤引擎交互.·内核态过滤引擎是整个过滤引擎的主体,内部分为多个分层,每分层都代表着网络协 ...

  9. 百度杀毒停止下载,个人PC杀毒软件真的走到尽头了吗?

    在时代浪潮的席卷下,不适应的服务和产品终将被淘汰.诺基亚如此,杀毒软件亦是如此.就在近日,久久沉寂的杀毒软件市场被投下一颗重磅炸弹--百度杀毒软件官网PC端不再提供下载,但手机端依然提供下载和杀毒服务 ...

  10. swoole在线聊天学习笔记

    <?php $http=); $http->on('request',function(swoole_http_request $request,swoole_http_response ...