[http://spaces.msn.com/members/shukebeta/Blog/cns!1psZEmYfE1uAECP30_KFiC1Q!128.entry 魏忠的Space发布]

::-- ZoomQuiet [DateTime(2006-01-09T06:12:38Z)] TableOfContents

1. python中的 new-tyle 类及其实例

(原文是python in a nutshell5.2节)

1.1. 5.2新版类及其实例

1.1.1. 5.2.1 The Built-in object Type

1.1.2. 5.2.2 Class-Level Methods

类级别方法

1.1.2.1. 5.2.2.1 Static methods

5.2.2.1静态方法

   1     class AClass(object):
   2 staticmethod #静态方法修饰符,表示下面的方法是一个静态方法
   3         def astatic(  ): print 'a static method'
   4     anInstance = AClass(  )
   5     AClass.astatic(  )                    # prints: a static method
   6     anInstance.astatic(  )                # prints: a static method

1.1.2.2. 5.2.2.2 Class methods

   1     class ABase(object):
   2         @classmethod #类方法修饰符
   3         def aclassmet(cls): print 'a class method for', cls.__name__
   4     class ADeriv(ABase): pass
   5     bInstance = ABase(  )
   6     dInstance = ADeriv(  )
   7     ABase.aclassmet(  )               # prints: a class method for ABase
   8     bInstance.aclassmet(  )           # prints: a class method for ABase
   9     ADeriv.aclassmet(  )              # prints: a class method for ADeriv
  10     dInstance.aclassmet(  )           # prints: a class method for ADeriv

1.1.3. 5.2.3 New-Style Classes

5.2.3 新版的类

1.1.3.1. 5.2.3.1 __init__

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

1.1.3.2. 5.2.3.2 __new__

python调用C.__init__(x,*args,**kwds)来初始化实例. 也就是说,对新类C来讲,语句 x=C(23)等同于:

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

当你覆盖__new__方法时,你不必使用函数修饰符 @staticmethod, python解释器根据上下文会认出__new__()方法. 如果你需要重绑定 C.__new__方法,在类外,你只需要使用 C.__new__=staticmethod(你想使用的新方法) 即可.(很少有这样的需求)

   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]    #返回这个实例

那么子类必须确保它的__init__方法是多次对同一实例调用是安全的.

1.1.4. 5.2.4 New-Style Instances

5.2.4新版类实例

1.1.4.1. 5.2.4.1 Properties

{{{ print x.prop

}}}

   1     class Rectangle(object):
   2         def __init__(self, width, heigth):
   3             self.width = width
   4             self.heigth = heigth
   5         def getArea(self):
   6             return self.width * self.heigth
   7         area = property(getArea, doc='area of the rectangle')

    attrib = property(fget=None, fset=None, fdel=None, doc=None)

   1     class Rectangle:
   2         def __init__(self, width, heigth):
   3             self.width = width
   4             self.heigth = heigth
   5         def getArea(self):
   6             return self.width * self.heigth
   7         def __getattr__(self, name):
   8             if name=  ='area': return self.getArea(  )
   9             raise AttributeError, name
  10         def __setattr__(self, name, value):
  11             if name=  ='area':
  12                 raise AttributeError, "can't bind attribute"
  13             self.__dict__[name] = value

1.1.4.2. 5.2.4.2 __slots__

' 5.2.4.2 slots属性

   1     class OptimizedRectangle(Rectangle):
   2         __slots__ = 'width', 'heigth'

1.1.4.3. 5.2.4.3 __getattribute__

   1     class listNoAppend(list):
   2         def __getattribute__(self, name):
   3             if name =  = 'append': raise AttributeError, name
   4             return list.__getattribute__(self, name)

   1     class AttributeWatcher:
   2         def __init__(self):
   3             # note the caution to avoid triggering __setattr__, and the
   4             # emulation of Python's name-mangling for a private attribute
   5             self.__dict__['_AttributeWatcher__mydict']={  }
   6         def __getattr__(self, name):
   7             # as well as tracing every call, for demonstration purposes we
   8             # also fake "having" any requested attribute, EXCEPT special
   9             # methods (__getattr__ is also invoked to ask for them: check by
  10             # trying a few operations on an AttributeWatcher instance).
  11             print "getattr", name
  12             try: return self.__mydict[name]
  13             except KeyError:
  14                 if name.startswith('__') and name.endswith('__'):
  15                     raise AttributeError, name
  16                 else: return 'fake_'+name
  17         def __setattr__(self, name, value):
  18             print "setattr", name, value
  19             self.__mydict[name] = value
  20         def __delattr__(self, name):
  21             print "delattr", name
  22             try: del self.__mydict[name]
  23             except KeyError: pass

1.1.4.4. 5.2.4.4 Per-instance methods

个体实例方法

   1     def fakeGetItem(idx): return idx
   2     class Classic: pass
   3     c = Classic(  )
   4     c.__getitem__ = fakeGetItem
   5     print c[23]                       # prints: 23
   6     class NewStyle(object): pass
   7     n = NewStyle(  )
   8     n.__getitem__ = fakeGetItem
   9     print n[23]                       # results in:
  10     # Traceback (most recent call last):
  11     #   File "<stdin>", line 1, in ?
  12     # TypeError: unindexable object

1.1.5. 5.2.5 新版对象模型中的继承

Inheritance in the New-Style Object Model

1.1.5.1. 5.2.5.1 Method resolution order

方法解析顺序:

1.1.5.2. 5.2.5.2 Cooperative superclass method calling

' 协作式调用超类方法'

   1     class A(object):
   2         def met(self):
   3             print 'A.met'
   4     class B(A):
   5         def met(self):
   6             print 'B.met'
   7             A.met(self)
   8     class C(A):
   9         def met(self):
  10             print 'C.met'
  11             A.met(self)
  12     class D(B,C):
  13         def met(self):
  14             print 'D.met'
  15             B.met(self)
  16             C.met(self)

   1     class A(object):
   2         def met(self):
   3             print 'A.met'
   4     class B(A):
   5         def met(self):
   6             print 'B.met'
   7             super(B,self).met(  )
   8     class C(A):
   9         def met(self):
  10             print 'C.met'
  11             super(C,self).met(  )
  12     class D(B,C):
  13         def met(self):
  14             print 'D.met'
  15             super(D,self).met(  )