python中的元类总结:
-
元类实际上做了以下三方面的工作:
- 干涉创建类的过程
- 修改类
- 返回修改之后的类
总结一句话,动态的创建类
-
元类查找的顺序:
- 首先检查Foo中是否具有属性metaclass?
- 如果找到,就使用metaclass定义的元类在内存中创建一个类对象。
- 如果在类定义中没有找到这个属性,就在模块级别中进行查找。
- 如果还是没有找到,就会使用父类Bar中的元类来创建类。
-
metaclass里面方法的顺序:
- __new__: 用于动态创建每一个类,这样在创建的过程中,修改类的属性方法等,只有在类的生成是调用一次
- __init__: 这个方法在new完成后,用来给属性和方法初始化,类生成时候调用一次
- __call__: 每次生成类的对象时候,调用一次,然后调用类自己的init函数,所以可以在__call__里面做一下生成对象时候统计
代码示例:
# -*- coding:utf8 -*-
class Basic(type):
count = 0
def __new__(cls, name, bases, newattrs):
print "new: %r %r %r %r" % (cls, name, bases, newattrs)
return super(Basic, cls).__new__(cls, name, bases, newattrs)
def __call__(self, *args):
print "call: %r %r" % (self, args)
self.count += 1
return super(Basic, self).__call__(*args)
def __init__(cls, name, bases, newattrs):
print "init: %r %r %r %r" % (cls, name, bases, newattrs)
super(Basic, cls).__init__(name, bases, dict)
class Foo:
__metaclass__ = Basic
def __init__(self, *args, **kw):
print "init: %r %r %r" % (self, args, kw)
a = Foo('a')
print a.count
b = Foo('b')
print a.count
c = Foo('c')
print a.count
结果:
new: <class '__main__.Basic'> 'Foo' () {'__module__': '__main__', '__metaclass__': <class '__main__.Basic'>, '__init__': <function __init__ at 0x7f95aa8927d0>}
init: <class '__main__.Foo'> 'Foo' () {'__module__': '__main__', '__metaclass__': <class '__main__.Basic'>, '__init__': <function __init__ at 0x7f95aa8927d0>}
call: <class '__main__.Foo'> ('a',)
init: <__main__.Foo object at 0x7f95aa8991d0> ('a',) {}
1
call: <class '__main__.Foo'> ('b',)
init: <__main__.Foo object at 0x7f95aa899290> ('b',) {}
2
call: <class '__main__.Foo'> ('c',)
init: <__main__.Foo object at 0x7f95aa8992d0> ('c',) {}
3