文档章节

Python元类

borey
 borey
发布于 2015/02/10 15:35
字数 394
阅读 31
收藏 0

1,使用type()函数运行时动态创建Class

2,定义metaclass类从type类继承,重写__new__方法,注意区分Model类和从Model继承的子类

3,定义模板类Model,使用__metaclass__ = metaclass元类

4,定义User类从Model类继承实现“Object Relational Mapping”,即对象-关系映射

#!/usr/bin/python
#-*- coding: utf-8 -*-

class Field(object):
	"""docstring for Field"""
	def __init__(self, name, colum_type):
		super(Field, self).__init__()
		self.name = name
		self.colum_type = colum_type
	def __str__(self):
		return '<%s:%s>' %(self.__class__.__name__, self.name)
		
class StringField(Field):
	"""docstring for StringField"""
	def __init__(self, name):
		super(StringField, self).__init__(name, 'varchar(100)')

class IntegerField(Field):
	"""docstring for IntegerField"""
	def __init__(self, name):
		super(IntegerField, self).__init__(name, 'bigint')

class ModelMetaclass(type):
	"""docstring for ModelMetaclass"""
	def __new__(cls, name, bases, attrs):
		print 'ModelMetaclass', cls, name, bases, attrs
		if name == 'Model': #区分Model与其子类型
			return type.__new__(cls, name, bases, attrs)
		print 'Found model:%s' %name
		mappings = dict()
		for k, v in attrs.iteritems():
			if isinstance(v, Field):
				print 'Found mappings: %s ==> %s' %(k, v)
				mappings[k] = v
		#删除Model子类的同名属性
		for k in mappings.iterkeys():
			attrs.pop(k)	
		attrs['__mappings__'] = mappings
		attrs['__table__'] = name
		return type.__new__(cls, name, bases, attrs)					

class Model(dict):
	"""docstring for Model"""
	__metaclass__ = ModelMetaclass

	def __init__(self, **kw):
		super(Model, self).__init__(**kw)
	
	def __getattr__(self, key):
		try:
			return self[key]
		except KeyError:
			raise AttributeError(r'"Model" object has no attribute' %key)
	
	def __setattr__(self, key, value):
		self[key] = value

	def save(self):
		field = []
		params = []
		args = []
		for k, v in self.__mappings__.iteritems():
			field.append(v.name)
			params.append('?')
			args.append(getattr(self, k, None))
		sql = 'insert into %s (%s) values (%s)' %(self.__table__, ','.join(field), ','.join(params))
		print 'Sql: %s' %sql
		print 'ARGS: %s' %str(args)
		
class User(Model):
	"""docstring for User"""
	def __init__(self, **kw):
		super(User, self).__init__(**kw)

	id = IntegerField('uid')
	name = StringField('username')
	email = StringField('email')
	password = StringField('password')
		
def main():
	#“Object Relational Mapping”,即对象-关系映射
	u = User(id='123456', name='Mick', email='mick@gmail.com', password='12345678')
	u.save()

if __name__ == '__main__':
	main()



© 著作权归作者所有

共有 人打赏支持
borey
粉丝 26
博文 55
码字总数 31182
作品 0
深圳
程序员
Python学习笔记二十四( 元类 )

class属性 class属性可以查看对象的类型. Person 类的实例对象person 的类型时Person 类类型, Python 是面向对象的语言, 那么Person 的类对象的类型又是什么? Person / int / str 的类对象的...

DragonFangQy
05/27
0
0
深刻理解Python中的元类(metaclass)

深刻理解Python中的元类(metaclass) 译注:这是一篇在Stack overflow上很热的帖子。提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解。他知道这肯定...

memorybox
2013/05/05
0
0
Python基础总结成千行代码,让Python入门更简单!

只要学会这千行代码,不管你是零基础还是弱基础或是没有接触过编程,都可以快速入门Python!当时我就不信邪啊,等我看完之后,即使作为一个Python老鸟了,还是领会到了很多教授他的独特见解!...

糖宝lsh
09/10
0
0
深刻理解Python中的元类

译注:这是一篇在Stack overflow上很热的帖子。提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解。他知道这肯定和自省有关,但仍然觉得不太明白,希...

ifnoelse
2014/07/21
0
0
万字长文带你成为Python老司机

万字长文带你成为Python老司机 前言: 本文主要总结项目开发中和面试中的Python高级知识点,是进阶Python高级工程师必备要点。 主要内容: No.1 一切皆对象 众所周知,Java中强调“一切皆对象...

棋帅小七
08/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

js实现产生n个随机数,并且随机数之和是固定值

function getrandom(minnum , maxnum ,total,size){ var num = total; //定义整数 var length= size; //定义多个整数的数量 var numArr = []; while(length > 1){ var rnd = Math.floor(Mat......

开源昕昕
4分钟前
0
0
精选Spring Boot三十五道必知必会知识点!

Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家。本文精选了三十五个常见的Spring Boot知识点,祝你一臂之力! 问题一 Spring Boot、Spring MVC 和 Sp...

Java填坑之路
6分钟前
1
0
MyBatis学习笔记

相关文档 mybatis深入理解(一)之 # 与 $ 区别以及 sql 预编译 MyBatis 处理sql中的 大于,小于,大于等于,小于等于

OSC_fly
6分钟前
0
0
Gradle从不同地方复制文件到一个文件夹/打zip包

复制 task copySDK(type: Copy, dependsOn: [":fatJarTask"]) { delete JAR_NAME delete SDK_OUT_PATH delete "$ROOT_BUILD_PATH/$SDK_ZIP_NAME" into('/jniLibs') {......

SuShine
7分钟前
0
0
CentOS关闭占用端口,修改Apache默认端口,并重启Apache

查找并关闭进程 在Linux系统中可以使用lsof命令和kill命令,两个命令配合查找并关闭占用端口的进程 查看某一端口使用情况的命令: lsof -i:端口号 效果如下,PID即进程的ID 根据PID关闭进程,...

临江仙卜算子
13分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部