<< >>

diveintopython.org |

Python for experienced programmers

## 3.6. 高级专用类方法

比起刚才的 `__getitem__` 和 `__setitem__` 还有更多的专用函数。某些可以让你模拟出你甚至可能不知道的功能。

例 3.13. 在 `UserDict` 中更多的专用方法

        def __repr__(self): return repr(self.data)
        def __cmp__(self, dict):
            if isinstance(dict, UserDict):
                return cmp(self.data, dict.data)
            else:
                return cmp(self.data, dict)
        def __len__(self): return len(self.data)
        def __delitem__(self, key): del self.data[key]

| `__repr__` 是一个专用的方法，在当调用 `repr(instance)` 时被调用。`repr` 函数是一个内置函数，它返回一个对象的字符串表示。它可以用在任何对象上，不仅仅是类的实例。你已经对 `repr` 相当熟悉了，尽管你不知道它。在交互式窗口中，当你只敲入一个变量名，接着按回车，Python使用 `repr` 来显示变量的值。自已用一些数据来创建一个字典 `d` ，然后用 `print repr(d)` 来看一看吧。
| `__cmp__` 在比较类实例时被调用。通常，你可以通过使用 `==` 比较任意两个Python对象，不只是类实例。有一些规则，定义了何时内置数据类型被认为是相等的，例如，字典在有着全部相同的关键字和值时是相等的。对于类实例，你可以定义 `__cmp__` 方法，自已编写比较逻辑，然后你可以使用 `==` 来比较你的类，Python将会替你调用你的 `__cmp__` 专用方法。
| `__len__` 在当调用 `len(instance)` 时被调用。`len` 是一个内置函数，可以返回一个对象的长度。它可以用于任何被认为理应有长度的对象。字符串的 `len` 是它的字符个数；字典的 `len` 是它的关键字的个数；列表或序列的 `len` 是元素的个数。对于类实例，定义 `__len__` 方法，接着自已编写长度的计算，然后调用`len(instance)`，Python将替你调用你的 `__len__` 专用方法。
| `__delitem__` 在调用 `del instance[key]` (你可能记得它作为从字典中删除单个元素的方法)时调用，Python替你调用 `__delitem__` 专用方法。

在这个地方，你可能会想，“所有这些工作只是为了在类中做一些我可以对一个内置数据类型所做的操作”。不错，如果你能够从象字典一样的内置数据类型进行继承的话，事情就容易多了(那样整个 `UserDict` 类将完全不需要了)。但是也许你可以，专用方法仍然是有用的，因为它们可以用于任何的类，而不只是象 `UserDict` 的封装类。

专用方法意味着任何类可以象字典一样保存键-值对，只要定义 `__setitem__` 方法。任何类可以表现得象一个序列，只要通过定义`__getitem__` 方法。任何定义了 `__cmp__` 方法的类可以用 `==` 进行比较。并且如果你的类表现拥有类似长度的东西，不要定义 `GetLength` 方法，而定义 `__len__` 方法，使用 `len(instance)`。

但是其它的面向对象语言仅让你定义一个对象的物理模型(“这个对象有 `GetLength` 方法”)，专用类方法象 `__len__` 允许你定义一个对象的逻辑模型(“这个对象有一个长度”)。

存在许多其它的专用方法。有一整套的专用方法，可以让类表现得象数值一样，允许你在类实例上进行加，减，和执行其它数学操作。(关于这一点典型的例子就是表示复数的类，数值带有实数和虚数部分。) `__call__` 方法让一个类表现得象一个函数，允许你直接调用一个类实例。并且存在其它的专用函数，允许类拥有只读或只写数据属性，在后面的章节中我们会更多地谈到这些。

进一步阅读 |

- Python Reference Manual 提供了所有专用类方法的文档。

« 专用类方法 | 类属性 »