`
shuiyutian
  • 浏览: 10619 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Python 类型和对象

阅读更多

Python 类型和对象

原址:http://wiki.woodpecker.org.cn/moin/PyTypesAndObjects#A.2Bj9lOm2cJTsBOSGEPTkk-

 

Shalabh Chaturvedi

Copyright © 2005-2009 Shalabh Chaturvedi
All Rights Reserved.

(小明同学译 wjm251 AT gmail.com

 

 

关于本书

解释新式的Python对象(new-style):

  • <type 'type'> and <type 'object'>是什么东西

  • 用户定义的类及实例是如何相互关联的,和内置类型有啥关系how user defined classes and instances are related to each other and to built-in types
  • metaclass是什么

新式类型New-style包含在Python2.2及以上,包括3.x。这些版本之间会有细微差异,不过这里涉及到的概念都是无差别的。本书讲的内容通常被称作Python类型系统或Python对象模型Python type system, or the object model.

This revision: 1.24

 

图索引

 

示例索引

 

需要提前了解的

应该注意的一些:

  • 本书涵盖新式 new-style 对象 (在Python 2.2中引入). 本书例子适用于Python 2.5 及以上,包括 Python 3.x.
  • 本书不是为完全初学者写的. 而是针对已经对Python有所了解 (稍稍了解即可) 并希望对它了解更多的人.
  • 本书为掌握新式(new-style)属性访问及descriptors, properties等机制提供了所需的底层的要点。如果只对属性方法感兴趣,请移步至 Python Attributes and Methods, 阅读之后也就理解了本书的 Summary.

python之旅快乐?Happy pythoneering!

 

1. 基本概念

 

深入Object

怎样准确的表达python中object的含义呢? 系统中每个对象是一条规则 - 是一个实体的体现. 可以通过如下特征来确定一个对象:

  • 有标识名字 (i.e. 给定两个名字我们可以判断他们是否指向同一个对象).
  • 有值 - 对象可能包含一堆属性 (i.e. 比如可以通过 objectname.attributename获得其他对象).
  • 有类型 type - 每个对象有一个确定的类型. 例如对象2的类型是 int ,对象 "joe" 的类型是 string.
  • 有一个或多个 bases. 并非所有对象都有bases,一些特别的对象会有. A base 类似于面向对象术语中的超类或基类。
  • 如果你更在意具体的对象在内存中怎样存放,而不是更想知道一些抽象的概念,
  • 这对你理解每个对象在内存中都有个具体的位置(可以用id函数来获得)很有帮助。(---注:这句瞎解得,没真正理解,附原文)
  • If you are more of the 'I like to know how the bits are laid out' type as opposed to the 'I like the meta abstract ideas' type, it might be useful for you to know that each object also has a specific location in main memory that you can find by calling the id() function.

==== type 和 bases === (如果存在的话) 很重要,因为它们定义了对象和其他对象之间的特定关系. 请记住对象的types 和 bases只是另外一些对象.很快就会看到这一点.

你可能会想到对象有名字但名字不是对象的一部分. 对象名在对象之外的命名空间中存在(比如函数的本地变量) 或者作为另一个对象的属性.

即使对2这样一个简单对象所包含的东西也比我们眼睛看到的要多.

Example1.1. 查看integer对象

>>> two = 2   1
>>> type(two)
<type 'int'> 2
>>> type(type(two))
<type 'type'> 3
>>> type(two).__bases__
(<type 'object'>,) 4
>>> dir(two) 5
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', 
 '__delattr__', '__div__', '__divmod__', '__doc__', '__float__',
 '__floordiv__', '__format__', '__getattribute__', '__getnewargs__',
 '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__',
 '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__',
 '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__',
 '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__',
 '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__',
 '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__',
 '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__',
 '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__',
 'conjugate', 'denominator', 'imag', 'numerator', 'real']
  • 1 在当前命名空间中我们把这个integer命名为two.
  • 2 <type 'int'>. 这是另一个对象, 现在来解剖一下. 注意这个对象也被称为 int 而 <type 'int'> 只是它打印出来的样子.

  • 3 <type 'int'> 的type是另外一个叫做 <type 'type'>的对象象.

  • 4 <type 'int'> 的bases属性是一个tuple,这个tuple包含一个叫 <type 'object'>的对象. 我想你没考虑过检查 bases这个属性 ;).

  • 5 列出这个原始integer对象的所有属性来 - 好多东西啊.

耐心点先来看我们的第一条规则

规则1
  • 任何东西都是一个object

int 是 object. 这不是说例如2和77这样的数字是object (他们确实是), 而是说确实有另外一个对象叫做 int ,他处于内存中的实际的整数之外的内存中. 实际上所有的整数对象的class属性都指向 int,他们共同的心声是"知我者int也". 在一个object上调用type()方法返回的也正好是这个对象的class属性的值.

我们定义的所有classes都是对象, 当然这些classes的实例也是对象.甚至我们定义的方法和函数也是对象. 并且像我们看到的,这些对象都有些不同.

 

空白状态

现在我们来从头构建python的对象系统. 我们从一个空白状态开始.

Figure 1.1. 空白状态

http://www.cafepy.com/article/python_types_and_objects/images/clean_slate.png

你可能在想为啥有两天灰色的竖线. 后面慢慢来揭晓. 竖线是来区别不同的区域的. 这个空白图中, 我们来逐渐加上各种对象,画上他们之间的关系,慢慢画满.

这个有助于帮助我们暂且搁置先入为主的各种有关面向对象的类和对象的观念,以对象的方式(我们这里的对象)来理解一切。

  • At this point, it helps if any preconceived object oriented notions of classes and objects are set aside, and everything is perceived in terms of objects (our objects) and relationships.

 

对象之间的关系

我们使用两种关系就可以连接我们所引入的这许多不同的对象. 这两种关系是子类-父类关系 (也可叫做特别化或继承, 如"人是个动物", 等等.) 和类-实例关系 (也叫实例化, 比如"Joe是个人", 等等.)。

如果你对这些概念已经熟悉了,可以继续往下看了,否则的话你可能需要先去看看这一部分“面向对象”.

 

2.引入对象

 

第一批对象

我们来查看<type 'object'> 和 <type 'type'>这两个对象.

Example 2.1. Examining <type 'object'> and <type 'type'>

>>> object 1
<type 'object'>
>>> type 2
<type 'type'> 
>>> type(object) 3
<type 'type'>
>>> object.__class__ 4
<type 'type'>
>>> object.__bases__ 5
()
>>> type.__class__ 6
<type 'type'>
>>> type.__bases__ 7
(<type 'object'>,)
  • 1 2 这是python中两个最基本对象. 前面我们介绍过用type()来查看一个对象object的类型type(通常就是class属性的值). 其实,它本身是个对象,并且也是个查看其他对象类型的方式

  • 3 4 5 查看 <type 'object'>: <type 'object'>的类型type是<type 'type'>. 我们也验证了它的class属性确实和调用type()是一样的.

  • 6 7 查看 <type 'type'>: 有趣的是<type 'type'>的type是它自己! 它的bases属性包含了 <type 'object'>.

下面我们来画一下所看到的.

Figure 2.1. 鸡和蛋的关系

http://www.cafepy.com/article/python_types_and_objects/images/chicken_and_egg.png

图中两个对象是python最基本对象. 也可以一次介绍一个,但这里有个鸡和蛋一样的矛盾 - 先介绍哪个好? 这两个对象是互相依赖的 - 每一个本身都不能单独存在,都要借助对方来描述自己.

还是继续我们的python实验吧:

Example 2.2. 关于 <type 'object'> 和 <type 'type'>的更多内容

>>> isinstance(object, object) 1
True
>>> isinstance(type, object) 2
True
  • 1 看看发生了什么? 这是 Dashed Arrow Up Rule 的一个应用. 由于<type 'type'> 是 <type 'object'>的子类, 则<type 'type'> 的实例也是<type 'object'>的实例.

  • 2 将 Dashed Arrow Up Rule 和 Dashed Arrow Down Rule 一起使用, 直接把箭头反过来也是正确的. (译注:事实上type,objcet的两两组合都是互为instance的)

如果对上面的证明不太理解, 没关系 - 反正也没什么用.

再看一个新概念 - 类对象type objects. 我们介绍过的对象都是类对象. 所说的类对象是什么呢? 类对象有如下共同特点:

  • 它们用来代表程序中抽象的数据类型. 例如, 用户定义的一个叫User的对象可能用来表示系统中所有的用户,另一个叫int的对象可能代表所有的整数.
  • 它们可以被子类化. 你可以新建一个与已存在的类对象有点类似的新对象.已存在的类对象将成为这个新对象的基类.
  • 它们可以被实例化. 意味着你可以新建一个已存在对象的实例. 这个新对象的class属性就是已存在对象.

  • 任何类对象的类型是 <type 'type'>.

  • 它们有时被称为types有时称为classes.

是的. Types和classes在Python中确实是同一个东西 (免责声明: 对老式类和早于2.2版本的Python不适用. 那是 types和classes有些不同但那时很久前的事了,现在已这些不同点已经一致了。因此让过去的事就过去吧,不好吗?). 不要吃惊,使用type()函数和class属性得到的是一样的.

class 这个术语传统是指被class这个关键字创建的class. 内置类型 (比如int和string)通常不和classes联系起来, 这更多是约定俗成的,实际上types和classes是同一个东西.我觉得这点很重要,可以提出一个规则:

Class is Type is Class
  • type和class这两个术语在所有Python >= 2.3的版本中是一样的.

类对象Types 和 (嗯,,让我想个更好的词) 非类对象non-types (呵呵!) 都是对象 但只有types可以子类化. Non-types代表的是具体的值所以子类化并没有意义. 非类对象的两个例子是整数 2 以及字符串 "hello". 想想,2的子类是什么意思,没意思吧?

还对判断类对象和非类对象感觉混淆吗?有一个简单的规则:

类和非类对象判断规则Type Or Non-type Test Rule
  • 如果一个对象是<type 'type'>的实例, 那它就是类对象. 否则是非类对象.

回头看,可以证明这个规则对我们所碰到的所有对象都是成立的, 包括 <type 'type'>,它是自己的实例.

总结一下:

  1. <type 'object'> 是 <type 'type'>的一个实例.

  2. <type 'object'> 不是任何类的子类.

  3. <type 'type'> 是自己的实例.

  4. <type 'type'> 是 <type 'object'>的子类.

  5. python中只有两种对象: 为了清楚叫它们types 和 non-types. Non-types 也可以叫实例, 但实例这个术语也可以指向一个类对象, 因为一个type一定是另一个的type的实例. Types 也被叫做 classes, 并且我经常把他们叫做classes.
  • Note that we are drawing arrows on our slate for only the direct relationships, not the implied ones (i.e. only if one object is another's class, or in the other's bases). This make economic use of the slate and our mental capacity.

 

更多内置类型

Python中不止这两个对象,这两个基本对象有一堆的兄弟

Figure 2.2. 一些内置类型

http://www.cafepy.com/article/python_types_and_objects/images/builtin_types.png

上面展示了一些内置对象,下面解释一下.

Example 2.3. 查看一些内置类型

>>> list 1
<type 'list'>
>>> list.__class__  2
<type 'type'>
>>> list.__bases__  3
(<type 'object'>,)
>>> tuple.__class__, tuple.__bases__ 4
(<type 'type'>, (<type 'object'>,))
>>> dict.__class__, dict.__bases__ 5
(<type 'type'>, (<type 'object'>,))
>>>
>>> mylist = [1,2,3] 6
>>> mylist.__class__ 7
<type 'list'>
  • 1 内置的<type 'list'> 对象.

  • 2 <type 'list'>的类型是<type 'type'>.

  • 3 它有一个基类 (即 superclass), <type 'object'>.

  • 4 5 类似的还有 <type 'tuple'> 和 <type 'dict'>.

  • 6 创建<type 'list'>的实例的方法.

  • 7 一个list对象的type是 <type 'list>. 不要惊讶.

当创建一个tuple或dictionary对象时, 他们是各自对应类型的实例.

怎样创建一个mylist的实例呢? 不能. 因为 mylist对象不是一个type.

 

子类化产生新对象

内置对象是内置在python中的. 当我们启动python的时候就存在,通常程序结束的时候他们还存在.那我们怎样创建新对象呢?

新对象不会无中生有的出现. 它们必须通过现有的对象来创建.

Example 2.4. 通过子类化构建对象

# Python 2.x:
class C(object): 1
    pass

# Python 3.x, 确定的object基类已经不需要指定了, 默认创建的都是class的基类:
class C: 2
    pass

class D(object):
    pass

class E(C, D): 3
    pass

class MyList(list): 4
    pass 
  • 1 关键字class告诉python通过子类化已有类型来创建一个新类型.
  • 2 不要在Python 2.x中这样写,这样得到的是一个旧式的类old-style class, 这里讲的这些在旧式类里都是不适用的.
  • 3 可以有多个基类.
  • 4 多数内置类型都可以被子类化(但不是全部).

从上面的例子可知, C.bases 包含 <type 'object'>, 而 MyList.bases 包含 <type 'list'>.

 

实例化产生新对象

子类化只是产生对象的一种方式,还有另外一种.

Example 2.5. 通过实例化构建对象

obj = object() 1

cobj = C() 2

mylist = [1,2,3] 3
  • 1 2 调用操作符 (()) 通过实例化已有对象来创建新对象. 这里的已有对象必须是一个类对象type. 对于不同的类对象,这个调用操作符可能接受参数.
  • 2 对某些内置类型python有特殊的语法来创建新对象. 方括号创建 <type 'list'>的实例; 整形数字直接量创建一个 <type 'int'>对象.

有了上面练习的这些, 我们的对象图就看起来更完美了.

Figure 2.3. 用户定义对象

http://www.cafepy.com/article/python_types_and_objects/images/user_built_objects.png

注意,仅仅通过子类化 <type 'object'>, 类型C 自动成为 <type 'type'>的实例. 可以通过查看C.class来确认这一点. 下节再对此做解释.

 

其实都是实例化的

对于这一点你可能会冒出下面这些问题,也可能没有,不过我还是打算解答一下:

  • Q: python是如何真正创建一个对象的?
  • A: python内部,当创建对象时, 肯定会使用一个type来创建这个type对象的一个实例. 具体的情况是调用这个类对象的new() 和 init() 方法(对这些内容的讨论已操作本书范围). 某种意义上,可以将类对象(type)看做是能够生产新对象的工厂. 这些生产出来的对象的类型(type)将是创建他们的类对象(type). 这就是为什么每个对象都有个类型type的原因.

  • Q: 当实例化的时候我们指定了类型,但子类化的时候,python如果确定使用什么类型呢?
  • A: 这要看你子类化时指定的基类,将基类的类型type作为新对象(新类)的type,在 Example 2.4, “通过子类化构建对象”这个例子中 , <type 'type'> (指定的基类<type 'object'>的type) 被用做正在创建的C的类型.

想一下就会知道多数iqngk下, <type 'object'>的任何子类 (以及子类的子类,等等)都将被赋予<type 'type'>这个类型.

高级材料展望
  • 一些更高级的讨论, 请仔细阅读, 或者跳到下一节.
  • Advanced discussion ahead, tread with caution, or jump straight to the next section.
  • Q: 我可以指定一个type来替代系统默认的机制吗?
  • A: 是的,一个可选方案就是用 metaclass 这个类的属性,如下示例:

Example 2.6. 使用class关键字定义类时指定一个type对象

切换行号显示
   1 class MyCWithSpecialType(object):
   2     __metaclass__ = SpecialType
  • 这样Python在创建MyCWithSpecialType时,是实例化 SpecialType的, 而不是<type 'type'>.

  • Q: 太棒了,可以把任意type对象作为metaclass?

  • A: 不是的,指定的元类metaclass必须是所用的基类的type的子类No. It must be a subclass of the type of the base object. 比如上面的例子中:

    • MyCWithSpecialType 的基类是<type 'object'>.

    • <type 'object'>的 type是<type 'type'>.

    • 所以如果用SpecialType做 metaclass的话, SpecialType必须是 <type 'type'>的子类才行.

    • 使用像SpecialType这样的东西需要特别小心,这些已经超出本书的范围.

    • (译注,

      似乎不是很确切,下面这个例子能运行。也可能是我正好选了个特例吧。
      
      class Atype(type):
          pass
      class AClass(object):
          __metaclass__ = Atype
      class BClass(AClass):
          __metaclass__ = type
      • 不过这个特性确实日常用的不多,不用深究了,作者也说超出本书范围,若有需求再 google吧。)
    • 实测某些情况下,有个元类冲突错误the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases)
  • Q: 如果有多个基类,但没指定metaclass,会使用哪个type对象呢?

  • A: 好问题. 取决于python能否计算出用哪个。若所以基类有相同的type, 就是用这个. 若他们有不同的互不相干的type, python无法算出用哪个. 此时就需要指定一个metaclass, 并且这个metaclass 必须是每个基类的type的共同子类.

  • Q: 我什么时候应该用metaclass?

  • A: 永远别用 (只要你还问这个问题的话就别用 :)

 

3. 总结一下

 

Python对象图

最后一章,我们最终得到一个有各种不同python对象的图

Figure 3.1. Python对象图

http://www.cafepy.com/article/python_types_and_objects/images/types_map.png

这一节我们也将解释图中灰色的竖线是干啥的. 根据人们对不同对象的叫法,灰色竖线将对象图分成三个区域 - 元类,类和实例.

观察这个图可以得出一些学究式的结论
  1. 虚线穿过了区域边界 (比如,从对象到元对象). 唯一的特例是<type 'type'> (也只能这样了, 否则就需要在它的左边再分一个另一个区域,另一个区域左边还得一个区域等等无穷尽。因为type的type就是自己啊).

  2. 实线不穿过边界. 又有一个例外, <type 'type'> -> <type 'object'> .

  3. 最右边的区域不能有实线. 它们是具体的对象,不能子类化.
  4. 虚线的箭头不能指向最右边区域. 具体的对象不能再实例化.
  5. 左边两个区域包含的是 types. 最右边区域包含的是non-types.
  6. 如果通过子类化<type 'type'>创建一个对象,它应该放在最左边的区域。并且它既是<type 'type'>的实例也是<type 'type'>的子类。

Also note that <type 'type'> is indeed a type of all types, and <type 'object'> a superclass of all types (except itself).

  • 也要记住,<type 'type'>确实是所有类对象的type,而<type 'object'> 是所有类对象的超类(除了它自己)。

 

概要

总结一下谈到过的内容:

  • python中有两种对象:
    1. - 可创建实例,可子类化.
    2. Non-type objects - 不能创建实例,不能子类化.
  • <type 'type'>;<type 'object'> 是python系统中的两个基本对象.

  • 每个对象都有class,并且等于该对象的type.

  • 每个type object有bases属性, 指向该对象的超类.只有<type 'object'>的bases是空的.

  • 要通过子类化构建对象,我们使用class关键字,并指定新对象的基类bases (或者可选的 type) . 这样通常创建出的是type object.
  • 要通过实例化构建对象, 需要使用在类对象上使用调用操作符即小括号 (())
  • 某些non-type objects可以用特定的python语法创建.比如[1, 2, 3] 创建一个 <type 'list'>的实例.

  • python在内部总是使用一个type object来创建一个新对象。创建出来的新对象是所用的type object的实例。通过class关键字创建的type object的类型的确定要看所指定的bases以及bases们的类型。
  • issubclass(A,B) (测试超类-子类关系) ,以下情况返回True:
    1. B在A.bases中,

    2. 对于A.bases中的每一个Z,如果 issubclass(Z,B)为True.(即若A的每个直接基类都是B的子类的话,就可以推导出 A也是B的子类)

  • isinstance(A,B) (测试类型-实例关系) ,以下情况返回True:
    1. BBA.class,

    2. issubclass(A.class,B) 为True.(即若A的类型是B的子类的话,A也就是B的实例)

  • 这样看来,我的Squasher确实也是蟒蛇. (没提过,不过现在你就知道了.)

 

好多内置类型还有个名字

Example 3.1. 更多内置 types

>>> import types  1

>>> types.ListType is list 2
True
>>> def f(): 3
...     pass
...
>>> f.__class__ is types.FunctionType 4
True
>>>
>>> class MyList(list): 5
...     pass
...
>>> class MyFunction(types.FunctionType): 6
...     pass
...
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: type 'function' is not an acceptable base type
>>> dir(types) 7
['BooleanType', 'DictProxyType', 'DictType', ..]
  • 1 types 模块中包含很多内置类型.
  • 2 一些我们熟知的类型还有另外一个名字.
  • 3 def 创建一个function对象.
  • 4 function对象的类型是 types.FunctionType

  • 5 有的内置类型可以被子类化.
  • 6 但另一些不行.
  • 7 还有更多我们没了解过的类型.

 

这些有什么意义

我们可以用我们选择的对象间的关系来创建新对象,但这对我们有什么用?

  • 对象间的关系决定了对象属性的访问是怎么起作用的,例如,当使用objectname.attributename,我们得到哪个对象?这完全取决于该对象objectname,它的类型以及它的基类(如果有的话)。

python中的属性访问机制在本系列的第二本书中讲解:Python Attributes and Methods.

 

经典类型Classic Classes

这是一份关于python中的classic classes 的备忘录. 用一个空的class关键字可以创建老式(早于python2.2)的类.

>>> class ClassicClass: 1
...     pass
...
>>> type(ClassicClass) 2
<type 'classobj'>
>>> import types
>>> types.ClassType is type(ClassicClass) 3
True
>>> types.ClassType.__class__ 4
<type 'type'>
>>> types.ClassType.__bases__ 5
(<type 'object'>,)
  • 1 不指定基类的class关键字会创建老式的类,注意要创建新式的类必须指定对象作为基类(然而python3.0中不再需要指定基类,因为3.0中默认的就是新式类)。 指定的基类中若只有老式类,那么创建出的也是老式类。若基类中老式的和新式的类都有的话创建出的就是新式的类。
  • 2 这个类型本书中还没有看到过.
  • 3 老式类的类型是一个叫types.ClassType 的对象.

  • 4 5 看起来它也像是另外一种类对象.

types.ClassType这个对象某种程度上可替代<type 'type'>. 该对象的实例(即老式类) 该对象的实例 (老式类) 也是类对象types. 新老式对象之间的属性访问规则是不同的。 types.ClassType 这个对象的存在时为了向后兼容,在将来版本的python中可能就没有了. 本书的其他部分所讲的内容不应被套用到老式类上去。去。

请在这里评论: discussion page. 感谢反馈!

到处结束了,朋友们!

 

4. 可能在其他地方学过的

 

面向对象

可以略过的章节?Can Skim Section

  • (注:这一节英文可能看着更舒服,翻译起来很费劲,感觉有些术语翻译了就变味了,尽量看原文吧)

用古怪的一节来讲解 类型-实例 和 超类-子类关系

我们引入很多不同的对象,他们之间只用两种关系就可以概括 ( 4.1. 关系)

  • “是一类” (图中实线): 即面向对象中的特殊化, 当其中一个(即子类)是另一个(超类)的特殊情况时两对象间存在这种关系.蛇“是一种”爬虫. 它具有爬虫的所有特征并且也有自己作为蛇的一些独特的特征.

 

      术语: *的子类, *的超类 and 超类-子类.
  • “是一个实例子”(图中虚线): 也叫实例化, 当其中一个 (即实例)是另一个(即类型)的具体例子时两对象间存在这种关系. 我有一个宠物蛇叫Squasher. Squasher 是蛇的一个实例.

 

      术语: *的实例, *的类型, 类型-实例 或 类-实例. 

注意在简单英语中术语,以上两种关系都可以叫'是一个' . , 蛇是一个爬虫. 不过我们用特定的术语来避免混淆.

Figure 4.1. 关系

http://www.cafepy.com/article/python_types_and_objects/images/relationships.png

    • 我们用实线表示第一种关系是因为对象之间很接近而不是一个和另一个有关系。例如,如果让列出和“蛇”最类似的词,人们很可能会说“爬虫”。但如果让列出和 'Squasher'最类似的词,人们不大可能说“蛇”
    • We use the solid line for the first relationship because these objects are closer to each other than ones related by the second. To illustrate - if one is asked to list words similar to 'snake', one is likely to come up with 'reptile'. However, when asked to list words similar to 'Squasher', one is unlikely to say 'snake'.
    • 基于这点,可以注意到下面的关系的属性
    • It is useful at this point to note the following (independent) properties of relationships:
    • 虚线向上规则Dashed Arrow Up Rule
      • 如果X是A的实例,A是B的子类,则X也是B的实例.
      虚线规则Dashed Arrow Down Rule
    • 如果B是M的实例,A是B的子类,则A也是M的实例.

换句话说, 虚线箭头一端可以向上移到实线箭头,虚线箭尾可以向下移 ( 如Figure 4.2. ""关系的传递" 中的2a和2b各自表示的).这些性质可以直接从父类-子类的关系定义得到

Figure 4.2. 关系的传递

http://www.cafepy.com/article/python_types_and_objects/images/relationships_transitivity.png

应用 虚线向上规则, 可以从下面第一条描述得到第二条:

  1. Squasher 是蛇的实例 (Squasher的类型是蛇).
  2. Squasher 是爬虫的实例 (Squasher的类型是爬虫).

之前我们说过每个对象有一个确切的类型.为啥 Squasher有两个? 注意虽然每个说法都是正确的, 其中一个更确切 (确切的说可以归纳另一个).也可以说:

  • Squasher.class 是 snake. (Python中, 对象的class指向对象的type).

  • isinstance(Squasher, snake) 和isinstance(Squasher, reptile) 都正确.

父类-子类关系也有个类似的规则.

合并实线规则
  • 若A是B的子类, B是C的子类, 则A也是C的子类

蛇是一种爬虫, 爬虫是一种动物. 所有蛇也是一种动物. 或者用Python代码表示:

  • snake.bases 是 (reptile,). (对象的bases 属性是一个包含对象超类的元组).

  • issubclass(snake, reptile) 和 issubclass(snake, animal) 都正确.

注意对象可能有不止一个基类.

 

相关资料

 

版权信息

 

This book was written in DocBook XML. The HTML version was produced using DocBook XSL stylesheets and xsltproc. The PDF version was produced using htmldoc. The diagrams were drawn using OmniGraffe [1]. The process was automated using Paver [2].

 

分享到:
评论

相关推荐

    Python类型和对象.pdf

    Python类型和对象.pdf

    Python类型和对象(20210930180213).pdf

    Python类型和对象(20210930180213).pdf

    Python的类型和对象

    讲述Python的type, class和对象之间的关系, Python 的对象模型,翻译自Python type and object

    PYTHON 面向对象编程指南

    分别介绍了__init__()方法、与Python无缝集成—基本特殊方法、属性访问和特性及修饰符、抽象基类设计的一致性、可调用对象和上下文的使用、创建容器和集合、创建数值类型、装饰器和mixin—横切方面;第2部分讲述持久...

    Python面向对象编程指南

    分别介绍了__init__()方法、与Python无缝集成—基本特殊方法、属性访问和特性及修饰符、抽象基类设计的一致性、可调用对象和上下文的使用、创建容器和集合、创建数值类型、装饰器和mixin—横切方面;第2部分讲述持久...

    大数据必修课 Python基础入门教程 Python自学资料课件-第8章 Python类和对象 共46页.pptx

    第8章 Python类和对象.pptx 第9章 Python异常.pptx 第10章 Python文件操作.pptx 第11章 Python项目实战:爬虫程序.pptx 第12章 Python项目实战:数据可视化.pptx 第13章 Python项目实战:数据分析.pptx

    python3-对象与实例.docx

    在Python3中,对象和实例是面向对象编程中最基本的概念之一,本文将详细介绍Python3中的对象和实例。 对象是Python3中最基本的概念之一,它是一个具有属性和方法的数据结构。在Python3中,一切皆为对象,包括数字、...

    Python List列表对象内置方法实例详解

    即是任意内存对象的有序集合,不同的类型对象可以存放在同一个列表中。通过索引来访问其中的元素。可以任意的嵌套、伸长、异构、为可变数据类型,支持原处修改列表内部元素的引用。 修改列表的元素

    一篇文章弄懂Python中所有数组数据类型

    前言 数组类型是各种编程语言中基本的数组结构了,本文来盘点下Python中各种“数组”类型的实现。...它的特点是可变的、能动态扩容,可存储Python中的一切对象,使用时不用指定存储的元素的类型。 使用非常简单

    Python程序设计:Python数字和运算符.pptx

    本任务围绕NBA球星信息展开,需要熟练掌握Python中常见数据类型的使用方法。 在本任务中,我们将先学习Python变量、字符串、列表、字典、集合等的使用方法,并穿插相应的案例及分析过程,实行理论讲解和案例分析相...

    python输出数据类型.md

    python输出数据类型 在Python中,要输出数据类型的语法通常使用type()函数。type()函数的作用是返回输入对象的数据类型。 type(object) 其中,object是要检查其数据类型的对象,可以是任何数据类型的对象,例如整数...

    Python 2和Python 3的介绍

    Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和...

    python对象编程代码

    定义一个类,定义类的对象,通过对象访问成员变量 练习使用类的构造函数和析构函数 练习使用类的静变量和静态方法...判断对象类型 定义一个父类,他定义子类继承父类 练习抽象类和多态 练习对象的序列化 练习对象的赋值

    Python3实现的字典、列表和json对象互转功能示例

    本文实例讲述了Python3实现的字典、列表和json对象互转功能。分享给大家供大家参考,具体如下: python3可以使用json模块操作json json.dumps(): 对json进行编码,对应php的json_encode() json.loads(): 对json进行...

    清华大学精品Python学习PPT课件-第7章 Python模块.pptx

    清华大学精品Python学习PPT课件-第8章 Python类和对象.pptx 清华大学精品Python学习PPT课件-第9章 Python异常.pptx 清华大学精品Python学习PPT课件-第10章 Python文件操作.pptx 清华大学精品Python学习PPT课件-第11...

    Python序列对象与String类型内置方法详解

    在Python数据结构篇中介绍了Python的序列类型数据结构,这次继续深入的学习序列和String类型对象的内建方法。 软件环境 系统 UbuntuKylin 14.04 软件 Python 2.7.3 IPython 4.0.0 序列类型 序列类型,即由整数...

    《Python源代码》书的pdf版(共两部分 part2)

    《Python源码剖析》共两部分,是一部分析Python的好书,通过学习《Python源码剖析》,你不想精通Python都难啊! 第0章 Python源码剖析--编译Python ... 1.1.2 定长对象和变长对象 1.2 类型对象 ……

    Python函数-对象-模块.pdf

    整理总结了Python语言函数的定义,类与对象的定义与使用,Python数据类型转换函数,random函数,判断输入是否为数字判断相关函数,Python取整的方式,常见的Python的数学函数,时间日期相关函数,以及Python的一种...

    Python 可变类型和不可变类型-列表、字典的修改和赋值

    Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和...

Global site tag (gtag.js) - Google Analytics