免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5383 | 回复: 0
打印 上一主题 下一主题

Python 3.1.1 中英文对照版语言参考手册 - 数据模型(下) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-01 16:54 |只看该作者 |倒序浏览

                本章状态:自校完成
3.3.4. 模拟可调用对象(Emulating callable objects)

object.__call__(self[, args...])

Called when the instance is “called” as a function; if this method is defined,
x(arg1, arg2, ...) is a shorthand for x.__call__(arg1, arg2, ...).
当实例作为函数使用时调用本方法。如果定义了这个方法, x(arg1, arg2, ...) 就相当于 x.__call__(arg1, arg2, ...) 。
3.3.5. 模拟容器对象(Emulating container types)

The following methods can be defined to implement container objects.  Containers
usually are sequences (such as lists or tuples) or mappings (like dictionaries),
but can represent other containers as well.  The first set of methods is used
either to emulate a sequence or to emulate a mapping; the difference is that for
a sequence, the allowable keys should be the integers k for which 0  k
N where N is the length of the sequence, or slice objects, which define a
range of items.  It is also recommended that mappings provide the methods
keys(), values(), items(), get(), clear(),
setdefault(), pop(), popitem(), copy(), and
update() behaving similar to those for Python’s standard dictionary
objects.  The
collections
module provides a MutableMapping
abstract base class to help create those methods from a base set of
__getitem__()
,
__setitem__()
,
__delitem__()
, and keys().
Mutable sequences should provide methods append(), count(),
index(), extend(), insert(), pop(), remove(),
reverse() and sort(), like Python standard list objects.  Finally,
sequence types should implement addition (meaning concatenation) and
multiplication (meaning repetition) by defining the methods
__add__()
,
__radd__()
,
__iadd__()
,
__mul__()
,
__rmul__()
and
__imul__()
described below; they should not define other numerical
operators.  It is recommended that both mappings and sequences implement the
__contains__()
method to allow efficient use of the in operator; for
mappings, in should search the mapping’s keys; for sequences, it should
search through the values.  It is further recommended that both mappings and
sequences implement the
__iter__()
method to allow efficient iteration
through the container; for mappings,
__iter__()
should be the same as
keys(); for sequences, it should iterate through the values.
通过定义以下方法可以实现容器对象。容器通常指有序类型(如列表或元组)或映射类型(如字典),不过也可以表示其它容器。第一个方法集用于模拟有序类型或映射:有序类型的区别在于,键只能是整数 k ( 0  k  N , N 是有序类型的长度)或者是定义了处在一个范围内的项的片断对象。另外,也推荐模拟映射类型时实现方法 keys() 、 values() 、 items() 、 get() 、 clear() 、 setdefault() 、 pop() 、 popitem() 、 copy() 和 update() ,这使得模拟出来的行为与Python标准字典对象类似。模块
collections
提供了 MutableMapping 抽象基类可用于帮助从基本方法
__getitem__()

__setitem__()

__delitem__()
和 keys() 中创建这些方法。可变有序类型应该提供方法 append() 、 count() 、 index() 、  extend() 、 insert() 、 pop() 、 remove() 、 reverse() 和 sort() ,就像Python标准列表对象那样。最后,有序类型应该用下述的方法  
__add__()

__radd__()

__iadd__()

__mul__()

__rmul__()

__imul__()
实现“加”操作(即连接)和“乘”操作(即重复)。它们也可以实现其它算术运算符。推荐映射和有序类型实现
__contains__()
方法以实现 in 操作符的有效使用,对于映射类型, in 应该搜索映射的键,对于有序类型,它应该搜索值 。进一步的建议是映射和有序类型实现
__iter__()
方法,以支持在容器中有效地进行迭代。对于映射,
__iter__()
应该与 keys() 相同,对于有序类型,它应该在值之间迭代。
object.__len__(self)

Called to implement the built-in function
len()
.  Should return the length
of the object, an integer >= 0.  Also, an object that doesn’t define a
__bool__()
method and whose
__len__()
method returns zero is
considered to be false in a Boolean context.
实现内置函数
len()
相仿的功能。应该返回对象的长度,一个大于等于0的整数。另外,如果对象没有定义
__bool__()
方法,那么在布尔上下文中,
__len__()
返回的 0 将被看作是“假”。
Note
Slicing is done exclusively with the following three methods.  A call like :
片断独立于下面介绍的三个方法,类似于下面的调用:
a[1:2] = b
is translated to :
会转换为
a[slice(1, 2, None)] = b
and so forth.  Missing slice items are always filled in with None.
以此类推。缺少的片断项会被替代为 None 。
object.__getitem__(self, key)

