17xie > Python 语言参考手册 > 3.3 特殊方法名 Special method names
背景:                 
[本书目录] [图书首页] [本书讨论区]  
链接地址:http://www.17xie.com/read-37425.html    注册17xie 一起来写书 实现您的出书梦想!


3.3 特殊方法名 Special method names

A class can implement certain operations that are invoked by special syntax (such as arithmetic operations or subscripting and slicing) by defining methods with special names. This is Python's approach to operator overloading, allowing classes to define their own behavior with respect to language operators. For instance, if a class defines a method named __getitem__(), and x is an instance of this class, then x[i] is equivalent to x.__getitem__(i). Except where mentioned, attempts to execute an operation raise an exception when no appropriate method is defined.

一个类可以实现以特殊句法才调用的某些操作(例如算术运算,下标操作及片断操作), 这是通过以特殊名字定义方法来实现的. 例如, 如果一个类定义了的方法名为__getitem__(), 并且x是这个类的实例, 那么x[i]就等价于x.__getitem__(i), (反过来是不正确的 -- 如果x是一个列表对象, x.__getitem__(i)不等价于x[i].)除了所提及的地方,试图执行没有适当的方法定义的操作会引起一个异常的抛出.

When implementing a class that emulates any built-in type, it is important that the emulation only be implemented to the degree that it makes sense for the object being modelled. For example, some sequences may work well with retrieval of individual elements, but extracting a slice may not make sense. (One example of this is the NodeList interface in the W3C's Document Object Model.)

当实现一个模拟任何内建类型的类时, 重要的地方在于模拟的程度只要使对象模拟时有效就行了. 例如, 某些有序类型的对象可能在单独提取某引起值时有效, 但在使用片断时是没有意义的.(这样的一个例子是在W3C的文档对象模型中的NodeList接口.)



3.3.1 基本定制 Basic customization

__init__( self[, ...])
Called when the instance is created. The arguments are those passed to the class constructor expression. If a base class has an __init__() method, the derived class's __init__() method, if any, must explicitly call it to ensure proper initialization of the base class part of the instance; for example: "BaseClass.__init__(self, [args...])". As a special constraint on constructors, no value may be returned; doing so will cause a TypeError to be raised at runtime.

在实例创建时调用, 参数上传递给类型构造器的表达式. 如果其基类也具有__init__(), 必须显式地在__init__()调用它, 以保证能够适当地初始化它的基类部分; 例如: "BaseClass.__init__(self, [args...])"作为构造器的特殊情况, 它没有值被返回, 如果返回某个值, 会在运行时抛出异常TypeError.

__del__( self)
Called when the instance is about to be destroyed. This is also called a destructor If a base class has a __del__() method, the derived class's __del__() method, if any, must explicitly call it to ensure proper deletion of the base class part of the instance. Note that it is possible (though not recommended!) for the __del__() method to postpone destruction of the instance by creating a new reference to it. It may then be called at a later time when this new reference is deleted. It is not guaranteed that __del__() methods are called for objects that still exist when the interpreter exits.

在实例被删掉时被调用, 也叫作析构器. 如果其基类也具有__del__()方法, 继承类应该在其__del__()显式地调用它, 以保证适当地删掉它的父类部分.注意, 在__del__()通过创建新的引用来推迟删除操作是允许的, 但这不是推荐的做法. 它然后在最后这个引用删除时被调用, 不能保证在解释器退出时, 仍存在的对象一定会调用__del__()方法.

Note: "del x" doesn't directly call x.__del__() -- the former decrements the reference count for x by one, and the latter is only called when x's reference count reaches zero. Some common situations that may prevent the reference count of an object from going to zero include: circular references between objects (e.g., a doubly-linked list or a tree data structure with parent and child pointers); a reference to the object on the stack frame of a function that caught an exception (the traceback stored in sys.exc_traceback keeps the stack frame alive); or a reference to the object on the stack frame that raised an unhandled exception in interactive mode (the traceback stored in sys.last_traceback keeps the stack frame alive). The first situation can only be remedied by explicitly breaking the cycles; the latter two situations can be resolved by storing None in sys.exc_traceback or sys.last_traceback. Circular references which are garbage are detected when the option cycle detector is enabled (it's on by default), but can only be cleaned up if there are no Python-level __del__() methods involved. Refer to the documentation for the gc module for more information about how __del__() methods are handled by the cycle detector, particularly the description of the garbage value.

注意: "del x"不直接调用x__del__() -- 前者将引用计数减一, 而后者仅仅在引用计数减到零时才被调用.有一些经常使用的方法, 可以防止引用计数减为零: 对象之间的循环引用(例如, 一个双链表或一个具有父结点和子结点指针的树形数据结构); 对某函数堆栈结构上的引发异常的对象进行引用(跟踪回溯对象保存在sys.exc_traceback是以保持其有效);或者在交互模式下对某函数堆栈上的引发了没有处理器的异常的对象做引用(跟踪回溯对象保存在sys.last_traceback中以保持其有效). 第一种方法仅能通过显式地破坏循环才能恢复,后两种情况, 可以通过将sys.exc_traceback和sys.last_traceback赋给None来恢复. 仅当循环引用检测器选项被允许时(这是默认的)循环引用才能为垃圾回收机制所发觉, 但这只在没有相关的Python级的__del__()方法时才会被清除.关于__del__()方法怎样处理循环引用的进一步信息参见gc module, 该处具体地描述了垃圾回收.

Warning: Due to the precarious circumstances under which __del__() methods are invoked, exceptions that occur during their execution are ignored, and a warning is printed to sys.stderr instead. Also, when __del__() is invoked in response to a module being deleted (e.g., when execution of the program is done), other globals referenced by the __del__() method may already have been deleted. For this reason, __del__() methods should do the absolute minimum needed to maintain external invariants. Starting with version 1.5, Python guarantees that globals whose name begins with a single underscore are deleted from their module before other globals are deleted; if no other references to such globals exist, this may help in assuring that imported modules are still available at the time when the __del__() method is called.

因为调用__del__()方法的不确定性, 在它执行时的异常会被忽略, 而只是在sys.stderr打印警告 信息.另外, 当某模块被删除,相应的__del__()方法调用时(例如, 程序退出时), 有些为__del_()方法所引用的全局名字可能已经删除了.由于这个原因, __del__()方法应该对其外部要求保持到最小.Python 1.5可以保证以单下划线开始的全局名字在其它全局名字被删除之前从该模块中被删除; 如果没有其它对存在的全局名字的引用, 这会对确定那些已导入的模块在调用__del__()之后有那些还是有效的时是有所帮助的.

__repr__( self)
Called by the repr() built-in function and by string conversions (reverse quotes) to compute the ``official'' string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form "<...some useful description...>" should be returned. The return value must be a string object. If a class defines __repr__() but not __str__(), then __repr__() is also used when an ``informal'' string representation of instances of that class is required.

由repr()内建函数调用或者在串转换(保留引号)时用来计算对象的"正式说明"字符串, 尽可能的, 这应该是一个能以相同的值重建一个对象的有效的Python表达式(在给定的适当有环境下), 如果这不可能的,也应该是返回一个"<... 某些有用的信息 ...>"形式的字符串. 返回值必须是一个字符串.

This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.

本函数典型地用法是用于调试, 所以这个串表述成详尽并无歧义是十分重要的.

__str__( self)
Called by the str() built-in function and by the print statement to compute the ``informal'' string representation of an object. This differs from __repr__() in that it does not have to be a valid Python expression: a more convenient or concise representation may be used instead. The return value must be a string object.

由str()内建函数调用, 或由print语句来计算该对象的"非正式"串描述. 这与__repr__()是不同的, 因为它不要求必须为一个有效的Python表达式: 可以采用一个更通俗或更简洁的表述方式.返回值必须是一个字符串对象.

__lt__( self, other)
__le__( self, other)
__eq__( self, other)
__ne__( self, other)
__gt__( self, other)
__ge__( self, other)
New in version 2.1. These are the so-called ``rich comparison'' methods, and are called for comparison operators in preference to __cmp__() below. The correspondence between operator symbols and method names is as follows: x<y calls x.__lt__(y), x<=y calls x.__le__(y), x==y calls x.__eq__(y), x!=y and x<>y call x.__ne__(y), x>y calls x.__gt__(y), and x>=y calls x.__ge__(y). These methods can return any value, but if the comparison operator is used in a Boolean context, the return value should be interpretable as a Boolean value, else a TypeError will be raised. By convention, False is used for false and True for true.

这是在2.1版本中新增的, 它们称为"厚比较"方法集,并且比下述的__cmp__()方法具有更高的优先级.具体的方法名和相应的运算符的对应关系如下:x<y调用x.__lt__(y); x<=y调用x.__le__(y);x==y调用x.__eq__(y);x!=y和x<>y调用x.__ne__(y); x>y调用x.__gt__(y); x>=y调用x.__ge__(y).这些方法可以返回任何值, 但是如果比较运算符用于布尔上下文, 返回值应该被解释成布尔值, 否则将抛出TypeError异常, 通常0表示假, 1用于表示真.

There are no implied relationships among the comparison operators. The truth of x==y does not imply that x!=y is false. Accordingly, when defining __eq__, one should also define __ne__ so that the operators will behave as expected.

对于这些方法是没有反函数版本(互换参数)的(在左边参数不支持该操作, 但右面的参数支持时使用).虽然, __lt__()和__gt__(),__le__()和__ge__(), __eq__()和__ne__()看起来是反函数.

There are no reflected (swapped-argument) versions of these methods (to be used when the left argument does not support the operation but the right argument does); rather, __lt__() and __gt__() are each other's reflection, __le__() and __ge__() are each other's reflection, and __eq__() and __ne__() are their own reflection.

Arguments to rich comparison methods are never coerced. A rich comparison method may return NotImplemented if it does not implement the operation for a given pair of arguments.

厚比较方法的参数并不是非要有.如果它对给定的参数对没有实现操作, 一个厚比较方法可以返回NotImplemented.

__cmp__( self, other)
Called by comparison operations if rich comparison (see above) is not defined. Should return a negative integer if self < other, zero if self == other, a positive integer if self > other. If no __cmp__(), __eq__() or __ne__() operation is defined, class instances are compared by object identity (``address''). See also the description of __hash__() for some important notes on creating objects which support custom comparison operations and are usable as dictionary keys. (Note: the restriction that exceptions are not propagated by __cmp__() has been removed since Python 1.5.)

如果厚比较操作(见上)未定义, 就调用本函数. 如果self<other小于应该返回负数, 如果self>other应该返回正数, 如果self == other返回, 应该返回零. 如果没有定义__cmp__(), 但定义了__eq__()或__ne__(), 则类的实例可以通过对象的标识("地址")比较. 对于创建支持定制比较操作的对象及可用的字典键的要点详见__hash__的描述(注意: 不能通过__cmp__()传播(propagated)的限制, 已经在Python1.5去掉了).

__rcmp__( self, other)
Changed in version 2.1: No longer supported.

版本2.1中的变化:不再支持.

__hash__( self)
Called for the key object for dictionary operations, and by the built-in function hash(). Should return a 32-bit integer usable as a hash value for dictionary operations. The only required property is that objects which compare equal have the same hash value; it is advised to somehow mix together (e.g., using exclusive or) the hash values for the components of the object that also play a part in comparison of objects. If a class does not define a __cmp__() method it should not define a __hash__() operation either; if it defines __cmp__() or __eq__() but not __hash__(), its instances will not be usable as dictionary keys. If a class defines mutable objects and implements a __cmp__() or __eq__() method, it should not implement __hash__(), since the dictionary implementation requires that a key's hash value is immutable (if the object's hash value changes, it will be in the wrong hash bucket).

为键对象的字典操作而调用, 并且通过内建函数hash()实现.应该返回一个可以在字典操作中可 用的32位整数值.仅有一个要求, 具有相同的值的对象应该有相同的散列值. 应该考虑以某种方式将 散列值与在对象中比较中起作用的部分联系起来(例如, 用排斥或). 如果类没有定义__cmp__()方法, 它也不应该定义__hash__()操作;如果类定义了__cmp__()或__eq__()但没有__hash__(), 它的实例就 不能作为散列表的键使用.如果类定义的是可变对象并且实现了__cmp__()或__eq__()方法, 它就不应该 实现__hash__(), 因为字典实现一个散列表的键值是不可变的(如果对象的散列值改变了, 它会放在错 误的散列表位置中).

__nonzero__( self)
Called to implement truth value testing, and the built-in operation bool(); should return False or True, or their integer equivalents 0 or 1. When this method is not defined, __len__() is called, if it is defined (see below). If a class defines neither __len__() nor __nonzero__(), all its instances are considered true.

在真值测试时调用; 应该返回0或者1.当此方法未定义时, __len__()就会被调用.如果类没定义__len__,没有定义__nonzero__(), 那么它就被看作为真.

__unicode__( self)
Called to implement unicode() builtin; should return a Unicode object. When this method is not defined, string conversion is attempted, and the result of string conversion is converted to Unicode using the system default encoding.

字数:12126    最后更新:8个月以前 [03-15 20:35]月落晨星 修改
本页编辑者:月落晨星  
[前一页]:3.2 标准类型层次 The…  [后一页]:3.3.2 定制属性访问 C…
[在本页中加入书签] [收藏本书] [推荐本书]
  17xie论坛 > 本书讨论区 > 本页评论   (共0条)
发表评论

用户名称 匿名发表
评论内容
验证码

关于我们 | 版权声明 | 免责声明 | 诚聘英才 | 联系我们 | 合作伙伴 | 友情链接 | 广告合作 | 提交意见
Copyright © 2007 17xie.com 互联网协同写书平台 京ICP备08002671号