# -*- encoding: utf-8 -*-
import os
'''
第33条: 用元类来验证子类
关键:
1 元类
作用: 验证某个类定义是否正确
原理: 定义新的类时,它会运行验证代码,确保新类符合规范
定义元类: 定义元类,需要从type中继承
对于使用该元类的其他类来说,会把这些类的class语句提中的内容发送给元类的
__new__方法。
2 元类的特点与引用场景
特点: 元类可以获知那个类的名称,继承的父类,以及定义在class与具体中的全部类属性
应用场景: 为了确保类的参数有效,可以把验证逻辑添加到Meta.__new__方法中
例如需要用类表示多边形,定义特殊验证类作为多边形的基类,把这个验证类当成自己的元类
注意: 元类中编写的验证逻辑时针对该基类的子类,而非基类本身
3 元类用法示例:
1) 元类继承自type,包含: 元数据,使用元类的那个类的名称,使用元类的那个类的父类,使用元类的那个类的类属性
2) 返回时,返回 type.__new__(meta, name, bases, class_dict)
3) 使用元类的类在类中定义一个类属性如下:
__metaclass__ = MyMetaClass
样例:
class ValidatePolygon(type):
def __new__(meta, name, bases, class_dict):
# 不要验证基类本身,而是验证基类的子类
if bases != (object,):
if class_dict['sides'] < 3:
raise ValueError('Polygons need more than three sides')
return type.__new__(meta, name, bases, class_dict)
class Polygon(object):
__metaclass__ = ValidatePolygon
@classmethod
def interiorAngles(cls):
return (cls.sides - 2) * 180
class Triangle(Polygon):
sides = 3
4 总结
元类可以在生成子类对象之前验证子类的定义是否符合要求
子类的class语句处理完成后,会调用其元类的__new__方法
参考:
Effectiv Python 编写高质量Python代码的59个有效方法
'''
class Meta(type):
def __new__(meta, name, bases, class_dict):
print "meta: {meta}, name: {name}, bases: {bases}, class_dict: {class_dict}".format(
meta=meta,
name=name,
bases=bases,
class_dict=class_dict
)
return type.__new__(meta, name, bases, class_dict)
class MyClass(object):
__metaclass__ = Meta
stuff = 123
def foo(self):
pass
class ValidatePolygon(type):
def __new__(meta, name, bases, class_dict):
# 不要验证基类本身,而是验证基类的子类
if bases != (object,):
if class_dict['sides'] < 3:
raise ValueError('Polygons need more than three sides')
return type.__new__(meta, name, bases, class_dict)
class Polygon(object):
__metaclass__ = ValidatePolygon
@classmethod
def interiorAngles(cls):
return (cls.sides - 2) * 180
class Triangle(Polygon):
sides = 3
print "Before class"
class Line(Polygon):
print "Before sides"
sides = 1
print "After sides"
print "After class"
def useMetaClass():
myClass = MyClass()
def process():
useMetaClass()
if __name__ == "__main__":
process()