Called to implement evaluation of self[key]. For sequence types, the
accepted keys should be integers and slice objects.  Note that the special
interpretation of negative indexes (if the class wishes to emulate a sequence
type) is up to the
__getitem__()
method. If key is of an inappropriate
type,
TypeError
may be raised; if of a value outside the set of indexes
for the sequence (after any special interpretation of negative values),
IndexError
should be raised. For mapping types, if key is missing (not
in the container),
KeyError
should be raised.
用于实现 self[key] 。对于有序类型,可接受的 key 应该有整数和片断对象。注意对负数索引(如果类希望模拟有序类型)的特殊解释也依赖于
__getitem__()
方法。如果 key 的类型不合适,可以抛出异常
TypeError
。如果 key 的值在有序类型的索引范围之外(在任何负值索引的特殊解释也行不通的情况下),可以抛出
IndexError
异常。对于映射类型,如果没有给出 key (或者不在容器之内),应该抛出异常
KeyError

Note
for
loops expect that an
IndexError
will be raised for illegal
indexes to allow proper detection of the end of the sequence.
for
循环根据由于无效索引导致的
IndexError
异常检测有序类型的结尾。
object.__setitem__(self, key, value)

Called to implement assignment to self[key].  Same note as for
__getitem__()
.  This should only be implemented for mappings if the
objects support changes to the values for keys, or if new keys can be added, or
for sequences if elements can be replaced.  The same exceptions should be raised
for improper key values as for the
__getitem__()
method.
在对 self[key] 赋值时调用。与
__getitem__()
有着相同的注意事项。如果映射类型对象要支持改变键的值或者增加新键,或者有序类型要支持可替换元素时,应该实现这个方法。在使用无效的 key 值时,会抛出与
__getitem__()
相同的异常。
object.__delitem__(self, key)

Called to implement deletion of self[key].  Same note as for
__getitem__()
.  This should only be implemented for mappings if the
objects support removal of keys, or for sequences if elements can be removed
from the sequence.  The same exceptions should be raised for improper key
values as for the
__getitem__()
method.
在删除 self[key] 时调用,与
__getitem__()
有相同的注意事项。如果映射对象要支持删除键,或者有序类型对象要支持元素的删除,就应该实现这个方法。在使用无效的 key 值时,会抛出与
__getitem__()
相同的异常。
object.__iter__(self)

This method is called when an iterator is required for a container. This method
should return a new iterator object that can iterate over all the objects in the
container.  For mappings, it should iterate over the keys of the container, and
should also be made available as the method keys().
在使用容器的迭代器时会调用这个方法。本方法应该返回一个可以遍历容器内所有对象的迭代器对象。对于映射类型,应该在容器的键上迭代,并且也应该定义 keys() 方法。
Iterator objects also need to implement this method; they are required to return
themselves.  For more information on iterator objects, see
Iterator Types
.
迭代器对象也需要实现这个方法,它们应该返回它自身。关于迭代器对象的更多信息,可以参考  
Iterator Types

object.__reversed__(self)

Called (if present) by the
reversed()
built-in to implement
reverse iteration.  It should return a new iterator object that iterates
over all the objects in the container in reverse order.
在使用内置函数
reversed()
实现反向迭代时调用这个方法。它应该返回一个以相反顺序在容器内迭代所有对象的新迭代器对象。
If the
__reversed__()
method is not provided, the
reversed()
built-in will fall back to using the sequence protocol (
__len__()
and
__getitem__()
).  Objects that support the sequence protocol should
only provide
__reversed__()
if they can provide an implementation
that is more efficient than the one provided by
reversed()
.
如果没有定义方法
__reversed__()
,内置函数
reversed()
会切换到备用方案:使用序列协议 (
__len__()
和  
__getitem__()
)。支持序列协议的对象只在有更高效的  
reversed()
实现方法时,才有必要实现  
__reversed__()

The membership test operators (
in
and
not in
) are normally
implemented as an iteration through a sequence.  However, container objects can
supply the following special method with a more efficient implementation, which
also does not require the object be a sequence.
成员测试运算符(
in

not in
)一般是在对有序类型进行迭代实现的。但是容器也可以实现方法提供更高效率的实现,并不要求对象一定是有序类型。
object.__contains__(self, item)

Called to implement membership test operators.  Should return true if item is
in self, false otherwise.  For mapping objects, this should consider the keys
of the mapping rather than the values or the key-item pairs.
在成员测试时调用这个方法。如果 item 在 self 之内应该返回真,否则返回假。对于映射类型的对象,测试应该是针对键的,而不是值,或者键值对。
3.3.6. 模拟数值类型(Emulating numeric types)

