一个类作为metaclass的时候,我们需要重写它的__new__方法,这个方法的参数包括要创建class object的 metaclass,类名,父类集合,类成员

class MyMetaclass(type):
def __new__(metaclz,name,bases,attrs):
print("create new class ",metaclz,name)
return type.__new__(metaclz, name, bases, attrs)

  这样在调用__new__的时候,就给了我们一些发挥的空间了,一般我们可以修改bases、attrs中的成员,或则根据这自己定义的一些规则做一些特别的事情。

比如,可以利用这个来写测试框架、代码规则检测,装饰类的方法,写ORM框架等等。

 

ORM框架大致demo:

# -*- coding:utf-8 -*- 

class Field(object):
def __init__(self, name, column_type):
self.name = name
self.column_type = column_type
def __str__(self):
return '<%s:%s>' % (self.__class__.__name__, self.name) class StringField(Field):
def __init__(self, name):
super(StringField, self).__init__(name, 'varchar(100)') class IntegerField(Field):
def __init__(self, name):
super(IntegerField, self).__init__(name, 'bigint') class ModelMetaclass(type):
def __new__(cls, name, bases, attrs):
#一般的ORM框架这里应该通过bases来处理
if name=='Model':
return type.__new__(cls, name, bases, attrs)
mappings = dict() #取出 数据库中的字段
for k, v in attrs.iteritems():
if isinstance(v, Field):
print('Found mapping: %s==>%s' % (k, v))
mappings[k] = v
#删除相关的类成员
for k in mappings.iterkeys():
attrs.pop(k)
attrs['__table__'] = name # 假设表名和类名一致
attrs['__mappings__'] = mappings # 保存属性和列的映射关系
return type.__new__(cls, name, bases, attrs) class Model(dict):
__metaclass__ = ModelMetaclass def __init__(self, **kw):
print("kw:",kw)
super(Model, self).__init__(**kw) def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(r"'Model' object has no attribute '%s'" % key) def __setattr__(self, key, value):
self[key] = value def save(self):
fields = []
params = []
args = []
for k, v in self.__mappings__.iteritems():
fields.append(v.name)
params.append('?')
args.append(getattr(self, k, None))
sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))
print('SQL: %s' % sql)
print('ARGS: %s' % str(args)) class User(Model):
# 定义类的属性到列的映射:
id = IntegerField('id')
name = StringField('username')
email = StringField('email')
password = StringField('password') u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd',zz='4555')
u.save()

  

metaclass 常用方式的更多相关文章

  1. Windows校验文件哈希hash的两种常用方式

    大家经常都到哪儿去下载软件和应用程序呢?有没想过下载回来的软件.应用程序或资源是否安全呢?在 Windows 10 和 Office 2016 发布当初,很多没权限的朋友都使用第三方网站去下载安装映像 ...

  2. 操作xml文档的常用方式

    1.操作XML文档的两种常用方式: 1)使用XmlReader类和XmlWriter类操作 XmlReader是基于数据流的,占用极少的内存,是只读方式的,所以速度极快.只能采用遍历的模式查找数据节点 ...

  3. iOS应用数据存储的常用方式

    iOS应用 数据存储的常用方式 XML属性列表 plist Preference 偏好设置 NSKeyedArchiver 归档 Core Data SQLite3 应用沙盒: Layer:     ...

  4. Postman几种常用方式

    Postman几种常用方式 1.get请求直接拼URL形式 对于http接口,有get和post两种请求方式,当接口说明中未明确post中入参必须是json串时,均可用url方式请求 参数既可以写到U ...

  5. JS类继承常用方式发展史

    JS类继承常用方式发展史 涉及知识点 构造函数方式继承 1-继承单个对象 1.1 多步走初始版 1.2 多步走优化版 1.3 Object.create()方式 2-继承多个对象 2.1 遍历 Obj ...

  6. 【转】shell:date 常用方式

    在linux下获取时间字符串 命令 date # 以yyyymmdd格式输出23天之前现在这个时刻的时间 $ date +%Y%m%d –date=’23 days ago’ $ date -u Th ...

  7. iOS边练边学--应用数据存储的常用方式(plist,Preference,NSKeyedArchiver)其中的三种

    iOS应用数据存储的常用方式: XML属性列表(plist)归档 Preference(偏好设置) NSKeyedArchiver归档(NSCoding) SQLite3--这里暂且不讲 Core D ...

  8. sqlalchemy 转json 的几种常用方式

    sqlalchemy 转json 的几种常用方式 # -*- coding:utf-8 -*- import datetime from flask import Flask, json, jsoni ...

  9. iOS- 网络访问两种常用方式【GET & POST】实现的几个主要步骤

    1.前言 上次,在博客里谈谈了[GET & POST]的区别,这次准备主要是分享一下自己对[GET & POST]的理解和实现的主要步骤. 在这就不多废话了,直接进主题,有什么不足的欢 ...

随机推荐

  1. C# EF增删改查

    1.增 //1.创建一个EF数据上下文对象 MyDBEntities context=new MyDBEntities(); //2.将要添加的数据,封装成对象 Users user = new Us ...

  2. Python学习【第六篇】运算符

    运算符 算数运算: a = 21 b = 10 c = 0 c = a + b print ("1 - c 的值为:", c) c = a - b print ("2 - ...

  3. spark 基本操作

    读取文件的数据 使用的数据:https://codeload.github.com/xsankar/fdps-v3/zip/master 读取单个文件的数据 case class Employee(E ...

  4. EXC_ARM_DA_ALIGN

    ios 版本上的问题  armv7  ipad2 int64 t = *(int64*)pBuff; 如果pBuff不是8字节对齐的地址就 crash 变通的方法是通过memcpy __sync_fe ...

  5. linux centos service 参数详解

    Service文件 开门见山,直接来看两个实际的服务配置文件吧. 第一个配置是 CoreOS 系统中 Docker 服务的 Unit 文件,路径是 /usr/lib/systemd/system/do ...

  6. Life Cycle of Thread – Understanding Thread States in Java

    Life Cycle of Thread – Understanding Thread States in Java 深入理解java线程生命周期. Understanding Life Cycle ...

  7. Java 线程的转换及状态

    线程的状态转换是线程控制的基础. 线程状态总的可分为五大状态:分别是生.死.可运行.运行.等待/阻塞.用一个图来描述如下: 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnabl ...

  8. tomcat7 配置

    引用:http://blog.csdn.net/mengxiangbaidu/article/details/7020484 1.安装JDK, 2.安装, apt-get install  tomca ...

  9. linux Centos下安装 sqlserver

    我使用的是Centos7在虚拟机中完成测试 1.下载设置mssql的yum源,执行以下代码,现在sqlserver的linux版本130多兆,网速慢的请等待 curl https://packages ...

  10. cef 介绍

    介绍 cef 是一个基于google chromiun的简单的框架. 它主要是作为一个内嵌浏览器嵌入到客户端应用程序中. 可以再 http://cefbuilds.com 下载最新的编译版本. 总体框 ...