shhgs <[email protected]>

  • Mar 7, 2007 2:07 PM

    class和type的区别 
    
    打一个比方。在学OO的时候,老师会说,class就是一个模子,往里面浇铁水之后,就有了对象了。
    
    OK,这里就有问题了。你写的代码,相当于工程师设计的图纸,而图纸是没有办法往里面浇铁水的,你得把图纸变成模子,才能往里面浇东西。
    
    于是,你写的代码,定义了一个算法。这个算法别称为class。
    
    你的class,交给type,type根据你的class,加工出一个模子,然后你就可以往里面浇铁水生成instance了。这个type就类似于工厂的生产能力,工艺流程,或者。。。在编程的时候,这个type是语言的一种机制,能把你用代码定义的算法,也就是class,解释成能生成object,或者说instance(其实这个术语更好)的一种object(在解释meta
    programming的时候,一定要区分instance和object。这也是为什么,我曾经宣称,OOP应该是面向客体的编程。)。
    
    OK,Py的type有很多,你import
    types然后dir(types)可以看到很多。具体而言,每种type都是一种组织内存的方式。比如说,Python内部表示类的对象,同表示instance的对象,其内部构造是不同的。那么这个内部构造是怎么定义的呢?就是这个type定义的。比如,每个instance都应该有一个dict,有表示其parent的tuple,此外还有初始化的时候,生成的parent类的对象(这部分具体应该问Robert
    Chen,我菜了)。而class里面可能就没有这么些东西。反正这就是type定义的。
    
    接下来的东西,你可以去看Py in a
    nutshell了。Alex把福尔摩斯推理的最重要的一页给撕了。我也是琢磨了半天,最后在看Programming
    Ruby的时候搞懂的。现在给你补齐,应该能看懂了。
    
  • Mar 7, 2007 10:13 PM

type和class绝对不同。

Python里面的所有对象,都是由type制造的。相应的type制造一个blanket的对象,然后解释器再根据你的源代码,往这个blanket的对象里面塞东西。

空白的class object是由types.ClassType或者types.TypeType创建的。而你写的代码,会先在一个dict里面运行,然后塞进这个blanket的class object里面。

>>> code = """
def func(self) :
       print "blah, blah, blah"
"""
>>> d = dict()
>>> exec(code, d)

>>> import types
>>> old_class = types.ClassType("OldClass", (), d)
>>> o = old_class()
>>> o.func()
blah, blah, blah

>>> new_class = types.TypeType("NewClass", (), d)
>>> o = new_class()
>>> o.func()
blah, blah, blah
  * instance一一样。先由types.InstanceType创建一个blanket的instance。在new
  * class里面,这一步可以通过__new__控制。而所谓的meta
  * programming正是在这个__new__里面搞花样。blanket的instance创建完毕,再把dict绑定过去。这样,一个instance就有了。
  • Mar 7, 2007 11:56 PM

    OK, class和type有不同的理解。我这里先解释一下我的定义。 
    
    class是指你源代码里面
    
    ----------------------------------
    class MyClass :
       def blah() :
           ........
    ----------------------------------
    
    用这种语法定义的类。
    
    而type是指
    
    -------------------------------------
    >>> import types
    >>> dir(types)
    ..................
    -------------------------------------
    
    你看到的这些东西。
    
    这两者截然不同。他们之间的关系,我用如下一个比喻解释。
    
    你是一个工程师。你现在设计一个很复杂的系统,里面用到了OOP的解决方案。你定义了各种对象,然后让他们相互传消息解决问题。
    
    但是你只是在图纸上设计了这些对象,定义了它们的接口。你不能直接往图纸里浇铁水,你得有模子。
    
    OK,你拿着图纸,找到一家叫Py的工厂。这个工厂拿到图纸之后说,没问题,我给你造。于是它根据图纸造一个模子(class
    object)。制造模子的时候,工厂用的是自己的生产工具(types.ClassType,或者tpyes.TypeType,看你用new
    class还是old class)。
    
    但是光有模子没用,你要的是解决问题,你得让工厂再按照你的图纸生产处一些能收发消息的对象。
    
    Py工厂说,没问题,有了模子还愁instance吗。只是我们的模子只能我们自己用。于是它再备料。这次出场的是InstanceType。你可以把InstanceType想成一种类似塑料一样的东西。原本你以为工厂是会往模子里浇铁水的,结果它的模子只能浇这种塑料。Anyway,东西做出来了,也能收发消息了,你就能让程序跑起来解决问题了。
    
  • Mar 8, 2007 9:13 AM

    type和class是两个空间的东西。
    
    class是用户空间的概念。当然这个用户是Py的程序员。
    
    type是在实现Py解释器的过程当中,其OO设计的一个层次。
    
    这两个空间在99.99%的情况下是没有交集的,只是在meta programming的时候碰了头。
    
    你举的这个例子确实有些两难。这个meta
    class对程序员来说,是一个class,对Py解释器来说,又可以当作type来用。Anyway,能写出这种代码的人,还在乎这种区别吗?
    
    现在不是解答问题吗。要解答问题,就得给一个内恰的,明确的,清晰的解释。而这个解释,很大程度上又取决于如何定义type和class。我觉得你的分类标准并不适合初学者。你所说的,type和class没有区别,实际上在写Py代码的时候并不实用。用户使用class就能自定义class,但是他们为什么不能自定义type?如果两者完全没有差别,为什么又要有type,而且还无处不在。这些问题都很实际,而且也不是你所说的"两者没有区别"所能解释的。相反我的划分方式,把class归到用户空间,把type归到Py解释器的实现,我觉得还是比较清楚的,也是能自圆其说的。
    
    我无意在这个地方和你辩论。读者要听谁的,请自己选择。
    
  • Mar 8, 2007 9:35 AM

    new class object的type是object。 
    
    反正不管是new还是old,type都是Py解释器内部的东西,class都是用户空间的东西。而知道type之间的相互关系,只是在meta
    programming的时候有用。
    
  • Mar 8, 2007 10:31 AM

    Py的type是不能自定义的。你只能继承已有的types里面的type。要想自定义一个type,比如像Perl,
    Ruby那样,用1..3表示一个Range,你就得用C。从这个角度来讲,不管new还是old的class,都不是type。
    
    你前面写的,class int(object)是笔误。我还以为可以这样继承int了。MyInt虽然继承了int,但是看不出有什么用。其实Python的meta
    programming也就type有用。
    
    new class object的type其实还是object。这个肯定是不错的。object是所有object的base
    type。其实new class object在初始化的时候,采用的方式同old class的大同小异。都是调用
    一个方法,生成一个blanket的instance,然后往里面塞东西。所不同的是,old class用的是InstanceType,而new
    class用的是class object的__new__方法。
    
    Python 2.2之前的OO实现还是很清楚的,现在这个实现,思路很混乱。主要是为了要过渡到Py
    3000。这个type和object之间的鸡和蛋的关系实在同Py的优雅不沾边。Py 3000取消了type之后,meta
    programming应该更容易了。