The following methods can be defined to emulate numeric objects. Methods
corresponding to operations that are not supported by the particular kind of
number implemented (e.g., bitwise operations for non-integral numbers) should be
left undefined.
以下方法用于模拟数值类型。不同数值类型所支持的操作符并不完全相同,如果一个类型不支持某些操作符(例如非整数值上的位运算),对应的方法就不应该被实现。
object.__add__(self, other)

object.__sub__(self, other)

object.__mul__(self, other)

object.__truediv__(self, other)

object.__floordiv__(self, other)

object.__mod__(self, other)

object.__divmod__(self, other)

object.__pow__(self, other[, modulo])

object.__lshift__(self, other)

object.__rshift__(self, other)

object.__and__(self, other)

object.__xor__(self, other)

object.__or__(self, other)

These methods are called to implement the binary arithmetic operations (+,
-, *, /, //, %,
divmod()
,
pow()
, **, ,
>>, &, ^, |).  For instance, to evaluate the expression
x + y, where x is an instance of a class that has an
__add__()
method, x.__add__(y) is called.  The
__divmod__()
method should be the
equivalent to using
__floordiv__()
and
__mod__()
; it should not be
related to
__truediv__()
.  Note that
__pow__()
should be defined
to accept an optional third argument if the ternary version of the built-in
pow()
function is to be supported.
这些方法用于二元算术操作( + 、 - 、 * 、 / 、 // 、 % ,
divmod()

pow()
、 ** 、  、 >> 、 & 、 ^ 、 | )。例如,在计算表达式 x + y 时, x 是一个定义了
__add__()
的类的实例,那么就会调用  x.__add__(y) 。方法
__divmod__()
应该与使用
__floordiv__()

__mod__()
的结果相同,但应该与
__truediv__()
无关。注意如果要支持三参数版本的内置函数
pow()
的话,方法
__pow__()
应该被定义成可以接受第三个可选参数的。
If one of those methods does not support the operation with the supplied
arguments, it should return NotImplemented.
如果以上任一方法无法处理根据参数完成计算的话,就应该返回 NotImplemented 。
object.__radd__(self, other)

object.__rsub__(self, other)

object.__rmul__(self, other)

object.__rtruediv__(self, other)

object.__rfloordiv__(self, other)

object.__rmod__(self, other)

object.__rdivmod__(self, other)

object.__rpow__(self, other)

object.__rlshift__(self, other)

object.__rrshift__(self, other)

object.__rand__(self, other)

object.__rxor__(self, other)

object.__ror__(self, other)

These methods are called to implement the binary arithmetic operations (+,
-, *, /, //, %,
divmod()
,
pow()
, **,
, >>, &, ^, |) with reflected (swapped) operands.
These functions are only called if the left operand does not support the
corresponding operation and the operands are of different types.
[3]
  For
instance, to evaluate the expression x - y, where y is an instance of
a class that has an
__rsub__()
method, y.__rsub__(x) is called if
x.__sub__(y) returns NotImplemented.
这些方法用于实现二元算术操作(``+`` 、 - 、 * 、 / 、 // 、 % 、
divmod()

pow()
、 ** 、   、 >> 、 & 、 ^ 、 | ),但用于操作数反射(即参数顺序是相反的)。这些函数只有在左操作数不支持相应操作,并且是参数是不同类型时才会被使用。[3] 例如,计算表达式 x - y , y 是一个定义了方法
__rsub__()
的类实例,那么在 x.__sub__(y) 返回 NotImplemented 时才会调用 y.__rsub__(x) 。
Note that ternary
pow()
will not try calling
__rpow__()
(the
coercion rules would become too complicated).
注意三参数版本的
pow()
不会试图调用
__rpow__()
。(这会导致类型自动转换规则过于复杂)
Note
If the right operand’s type is a subclass of the left operand’s type and that
subclass provides the reflected method for the operation, this method will be
called before the left operand’s non-reflected method.  This behavior allows
subclasses to override their ancestors’ operations.
注意:如果右操作数的类型是左操作数的一个子类,并且这个子类提供了操作数反射版本的方法。那么,子类的操作数反射方法将在左操作数的非反射方法之前调用。这个行为允许了子类可以覆盖祖先类的操作。
object.__iadd__(self, other)

object.__isub__(self, other)

object.__imul__(self, other)

object.__itruediv__(self, other)

object.__ifloordiv__(self, other)

object.__imod__(self, other)

object.__ipow__(self, other[, modulo])

object.__ilshift__(self, other)

