您当前位置:首页 > 深入 Python > 对象和面向对象 > 高级特殊类方法 | << >> | ||||
深入 Python从 Python 新手到专家 |
Python 拥有的特殊方法不仅仅是 __getitem__ 和 __setitem__。其中一些方法可以让您模拟您可能根本不知道的功能。
此示例展示了 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(实例) 时会调用它。repr 函数是一个内置函数,它返回对象的字符串表示形式。它适用于任何对象,而不仅仅是类实例。您已经非常熟悉 repr,即使您可能没有意识到。在交互式窗口中,当您只输入一个变量名并按下 ENTER 键时,Python 会使用 repr 来显示变量的值。尝试创建一个包含一些数据的字典 d,然后使用 print repr(d) 来亲自查看。 |
![]() |
__cmp__ 在您比较类实例时被调用。通常,您可以使用 == 比较任意两个 Python 对象,而不仅仅是类实例。有一些规则定义了何时认为内置数据类型相等;例如,当字典具有所有相同的键和值时,它们是相等的;当字符串长度相同且包含相同的字符序列时,它们是相等的。对于类实例,您可以定义 __cmp__ 方法并自己编写比较逻辑,然后可以使用 == 比较类的实例,Python 会为您调用 __cmp__ 特殊方法。 |
![]() |
__len__ 在您调用 len(实例) 时被调用。len 函数是一个内置函数,它返回对象的长度。它适用于任何可以合理地认为具有长度的对象。字符串的 len 是其字符数;字典的 len 是其键数;列表或元组的 len 是其元素数。对于类实例,定义 __len__ 方法并自己编写长度计算代码,然后调用 len(实例),Python 会为您调用 __len__ 特殊方法。 |
![]() |
__delitem__ 在您调用 del 实例[键] 时被调用,您可能还记得这是从字典中删除单个项目的方法。当您在类实例上使用 del 时,Python 会为您调用 __delitem__ 特殊方法。 |
![]() |
|
在 Java 中,您可以使用 str1 == str2 来确定两个字符串变量是否引用同一个物理内存位置。这被称为对象标识,在 Python 中写为 str1 is str2。要在 Java 中比较字符串值,您将使用 str1.equals(str2);在 Python 中,您将使用 str1 == str2。那些被教导相信世界会更美好,因为 Java 中的 == 是按标识而不是按值进行比较的 Java 程序员,在适应 Python 缺乏这种“陷阱”时可能会遇到困难。 |
在这一点上,您可能会想:“做了这么多工作,只是为了在一个类中做一些我可以用内置数据类型完成的事情。” 的确,如果您可以从字典之类的内置数据类型继承,生活会更轻松(并且整个 UserDict 类都是不必要的)。但即使您可以这样做,特殊方法仍然很有用,因为它们可以用于任何类,而不仅仅是像 UserDict 这样的包装类。
特殊方法意味着任何类都可以像字典一样存储键/值对,只需定义 __setitem__ 方法即可。任何类都可以像序列一样工作,只需定义 __getitem__ 方法即可。任何定义了 __cmp__ 方法的类都可以使用 == 进行比较。如果您的类表示具有长度的内容,请不要定义 GetLength 方法;定义 __len__ 方法并使用 len(实例)。
![]() |
|
其他面向对象语言只允许您定义对象的物理模型(“此对象具有 GetLength 方法”),而 Python 的特殊类方法(如 __len__)允许您定义对象的逻辑模型(“此对象具有长度”)。 |
Python 还有很多其他的特殊方法。有一整套方法可以让类像数字一样工作,允许您对类实例进行加、减和其他算术运算。(这方面的典型例子是一个表示复数的类,即具有实部和虚部的数字。)__call__ 方法可以让一个类像函数一样工作,允许您直接调用一个类实例。还有其他的特殊方法允许类具有只读和只写的数据属性;我们将在后面的章节中详细讨论这些内容。
<< 特殊类方法 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
介绍类属性 >> |