1、用元类验证子类

每当我们定义新类的时候,元类就会运行雅正代码,以确保这个新类符合规定的规范。
Python系统把子类的class语句处理完毕,就会调用元类的 __new__ 方法。元类可以通过 __new__ 方法,获取子类、孙子类的名称,父亲及属性。
这样使得我们不需要将验证代码放在本类 __init__ 方法中,等到构建对象再验证。

下例中,定义一个边数小于3的子类,class语句一结束,元类的验证代码就会拒绝这个class。

class ValidatePolygon(type):
def __new__(meta, name, bases, class_dict):
# Don't validate the abstract Polygon class
if bases != (object,):
if class_dict['sides'] < 3:
raise ValueError('Polygons need 3+ sides')
return type.__new__(meta, name, bases, class_dict) class Polygon(object, metaclass=ValidatePolygon):
sides = None # Specified by subclasses @classmethod
def interior_angles(cls):
return (cls.sides - 2) * 180 class Triangle(Polygon):
sides = 3 print(Triangle.interior_angles())

2、用元类注册子类

每次从基类中继承子类时,基类的元类都可以自动运行注册代码。
这在需要反向查找 ‘reverse lookup’ 时很有用,使得在简单标识符和对应的类之间,建立映射关系。
依然利用的是class语句执行完,自动调用元类的 __new__ 方法。

import json 

registry = {}

def register_class(target_class):
registry[target_class.__name__] = target_class def deserialize(data):
params = json.loads(data)
name = params['class']
target_class = registry[name]
return target_class(*params['args']) class Meta(type):
def __new__(meta, name, bases, class_dict):
cls = type.__new__(meta, name, bases, class_dict)
register_class(cls)
return cls class Serializable(object):
def __init__(self, *args):
self.args = args def serialize(self):
return json.dumps({
'class': self.__class__.__name__,
'args': self.args,
}) def __repr__(self):
return '%s(%s)' % (
self.__class__.__name__,
', '.join(str(x) for x in self.args)) class RegisteredSerializable(Serializable, metaclass=Meta):
pass class Vector3D(RegisteredSerializable):
def __init__(self, x, y, z):
super().__init__(x, y, z)
self.x, self.y, self.z = x, y, z v3 = Vector3D(10, -7, 3)
print('Before: ', v3)
data = v3.serialize()
print('Serialized:', data)
print('After: ', deserialize(data)) print(registry)

3、用元类注解类的属性

使用元类像是在 class 语句上放置了挂钩,class语句处理完毕,挂钩就会立刻触发。
下列中借助元类设置了 Filed.nameFiled.name

class Field(object):
def __init__(self):
# These will be assigned by the metaclass.
self.name = None
self.internal_name = None def __get__(self, instance, instance_type):
if instance is None: return self
return getattr(instance, self.internal_name, '') def __set__(self, instance, value):
setattr(instance, self.internal_name, value) class Meta(type):
def __new__(meta, name, bases, class_dict):
for key, value in class_dict.items():
if isinstance(value, Field):
value.name = key
value.internal_name = '_' + key
cls = type.__new__(meta, name, bases, class_dict)
return cls class DatabaseRow(object, metaclass=Meta):
pass class BetterCustomer(DatabaseRow):
first_name = Field()
last_name = Field()
prefix = Field()
suffix = Field() foo = BetterCustomer()
print('Before:', repr(foo.first_name), foo.__dict__)
foo.first_name = 'Euler'
print('After: ', repr(foo.first_name), foo.__dict__)

元类总结就到这里,自己也没有完全理解清楚。
希望对此有深刻理解的pythoner留言。

代码来自:https://github.com/bslatkin/effectivepython

Python的元类的更多相关文章

  1. python 通过元类控制类的创建

    一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...

  2. Python 的元类设计起源自哪里?

    一个元老级的 Python 核心开发者曾建议我们( 点击阅读),应该广泛学习其它编程语言的优秀特性,从而提升 Python 在相关领域的能力.在关于元编程方面,他的建议是学习 Hy 和 Ruby.但是 ...

  3. 关于python的元类

    当你创建一个类时: class Foo(Bar): pass Python做了如下的操作: Foo中有__metaclass__这个属性吗?如果是,Python会在内存中通过__metaclass__ ...

  4. 理解python的元类

    看了一篇文档,借鉴一下!写下自己对python元类的理解,欢迎各位大神给出意见. 我的理解就是 type用来创建元类,元类用来创建类,类用来创建实例 这样一想,是不是可以认为元类创建类的过程等同于类创 ...

  5. 【转】Python 之 元类

    原文链接: https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python      http://python.jo ...

  6. Python中元类

    元类(metaclass) 简单地说,元类就是一个能创建类的类,而类class 是由type创建的,class可以创建对象 type与object的关系详见:python中type和object 1. ...

  7. 转---一文读懂 python 的元类

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

  8. Python之元类详细解析

    一.补充内置函数isinstance和issubclass 1.isinstance是判断一个对象是不是由一个对象产生的 class Foo: pass obj=Foo() print(isinsta ...

  9. Python之元类详解

    一.引子 元类属于Python面向对象编程的深层魔法,99%的人都不得要领,一些自以为搞明白元类的人其实也是自圆其说,点到为止,从队元类的控制上来看就破绽百出,逻辑混乱: 二.什么是元类 一切源自于一 ...

随机推荐

  1. 深度解析PHP数组函数array_slice

    看到array_slice()这个函数让我想起了VFP中的range这个范围取值的子句 这个函数一共有四个参数: 被取值的数组(必需) 取值的起始位置(必需) 取值的终止位置,如果不填写默认到数组最后 ...

  2. CodeForces 544C (Writing Code)(dp,完全背包)

    题意:有n个程序员,要协作写完m行代码,最多出现b个bug,第i个程序员每写一行代码就会产生a[i]个bug,现在问,这n个人合作来写完这m行代码,有几种方案使得出的bug总数不超过b(题中要求总方案 ...

  3. 【JAVAWEB学习笔记】网上商城实战:环境搭建和完成用户模块

    网上商城实战 今日任务 完成用户模块的功能 1.1      网上商城的实战: 1.1.1    演示网上商城的功能: 1.1.2    制作目的: 灵活运用所学知识完成商城实战. 1.1.3    ...

  4. poj2104(划分树模板)

    poj2104 题意 给出一个序列,每次查询一个区间,要求告诉这个区间排序后的第k个数. 分析 划分树模板,O(mlogn). 建树.根据排序之后的数组,对于一个区间,找到中点的数,将整个区间分为左右 ...

  5. Node.js爬虫-爬取慕课网课程信息

    第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让 ...

  6. 谈谈this对象

    通过平常的使用简单总结了一下不同形式的函数调用下this的指向,函数的调用形式决定了this的指向.就简单分析一下以下几种情况: 情况一:纯粹的函数调用 eg: var x=1; function f ...

  7. NLTK学习笔记(八):文法--词关系研究的工具

    [TOC] 对于一门语言来说,一句话有无限可能.问题是我们只能通过有限的程序来分析结构和含义.尝试将"语言"理解为:仅仅是所有合乎文法的句子的大集合.在这个思路的基础上,类似于 w ...

  8. MongoDB--数据库管理

    <strong>1.mongod 启动项注释(默认不能生成路径,需手动建立)</strong><br /><span style="white-sp ...

  9. MiniProfiler使用点滴记录-2017年6月23日11:08:23

    1.看似针对同样一段查询表ef达式,重复执行却没有被记录下来.其实这是正常情况,因为ef并没有重复去执行 相同sql查询. 2.MiniProfiler结合MVC过滤器进行 拦截记录Sql,示例代码: ...

  10. java 动态代理的实现

    http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html