http://www.cafepy.com/article/python_types_and_objects/python_types_and_objects.html

关于新类的更多特性和使用方法,参考
Unifying types and classes in Python 2.2
How-To Guide for Descriptors

http://hi.baidu.com/mirguest/blog/item/a6da9f64ed0bc42bab184c32.html

http://wiki.woodpecker.org.cn/moin/PyNewStyleClass

new-style classes的使用
new-style classes提供了一些新的特殊方法,让我们可以更好地控制类的行为。
下面,我们讲几个常用的:
1.__new__:
  __init__用来控制类的实例的初始化,而__new__控制初始化之前的行为---也就是实例的生成。
  因此__new__的第一个参数是类(cls),而不是self。__new__的任务是返回一个所传入参数类(cls)的实例。
  但,真正能够生成一个new-style class的实例的,只有object.__new__。因此我们定义的__new__,在需
  要生成实例时,就应该调用它。
  利用__new__的这个特性,我们可以很容易实现Singleton Pattern,让我们的类只会产生一个唯一的对象
>>> class Singleton(object):
 __instance = None
 def __new__(cls, *args, **kwd):
  if Singleton.__instance is None:
   Singleton.__instance = object.__new__(cls, *args, **kwd)
  return Singleton.__instance
>>> class MyClass(Singleton):
 pass

>>> a = MyClass()
>>> b = MyClass()
>>> a is b
True
>>> a is b is Singleton._Singleton__instance
True  
  通过继承,就可以使我自定义的类的行为符合Singleton Pattern的要求
  
2.__getattribute__:
  __getattribute__比__getattr__对使用“.语法”(如obj.a)进行对象的属性和方法的读取操作提供了更强大的控制。
  任何obj.a,都会被直接转化为obj.__getattribute__(a),包括__dict__。因此,在__getattribute__的实现,我们
  不能直接用使用__dict__(那会造成循环调用),而应该的把真正的读取操作交给object.__getattribute__。
>>> class MyClass(object):
 def __getattribute__(self, name):
  print "accessing", name
  return object.__getattribute__(self, name)

 
>>> a = MyClass()
>>> a.__dict__
accessing __dict__
{}

3.__get__,__set__,__delete__:
  重载这三个方法,可以实现对类属性的读写控制
class RevealAccess(object):
    """A data descriptor that sets and returns values
       normally and prints a message logging their access.
    """

    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print 'Retrieving', self.name
        return self.val

    def __set__(self, obj, val):
        print 'Updating' , self.name
        self.val = val

>>> class MyClass(object):
    x = RevealAccess(10, 'var "x"')
    y = 5

>>> m = MyClass()
>>> m.x
Retrieving var "x"
10
>>> m.x = 20
Updating var "x"
>>> m.x
Retrieving var "x"
20
>>> m.y
5
  可以用内建函数property,简化上述步骤
>>> class MyClass(object):
 def __init__(self):
  self.__x = 1
 def getx(self):
  print "Retrieving x"
  return self.__x
 def setx(self, value):
  print "Updating x"
  self.__x = value
 def delx(self):
  print "Deleting x"
  del self.__x
 x = property(getx, setx, delx, "I'm the x property")
 
>>> m = MyClass()
>>> m.x
Retrieving x
1
>>> m.x = 2
Updating x
>>> del m.x
Deleting x


 

1.4.1. 5.2.3.1 __init__方法

下面的 C 类(一个 new-style class)中, 从 object 继承来的原始 __init__方法, 可以认为就是一个 pass 语句, 因为它几乎什么都不做, 建议你在所有的 new-style class 中重新实现 __init__ 方法.

1 class C(object):
2     def __init__(self): pass
3     # rest of class body omitted

示例中的的类只允许无参数调用,硬要传递一个参数给它会产生异常(如用C('xyz')). 如果C没有重载__init__方法, 调用C('xyz')会象 'xyz' 根本不存在一样忽略参数继续执行. 注意: (根据我的试验,2.4版中这点发生了变化,即使没有重载__init__方法,象C('xyz')这样调用一样会引发异常)

1.4.2. 5.2.3.2 __new__方法

每一个 new-style class 都有一个名为__new__的静态方法. 当你调用 C(*args,**kwds)创建一个C实例时,python内部调用的是 C.__new__(C,*args,**kwds).

new方法的返回值 x 就是该类的实例. 在确认 x 是C的实例以后, python调用C.__init__(x,*args,**kwds)来初始化这个实例. 也就是说,对新类C来讲,语句 x=C(23)等同于:

1 x = C.__new__(C, 23)
2 if isinstance(x, C): C.__init__(x, 23)

object.__new__创建一个新的,未初始化的类实例,它接收传递过来的第一个参数(也就是类对象本身),忽略其它的参数.当你重载__new__方法时,你不必使用函数修饰符@staticmethod, python解释器根据上下文会认出__new__()方法是一个静态方法. 如果你需要重绑定 C.__new__方法,你只需要在类外面执行 C.__new__=staticmethod(你想使用的新方法)就可以了.(极少有这样的需求)

__new__方法拥有函数工厂的绝大部分弹性.根据实际需求,我们可以让__new__返回一个已有的实例或者创建一个新的实例.
下面举一个通过重载__new__方法实现独身对象的设计模式的例子:

1 class Singleton(object):
2     _singletons = {}
3     def __new__(cls, *args, **kwds):
4         if not cls._singletons.has_key(cls):            #若还没有任何实例
5             cls._singletons[cls] = object.__new__(cls)  #生成一个实例
6         return cls._singletons[cls]                             #返回这个实例

Singleton的所有子类(当然是没有重载__new__方法的子类)都只可能有一个实例. 如果该类的子类定义了一个__init__方法,那么它必须保证它的__init__方法能够安全的对同一实例进行多次调用.