__new__方法限于新式类,是静态方法,且不是类方法,用来创建对象。
__init__方法是普通方法,用来初始化对象。
流程是(不完全正确): obj = classObj.__new__(classObj); type(obj).__init__(obj); (属性方法的访问,请参考前面的文章)
返回的obj可以和classObj没有任何关系,而且__new__至少会返回一个None对象,如果返回的type(obj)!=classObj,那么不会调用__init__方法。
class Singleton(object): '单例的实现' def __new__(cls, *args, **kwargs): # 静态方法,不要被cls给迷惑了 if not hasattr(cls, '_instance'): # 最终访问的还是object中的__new__方法, cls._instance = super(Singleton, cls).__new__(cls) return cls._instance def __init__(self, *args, **kwargs): PRint self,args,kwargs @staticmethod def bar(self, *args, **kwargs): print 'I am bar.',self @classmethod def foo(self, *args, **kwargs): print 'I am foo.',selfobj1 = Singleton()obj2 = Singleton()Singleton._instance = 'I am not a foo.'obj3 = Singleton()print id(obj1),obj1,obj1.foo()print id(obj2),obj2,obj2.foo()print id(obj3),obj3obj1.__new__() # 报错obj1.bar() # 报错obj1.foo()Singleton.__new__() # 报错Singleton.bar() # 报错Singleton.foo()2,__new__、__init__、__call__和__metaclass__:
首先清楚用于定制类的特殊方法,都是由类型进行调用,而不是实例,
如:a()等于type(a).__call__(a),而不是a.__call__()!!!
如:a+b等于type(a).__add__(a,b),而不是a.__add__(b)!!!
如:a = A()中对a的初始化,等于type(a).__init__(a),而不是a.__init__()!!!
看看__new__、__init__、__call__和__metaclass__之间的运作关系和机制,详解类和实例的创建过程:
class AA(object): def __new__(self, *args, **kwargs):# 静态方法,self需要自己传递 print 'new in AA',args,kwargs return super(AA, self).__new__(self, *args, **kwargs) def __init__(self, *args, **kwargs):# 普通方法,self会自动绑定 print 'init in AA',args,kwargs return super(AA, self).__init__(*args, **kwargs) def __call__(self, *args,**kwargs): # 普通方法,self会自动绑定 print 'call in AA',args,kwargs# return super(AA, self).__call__(*args,**kwargs)class BB(type): def __new__(self, name, bases, attrs):# 静态方法,self需要自己传递 print 'new in BB',name, bases, attrs return super(BB, self).__new__(self, name, bases, attrs) def __init__(self, *args, **kwargs):# 普通方法,self会自动绑定 print 'init in BB',args,kwargs return super(BB, self).__init__(*args, **kwargs) def __call__(self, *args,**kwargs): # 普通方法,self会自动绑定 print 'call in BB',args,kwargs return super(BB, self).__call__(*args,**kwargs)class CC(AA): '一旦执行定义类CC的代码,就会调用BB元类中的__new__方法,其中真正生成类CC的是super(BB, self)中的__new__,也就是type中的__new__方法,检查返回对象是否是BB的实例,若是则调用type(CC).__init__(CC),也就是BB元类中的__init__方法,来初始化CC对象' __metaclass__ = BB def __new__(self, *args, **kwargs):# 静态方法,self需要自己传递 print 'new in CC',args,kwargs return super(CC, self).__new__(self, *args, **kwargs) def __init__(self, *args, **kwargs):# 普通方法,self会自动绑定 print 'init in CC',args,kwargs return super(CC, self).__init__(*args, **kwargs) def __call__(self, *args,**kwargs): # 普通方法,self会自动绑定 print 'call in CC',args,kwargs return super(CC, self).__call__(*args,**kwargs)c = CC()c()c = CC():BB中的__call__方法定义了对CC的调用行为,如同type(CC).__call__(CC),而不是CC.__call__(),然后BB中的__call__,等价于type.__call__,最终调用CC里面的__new__方法,CC的__new__方法调用AA的__new__方法,AA的__new__方法调用object中(不是type)的__new__方法生成并返回实例对象c。检查返回的对象c是否是CC的实例,若是则调用type(c).__init__(c),也就是CC元类中的__init__方法,来初始化c对象。c():CC中的__call__方法定义了对c的调用行为,如同type(c).__call__(c),而不是c.__call__()
__metaclass__的查找和继承:先在CC中找__metaclass__属性,再在基类中找,再在其定义所在模块中找,最后使用默认的type来创建这个类对象,即类对象的默认__class__是type。
3,type中__new__来的动态创建类:
class Myclass(object): def __new__(cls, *args,**kwargs): tmp = super(type(cls),cls).__new__(cls, *args,**kwargs) tmp.name = 'my name is lucy.' return tmp'---------or----------'def __new2__(cls, *args,**kwargs): tmp = super(type(cls),cls).__new__(cls, *args,**kwargs) tmp.name = 'my name is lucy2.' return tmpMyclass2 = type('Myclass2',(object,),{'__new__':__new2__})'---------or----------'Myclass3 = type('Myclass3',(object,),{'name':'my name is lucy3.'})@staticmethoddef __new3__(cls, *args,**kwargs): return super(type(cls),cls).__new__(cls, *args,**kwargs)Myclass3.__new__ = __new3__a,b,c = Myclass(),Myclass2(),Myclass3()print type(a),': ',a.name,' ',a.__dict__ # name在a的__dict__中print type(b),': ',b.name,' ',b.__dict__ # name在b的__dict__中print type(c),': ',c.name,' ',c.__dict__ # name在Myclass3的__dict__中4,粘贴两个别人的例子,一个是关于hook,一个是关于orm:
def make_hook(f): """Decorator to turn 'foo' method into '__foo__' method """ f.is_hook = 1 return fclass MyType(type): def __new__(cls, name, bases, attrs): if name.startswith('None'): return None # Go over attributes and see if they should be renamed. newattrs = {} for attrname, attrvalue in attrs.iteritems(): if getattr(attrvalue, 'is_hook', 0): newattrs['__%s__' % attrname] = attrvalue else: newattrs[attrname] = attrvalue return super(MyType, cls).__new__(cls, name, bases, newattrs) def __init__(self, name, bases, attrs): super(MyType, self).__init__(name, bases, attrs) # classregistry.register(self, self.interfaces) print "Would register class %s now." % self def __add__(self, other): # 定义类对象相加的行为,就是返回一个继承这两个类对象的类对象 class AutoClass(self, other): pass return AutoClass # Alternatively, to autogenerate the classname as well as the class: # return type(self.__name__ + other.__name__, (self, other), {}) def unregister(self): # classregistry.unregister(self) print "Would unregister class %s now." % selfclass MyObject(object): __metaclass__ = MyTypeclass NoneSample(MyObject): pass# Will print "NoneType None"print type(NoneSample), repr(NoneSample)class Example(MyObject): def __init__(self, value): self.value = value @make_hook def add(self, other): # 创建一个新的Example对象, return self.__class__(self.value + other.value)# Will unregister the classExample.unregister()inst = Example(10)new_inst = inst + instprint new_inst.value ,': inst的加法调用的是inst.__class__的__add__函数,也就是Example.__add__'class Sibling(MyObject): passExampleSibling = Example + Sibling# Example的加法调用的是Example.__class__的__add__函数,也就是MyType.__add__'# ExampleSibling is now a subclass of both Example and Sibling (with no# content of its own) although it will believe it's called 'AutoClass'print ExampleSiblingprint ExampleSibling.__mro__' ORM 对象关系映射 '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 StringField(Field): def __init__(self, name): super(StringField, self).__init__(name, 'varchar(100)')class IntegerField(Field): def __init__(self, name): super(IntegerField, self).__init__(name, 'bigint')class ModelMetaclass(type): def __new__(cls, name, bases, attrs): if name=='Model': return type.__new__(cls, name, bases, attrs) print('Found model: %s' % name) mappings = dict() for k, v in attrs.iteritems(): if isinstance(v, Field): print('Found mapping: %s ==> %s' % (k, v)) mappings[k] = v for k in mappings.iterkeys(): attrs.pop(k) attrs['__mappings__'] = mappings # 保存属性和列的映射关系 attrs['__table__'] = name # 假设表名和类名一致 return type.__new__(cls, name, bases, attrs)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__.iteritems(): 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))# testing code:class User(Model): id = IntegerField('uid') name = StringField('username') email = StringField('email') passWord = StringField('password')u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')u.save()参考:
http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-pythonhttp://stackoverflow.com/questions/865911/is-everything-an-object-in-python-like-rubyhttp://eli.thegreenplace.net/2012/03/30/python-objects-types-classes-and-instances-a-glossary/https://docs.python.org/2/reference/datamodel.htmlhttp://python.jobbole.com/82110/(如果有什么说的不对的地方,欢迎大家多多批评指正。)
新闻热点
疑难解答