python 可以通过`type`函数创建类,也可通过type判断数据类型

import socket
from io import StringIO
import sys
class TypeClass(object):
def typeprint(self, name = 'typeclass'):
print('class name is %s' %(name)) typeclasses = TypeClass()
print(type(TypeClass))
print(type(typeclasses)) def printHW(self):
print('Hello world!!!')
TypeClass2 = type('TypeClass2', (object,), dict(typeprinthw = printHW))
typeclass2 = TypeClass2()
typeclass2.typeprinthw()

  

type创建类格式为type('类名',(基类1,基类2...), dict(成员函数名=函数名))
第一个参数为类名,第二个参数为一个tuple,如果继承的基类只有一个,要注意tuple写法(基类,),第三个参数为dict构造的类成员函数
除了可以用type创建类之外,可以用`metaclass`限制类的行为

使用metaclass需要先定义一个特定功能的元类,这个元类一般按照功能名字命名,末尾以Metaclass结束,表示一个特定功能的元类,这个元类必须继承于type类,内部必须实现
`__new__`借口完成类的限定。`__new__`的调用先于`__init__`,在对象构造之前调用。

class DictMetaclass(type):
def __new__(cls, name, bases, attrs):
def insertfunc(self, key, value):
self[key]=value
attrs['insert'] = insertfunc
return type.__new__(cls,name,bases,attrs) class MyDict(dict, metaclass = DictMetaclass):
pass mydict = MyDict()
mydict.insert('nice', 3)
print(mydict['nice'])

  

定义了一个DictMetaclass元类,继承于type类,内部实现了__new__方法,__new__方法四个参数分别为准备创建的类对象,类名字,该类的基类集合,类的方法集合。并且__new__内部调用了type类的__new__函数,完成了新功能属性的绑定。下面同样实现一个list类的扩展

class ListMetaclass(type):
def __new__(cls, name, bases, attrs):
attrs['insert'] = lambda self, value: self.append(value)
return type.__new__(cls,name,bases,attrs) class Mylist(list,metaclass = ListMetaclass):
pass mylist = Mylist()
mylist.insert('name')
mylist.insert('age')
print(mylist)

  

下面为在廖雪峰官网学习的ORM框架例子
ORM全称“Object Relational Mapping”,即对象-关系映射,就是把关系数据库的一行映射为一个对象,也就是一个类对应一个表,这样,写代码更简单,不用直接操作SQL语句。
要编写一个ORM框架,所有的类都只能动态定义,因为只有使用者才能根据表的结构定义出对应的类来。
让我们来尝试编写一个ORM框架。
先实现Field类和其派生类

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 IntegerField(Field):
def __init__(self, name):
super(IntegerField,self).__init__(name, 'bigint') class StringField(Field):
def __init__(self, name):
super(StringField, self).__init__(name,'varchar(100)')

  

Field类用来管理数据库的字段和字段类型
实现ModelMetaclass这个元类,用于限制User类

class ModelMetaclass(type):
def __new__(cls,name,bases,attrs):
if name == 'Model':
return type.__new__(cls, name, bases, attrs)
print('Founc model: %s' % name)
mappings = dict()
for k, v in attrs.items():
if isinstance(v,Field):
print('Found mapping: %s ==> %s' %(k,v))
mappings[k] = v
for k in mappings.keys():
attrs.pop(k)
attrs['__mappings__'] = mappings
attrs['__table__'] = name
return type.__new__(cls, name, bases, attrs)

  

ModelMetaclass类中过滤了Model类的处理,将其他类的属性删除,将映射关系存储至__mappings__属性字段,并且__table__字段用来存储类名。
下面实现Model类

class Model(dict , 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 '%s' " %key)
def __setattr__(self, key, value):
self[key]=value def save(self):
fields = []
params = []
args = []
for k, v in self.__mappings__.items():
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))

  

Model 类继承了dict, 实现save函数,save函数将__mappings__属性值内容取出来,就是在ModelMetaclass中构造的mappings,其他类继承Model,调用save函数可以动态调用sql语句。
定义User类并且调用save

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')
u.save()

  

输出如下:

我的微信公众号:

python学习(十)元类的更多相关文章

  1. Python中的元类(metaclass)

    推荐+收藏:深刻理解Python中的元类(metaclass) 做一些笔记学习学习: 在大多数编程语言中,类就是用来描述如何生成一个对象的代码段,在Python中类也是一个对象,这个(类)对象自身拥有 ...

  2. [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式

    使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...

  3. Python之面向对象元类

    Python之面向对象元类 call方法: class People: def __init__(self,name): self.name=name # def __call__(self, *ar ...

  4. python基础——使用元类

    python基础——使用元类 type() 动态语言和静态语言最大的不同,就是函数和类的定义,不是编译时定义的,而是运行时动态创建的. 比方说我们要定义一个Hello的class,就写一个hello. ...

  5. Python基础:元类

    一.概述 二.经典阐述 三.核心总结 1.类的创建过程 2.元类的使用惯例 四.简单案例 1.默认行为 2.使用元类 五.实践为王 一.概述 Python虽然是多范式的编程语言,但它的数据模型却是 纯 ...

  6. Python学习 Part7:类

    Python学习 Part7:类 1. 作用域和命名空间 命名空间(namespace)就是一个从名称到对象的映射. 命名空间的一些实例:内置名称集(函数,像abs(),和内置异常名称),一个模块中的 ...

  7. python学习笔记4_类和更抽象

    python学习笔记4_类和更抽象 一.对象 class 对象主要有三个特性,继承.封装.多态.python的核心. 1.多态.封装.继承 多态,就算不知道变量所引用的类型,还是可以操作对象,根据类型 ...

  8. 什么是python中的元类

    所属网站分类: python高级 > 面向对象 作者:goodbody 原文链接: http://www.pythonheidong.com/blog/article/11/ 来源:python ...

  9. [Python之路] 元类(引申 单例模式)

    一.类也是对象 当我们定义一个变量或者函数的时候,我们可以在globals()的返回值字典中找到响应的映射: def A(): print("This is function A" ...

随机推荐

  1. Vue-lazyload 的使用

    Vue 项目使用 Vue-lazyload 做图片懒加载. 下载 下载 Vue-lazyload 的包NPM包 npm install vue-lazyload --save 引入 在项目 main. ...

  2. 『ACM C++』PTA浙大 | 基础题 - Have Fun with Numbers

    连着这两道都是开学前数构老师的“爱心作业”,还没上课开学就给我们布置作业了,这道题有点小坑,也经常遇到类似的问题,特地拿出来记录一下. -------------------------------- ...

  3. 4.hive的外部表和内部表

    1.外部表和内部表区别 创建表时:创建内部表时,会将数据移动到数据仓库指向的路径:若创建外部表,仅记录数据所在的路径, 不对数据的位置做任何改变. 删除表时:在删除表的时候,内部表的元数据和数据会被一 ...

  4. Fluent Python: Slice

    Pyhton中序列类型支持切片功能,比如list: >>> numbers = [1, 2, 3, 4, 5] >>> numbers[1:3] [2, 3] tu ...

  5. 如何理解IPD+CMMI+Scrum一体化研发管理解决方案之IPD篇

    如何快速响应市场的变化,如何推出更有竞争力的产品,如何在竞争中脱颖而出,是国内研发企业普遍面临的核心问题,为了解决这些问题,越来越多的企业开始重视创新与研发管理,加强研发过程的规范化,集成产品开发(I ...

  6. Scrum立会报告+燃尽图(十月二十七日总第十八次)

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2246 项目地址:https://git.coding.net/zhang ...

  7. “Hello World!”团队第六周的第一次会议

    今天是我们团队“Hello World!”团队第六周召开的第一次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.Todo List 六.会议照片 七.燃尽图 一.会议时间 ...

  8. 把字符串"3,1,2,4"以","分割拆分为数组,数组元素并按从小到大的顺序排列

    package com.wangcf; /** * 把字符串"3,1,2,4"以","分割拆分为数组,数组元素并按从小到大的顺序排列 * @author fan ...

  9. 配置resin web方式部署项目

    写在前面,推荐下载resin4.0.47版本.其它版本没有测试 最近打算做一个小项目,然后容器选用了resin.想通过web提交war文件的方式 进行部署,更新代码也方便. 试了resin最新的版本( ...

  10. WebSphere应用服务器内存泄漏探测与诊断工具选择最佳实践

    内存泄漏是比较常见的一种应用程序性能问题,一旦发生,则系统的可用内存和性能持续下降:最终将导致内存不足(OutOfMemory),系统彻底宕掉,不能响应任何请求,其危害相当严重.同时,Java堆(He ...