object.__irshift__(self, other)

object.__iand__(self, other)

object.__ixor__(self, other)

object.__ior__(self, other)

These methods are called to implement the augmented arithmetic assignments
(+=, -=, *=, /=, //=, %=, **=, , >>=,
&=, ^=, |=).  These methods should attempt to do the operation
in-place (modifying self) and return the result (which could be, but does
not have to be, self).  If a specific method is not defined, the augmented
assignment falls back to the normal methods.  For instance, to execute the
statement x += y, where x is an instance of a class that has an
__iadd__()
method, x.__iadd__(y) is called.  If x is an instance
of a class that does not define a
__iadd__()
method, x.__add__(y)
and y.__radd__(x) are considered, as with the evaluation of x + y.
这些方法用于实现参数化算术赋值操作( += 、 -= 、 *= 、 /= 、 //= 、 %= 、 **= 、  、 >>= 、  &= 、 ^= 、 |=))。这些方法应该是就地操作的(即直接修改 self )并返回结果(一般来讲,这里应该是对 self 直接操作,但并不是一定要求如此)。如果没有实现某个对应方法的话,参数化赋值会蜕化为正常方法。例如,执行语句 x += y 时, x 是一个实现了
__iadd__()
方法的实例, x.__iadd__(y) 就会被调用。如果 x 没有定义
__iadd__()
,就会选择 x.__add__(y) 或者  y.__radd__(x) ,与 x + y 类似。
object.__neg__(self)

object.__pos__(self)

object.__abs__(self)

object.__invert__(self)

Called to implement the unary arithmetic operations (-, +,
abs()
and ~).
用于实现一元算术操作( - 、 + 、
abs()
和 ~ )。
object.__complex__(self)

object.__int__(self)

object.__float__(self)

object.__round__(self[, n])

Called to implement the built-in functions
complex()
,
int()
,
float()
and
round()
.  Should return a value
of the appropriate type.
用于实现内置函数
complex()

int()

float()

round()
。应该返回对应的类型值。
object.__index__(self)

Called to implement
operator.index()
.  Also called whenever Python needs
an integer object (such as in slicing, or in the built-in
bin()
,
hex()
and
oct()
functions). Must return an integer.
用于实现函数
operator.index()
,或者在Python需要一个整数对象时调用(例如在分片时(slicing),或者在内置函数函数
bin()
、  
hex()

oct()
中)。这个方法必须返回一个整数。
3.3.7. with语句的上下文管理器(With Statement Context Managers)

A context manager is an object that defines the runtime context to be
established when executing a
with
statement. The context manager
handles the entry into, and the exit from, the desired runtime context for the
execution of the block of code.  Context managers are normally invoked using the
with
statement (described in section
with 语句(The with statement)
), but can also be
used by directly invoking their methods.
上下文管理器( context manager )是一个对象,这个对象定义了执行
with
语句时要建立的运行时上下文。上下文管理器负责处理执行某代码块时对应的运行时上下文进入和退出。运行时上下文的使用一般通过
with
语句(参见
with 语句(The with statement)
),但也可以直接调用它的方法。
Typical uses of context managers include saving and restoring various kinds of
global state, locking and unlocking resources, closing opened files, etc.
上下文管理器的典型用途包括保存和恢复各种全局状态,锁定和解锁资源,关闭打开的文件等等。
For more information on context managers, see
Context Manager Types
.
关于上下文管理的更多信息,可以参考
Context Manager Types

object.__enter__(self)

Enter the runtime context related to this object. The
with
statement
will bind this method’s return value to the target(s) specified in the
as
clause of the statement, if any.
进入与这个对象关联的运行时上下文。
with
语句会把这个方法的返回值与
as
子句指定的目标绑定在一起(如果指定了的话)。
object.__exit__(self, exc_type, exc_value, traceback)

Exit the runtime context related to this object. The parameters describe the
exception that caused the context to be exited. If the context was exited
without an exception, all three arguments will be
None
.
退出与这个对象相关的运行时上下文。参数描述了导致上下文退出的异常,如果是无异常退出,则这三个参数都为
None

If an exception is supplied, and the method wishes to suppress the exception
(i.e., prevent it from being propagated), it should return a true value.
Otherwise, the exception will be processed normally upon exit from this method.
如果给出了一个异常,而这个方法决定要压制它(即防止它把传播出去),那么它应该返回真。否则,在退出这个方法时,这个异常会按正常方式处理。
Note that
__exit__()
methods should not reraise the passed-in exception;
this is the caller’s responsibility.
注意方法
__exit__()
不应该把传入的异常重新抛出,这是调用者的责任。
See also
PEP 0343
- The “with” statement (”with” 语句)The specification, background, and examples for the Python
with
statement.
Python
with
语句的规范、背景和例子。
3.3.8. 搜索特殊方法(Special method lookup)

For custom classes, implicit invocations of special methods are only guaranteed
to work correctly if defined on an object’s type, not in the object’s instance
dictionary.  That behaviour is the reason why the following code raises an
exception:
对于定制类,只有在对象类型的字典里定义好,才能保证成功调用特殊方法。这是以下代码发生异常的原因:
>>> class C(object):
...     pass
...
>>> c = C()
>>> c.__len__ = lambda: 5
>>> len(c)
Traceback (most recent call last):
  File "", line 1, in
TypeError: object of type 'C' has no len()
The rationale behind this behaviour lies with a number of special methods such
as
__hash__()
and
__repr__()
that are implemented by all objects,
including type objects. If the implicit lookup of these methods used the
conventional lookup process, they would fail when invoked on the type object
itself:
这个行为的原因在于,有不少特殊方法在所有对象中都得到了实现,例如
__hash__()

__repr__()
。如果按照常规的搜索过程搜索这些方法,在涉及到类型对象时就会出错:
>>> 1 .__hash__() == hash(1)
True
>>> int.__hash__() == hash(int)
Traceback (most recent call last):
  File "", line 1, in
TypeError: descriptor '__hash__' of 'int' object needs an argument
Incorrectly attempting to invoke an unbound method of a class in this way is
sometimes referred to as ‘metaclass confusion’, and is avoided by bypassing
the instance when looking up special methods:
试图以这种错误方式调用一个类的未绑定方法有时叫作“元类含混”,可以通过在搜索特殊方法时跳过实例避免:
>>> type(1).__hash__(1) == hash(1)
True
>>> type(int).__hash__(int) == hash(int)
True
In addition to bypassing any instance attributes in the interest of
correctness, implicit special method lookup generally also bypasses the
__getattribute__()
method even of the object’s metaclass:
除了因为正确性的原因而跳过实例属外之外,特殊方法搜索也会跳过
__getattribute__()
方法,甚至是元类中的:
>>> class Meta(type):
...    def __getattribute__(*args):
...       print("Metaclass getattribute invoked")
...       return type.__getattribute__(*args)
...
>>> class C(object, metaclass=Meta):
...     def __len__(self):
...         return 10
...     def __getattribute__(*args):
...         print("Class getattribute invoked")
...         return object.__getattribute__(*args)
...
>>> c = C()
>>> c.__len__()                 # Explicit lookup via instance
Class getattribute invoked
10
>>> type(c).__len__(c)          # Explicit lookup via type
Metaclass getattribute invoked
10
>>> len(c)                      # Implicit lookup
10
Bypassing the
__getattribute__()
machinery in this fashion
provides significant scope for speed optimisations within the
interpreter, at the cost of some flexibility in the handling of
special methods (the special method must be set on the class
object itself in order to be consistently invoked by the interpreter).
这种跳过
__getattribute__()
的机制为解释器的时间性能优化提供了充分的余地,代价是牺牲了处理特殊方法时的部分灵活性(为了保持与解释器的一致,特殊方法必须在类对象中定义)。
Footnotes
[1]
It is possible in some cases to change an object’s type, under certain
controlled conditions. It generally isn’t a good idea though, since it can
lead to some very strange behaviour if it is handled incorrectly.
是在某些受控制的条件下,修改对象类型是有可能的。但一般这不是个好做法,因为一旦处理不周,就有可能导致一些非常奇怪的行为。
[2]
A descriptor can define any combination of
__get__()
,
__set__()
and
__delete__()
.  If it does not define
__get__()
,
then accessing the attribute even on an instance will return the descriptor
object itself.  If the descriptor defines
__set__()
and/or
__delete__()
, it is a data descriptor; if it defines neither, it is a
non-data descriptor.
一个描述符可以定义
__get__()

__set__()

__delete__()
的任意组合。如果它没有定义
__get__()
,那么访问该属性(甚至通过实例)就直接会返回该描述符本身。如果描述符定义了
__set__()
和(或)
__delete__()
,它就是一个数据描述符。如果两者都没有定义,它就是非数据描述符。
[3]
For operands of the same type, it is assumed that if the non-reflected method
(such as
__add__()
) fails the operation is not supported, which is why the
reflected method is not called.
对于相同类型的操作数,假定如果非反射方法失败就意味着并不支持这个运算符。这就是没有调用反射方法的原因。
               
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u1/42957/showart_2137263.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP