python 原类Metaclass 与 class语句

python 在2.7中新式类中出现了原类这个强大无比的工具,以下内容仅仅针对新式类

原类(metaclass)
内置的type是所有原类的基类,原类仅接受3个参数,原类的实例是一个普通类
普通类(cls)
内置的object是所有普通类的基类,可接受任意个参数,普通类的实例是一个
一般对象(obj)
由普通类创建的对象

type 是可接受多个参数的,若三个参数则返回一个cls,第一个参数表示函数名,第二个参数表示继承列表,第三个参数是函数属性

cls = type("class_name", (), {}) 
print isinstanse(cls, objects)  # -> True
print cls.__class__  # -> <type 'type'>  通过原类创建的都是新式类,都继承自object
print object.__class__  # -> <type 'type'> 默认的object对象是type的一个实例

再来说说python的class语句吧

class MyClass(object,):
    a = 1
    def addone(self, x):
        return self.a + x
基本上是等价于
def addone(self, x):
    return self.a + x
MyClass = type('MyClass', (object,), {'a': 1, 'addone': addone}
del addone
class 看起来就是一个type的语法糖,这是就有了一个问题;如果是继承自type得原类创建cls,是不是class语句就没法玩了。此时引出了一个python类的一个内置属性 __metaclass__ (__meta__ python>3)python规定如果一个class申明的时候设置了__metaclass__就用这个对应的值来作为type。听起来有点绕,看例子
class MyType(type):
    def __call__(self, *args, **kwargs):
        print "meta_calling", args, kwargs
        obj = super(MyType, self).__call__(*args, **kwargs)
        print "meta_called", obj
        return obj
 
def addone(self, x):
    return self.a + x
MyClass = MyType('MyClass', (object,), {'a': 1, 'addone': addone}
del addone
基本上是等价于
class MyType(type):
    def __call__(self, *args, **kwargs):
        print "meta_calling", args, kwargs
        obj = super(MyType, self).__call__(*args, **kwargs)
        print "meta_called", obj
        return obj
 
class MyClass(object,):
    __metaclass__ = MyType
    a = 1
    def addone(self, x):
        return self.a + x
这样看起来,class语句基本都可以被type可调用对象替代了,这可以干什么呢?总的说,就是我们不用再去手动申明class了,我们可以写一个程序用type自己创建class,毕竟在python这种动态语言中,class也是一个对象。
不知道各位看官是否写过python的web项目。在django或者flask中使用form表单控件时,通常都是申明一个表单类;如果表单的内容不确定的时候,比如表单内容根据配置来显示,这个时候用type自动生成对应的表单类就非常的简洁。
当然,原类是概念上的统一,起强大特性能不用就不要用(但不是说能不会就不会),用的好造福万年,用的不好遗臭万年

关于xu xc

已经工作了,有点懒,完了在写自我介绍吧
此条目发表在python分类目录,贴了, 标签。将固定链接加入收藏夹。