免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4003 | 回复: 0

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

论坛徽章:
0
发表于 2010-01-01 16:49 |显示全部楼层

               
                                本章状态:自校完成
3.3.1. 基本定制(Basic customization)

object.__new__(cls[, ...])

Called to create a new instance of class cls.  
__new__()
is a static
method (special-cased so you need not declare it as such) that takes the class
of which an instance was requested as its first argument.  The remaining
arguments are those passed to the object constructor expression (the call to the
class).  The return value of
__new__()
should be the new object instance
(usually an instance of cls).
用于创建类 cls 的新实例。
__new__()
是静态方法(但你并不需要显式地这样声明),它的第一个参数是新实例的类,其余的参数就是传递给类构造器(即类调用)的那些参数。
__new__()
的返回值应该是新对象实例(一般来说是类 cls 的实例)。
Typical implementations create a new instance of the class by invoking the
superclass’s
__new__()
method using super(currentclass,
cls).__new__(cls[, ...]) with appropriate arguments and then modifying the
newly-created instance as necessary before returning it.
这个方法的典型实现是用适当的参数通过 super(currentclass, cls).__new__(cls[, ...]) 调用父类的
__new__()
方法创建新实例,在其基础上做可能的修改,再返回之。
If
__new__()
returns an instance of cls, then the new instance’s
__init__()
method will be invoked like __init__(self[, ...]), where
self is the new instance and the remaining arguments are the same as were
passed to
__new__()
.
如果
__new__()
返回了 cls 的一个实例,之后会以 __init__(self[, ...]) 的方式调用新实例的
__init__()
方法,其中 self 是新实例,其余参数与传递给
__new__()
的相同。
If
__new__()
does not return an instance of cls, then the new instance’s
__init__()
method will not be invoked.
如果
__new__()
没有返回 cls 的实例,就不会调用新实例的
__init__()

__new__()
is intended mainly to allow subclasses of immutable types (like
int, str, or tuple) to customize instance creation.  It is also commonly
overridden in custom metaclasses in order to customize class creation.
引入
__new__()
主要是为了允许对不可变类型(如整数、字符串和元组)的子类定制实例。另外,它通常也在元类(metaclass)定制化时被重载,目的是定制类的创建。
object.__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__()
方法,那么必须显式地调用它以确保完成对实例基础部分的初始化。例如, BaseClass.__init__(self, [args...]) 。作为一个构造时的特殊限制,这个方法不会返回任何值,否则会导致运行时抛出异常
TypeError

object.__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.
在实例要被释放(destroy)时被调用,也称为析构器。如果基类中也有
__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_info()[2] 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.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.ext_info()[2] 中的回溯对象保证了栈桢不会被删除);或者交互模式下出现未拦截异常的栈桢上的对象的引用( sys.last_traceback 中的回溯对象保证了栈桢不会被删除)。第一种情况只有能通过地打破循环才能解决。后两种情况,可以通过将 sys.last_traceback 赋予 None 解决。只有在打开循环检查器选项时(这是默认的),循环引用才能被垃圾回收机制发现,但前提是Python脚本中的
__del__()
方法不要参与进来。关于
__del__()
与循环检查器是如何相互影响的详细信息,可以参见
gc
模块的介绍,尤其是其中的 garbage 值的描述。
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 or in the process of being torn down (e.g. the import
machinery shutting down).  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__()
所引用的全局名字可能已经删除了,或者正在删除(例如,正在清理import关系)。由于这些原因,
__del__()
方法对外部不变式的要求应该保持最小。从Python1.5开始,Python可以保证以单下划线开始的全局名字一定在其它全局名字之前从该模块中删除,如果没有其它对这种全局名字的引用,这个功能有助于保证导入的模块在调用
__del__()
时还是有效的。
object.__repr__(self)

Called by the
repr()
built-in function 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  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表达式(在适当环境下)。如果这不可能,也应该是返回一个形如  一些有用的描述 ...> 的字符串。返回值必须是一个字符串对象。如果类定义了
__repr__()
方法,但没有定义
__str__()
,那么
__repr__()
也可以用于产生类实例的“说明性“字符串描述。
This is typically used for debugging, so it is important that the representation
is information-rich and unambiguous.
一般来说,这通常用于调试,所以描述字符串的信息丰富性和无歧义性是很重要的。
object.__str__(self)

Called by the
str()
built-in function and by the
print()
function
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表达式,可以采用比较通俗简洁的表述方式。返回值必须是一个字符串对象。
object.__format__(self, format_spec)

Called by the
format()
built-in function (and by extension, the
format()
method of class
str
) to produce a “formatted”
string representation of an object. The format_spec argument is
a string that contains a description of the formatting options desired.
The interpretation of the format_spec argument is up to the type
implementing
__format__()
, however most classes will either
delegate formatting to one of the built-in types, or use a similar
formatting option syntax.
由内置函数
format()
(和
str
类的方法
format()
)调用,用来构造对象的“格式化”字符串描述。 format_spec 参数是描述格式选项的字符串。 format_spec 的解释依赖于实现
__format__()
的类型,但一般来说,大多数类要么把格式化任务委托(转交)给某个内置类型,或者使用与内置类型类似的格式化选项。
See
Format Specification Mini-Language
for a description of the standard formatting syntax.
关于标准格式语法的描述,可以参考
Format Specification Mini-Language

The return value must be a string object.
返回值必须是字符串对象。
object.__lt__(self, other)

object.__le__(self, other)

object.__eq__(self, other)

object.__ne__(self, other)

object.__gt__(self, other)

object.__ge__(self, other)

These are the so-called “rich comparison” methods. The correspondence between
operator symbols and method names is as follows: x calls x.__lt__(y),
x calls x.__le__(y), x==y calls x.__eq__(y), x!=y calls
x.__ne__(y), x>y calls x.__gt__(y), and x>=y calls
x.__ge__(y).
它们称为”厚比较”方法。运算符与方法名的对应关系如下: x 调用 x.__lt__(y) 、  x 调用 x.__le__(y) 、 x==y 调用 x.__eq__(y) 、 x!=y 调用  x.__ne__(y) 、 x>y 调用 x.__gt__(y) 、 x>=y 调用 x.__ge__(y) 。
A rich comparison method may return the singleton NotImplemented if it does
not implement the operation for a given pair of arguments. By convention,
False and True are returned for a successful comparison. However, these
methods can return any value, so if the comparison operator is used in a Boolean
context (e.g., in the condition of an if statement), Python will call
bool()
on the value to determine if the result is true or false.
不是所有厚比较方法都要同时实现的,如果个别厚比较方法没有实现,可以直接返回 NotImplemented 。从习惯上讲,一次成功的比较应该返回 False 或 True 。但是这些方法也可以返回任何值,所以如果比较运算发生在布尔上下文中(例如 if 语句中的条件测试),Python会在返回值上调用函数
bool()
确定返回值的真值。
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.  See the paragraph on
__hash__()
for
some important notes on creating
hashable
objects which support
custom comparison operations and are usable as dictionary keys.
在比较运算符之间并没有潜在的相互关系。 x==y 为真并不意味着 x!=y 为假。因此,如果定义了方法
__eq__()
,那么也应该定义
__ne__()
,这样才可以得到期望的效果。关于如何创建可以作为字典键使用的
hashable
对象,还需要参考
__hash__()
的介绍。
There are no 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.
没有参数交换版本的方法定义(这可以用于当左边参数不支持操作,但右边参数支持的情况)。
__lt__()

__gt__()
相互反射(即互为参数交换版本);  
__le__()

__ge__()
相互反射;
__eq__()

__ne__()
相互反射。
Arguments to rich comparison methods are never coerced.
传递给厚比较方法的参数不能是被自动强制类型转换的(coerced)。
To automatically generate ordering operations from a single root operation,
see the
Total Ordering recipe in the ASPN cookbook
.
关于如何从一个根操作自动生成顺序判定操作,可以参考
Total Ordering recipe in the ASPN cookbook
.
object.__hash__(self)

Called by built-in function
hash()
and for operations on members of
hashed collections including
set
,
frozenset
, and
dict
.  
__hash__()
should return an integer.  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.
由内置函数
hash()
,或者是在可散列集合(hashed collections,包括
set

frozenset

dict
)成员上的操作调用。这个方法应该返回一个整数。只有一个要求,具有相同值的对象应该有相同的散列值。应该考虑以某种方式(例如排斥或)把在对象比较中起作用的部分与散列值关联起来。
If a class does not define an
__eq__()
method it should not define a
__hash__()
operation either; if it defines
__eq__()
but not
__hash__()
, its instances will not be usable as items in hashable
collections.  If a class defines mutable objects and implements an
__eq__()
method, it should not implement
__hash__()
, since the
implementation of hashable collections requires that a key’s hash value is
immutable (if the object’s hash value changes, it will be in the wrong hash
bucket).
如果类没有定义
__eq__()
方法,那么它也不应该定义
__hash__()
方法;如果一个类只定义了
__eq__()
方法,那么它是不适合作散列键的。如果可变对象实现了
__eq__()
方法,它也不应该实现
__hash__()
方法,因为可散列集合要求键值是不可变的(如果对象的散列值发生了改变,它会被放在错误的桶(bucket)中)。
User-defined classes have
__eq__()
and
__hash__()
methods
by default; with them, all objects compare unequal (except with themselves)
and x.__hash__() returns id(x).
所有用户定义类默认都定义了方法
__eq__()

__hash__()
,这样,所有对象都可以进行相等比较(除了与自身比较)。  x.__hash__() 返回 id(x) 。
Classes which inherit a
__hash__()
method from a parent class but
change the meaning of
__eq__()
such that the hash value returned is no
longer appropriate (e.g. by switching to a value-based concept of equality
instead of the default identity based equality) can explicitly flag
themselves as being unhashable by setting __hash__ = None in the class
definition. Doing so means that not only will instances of the class raise an
appropriate
TypeError
when a program attempts to retrieve their hash
value, but they will also be correctly identified as unhashable when checking
isinstance(obj, collections.Hashable) (unlike classes which define their
own
__hash__()
to explicitly raise
TypeError
).
如果子类从父类继承了方法
__hash__()
,但修改了
__eq__()
,这时子类继承的散列值就不再正确了(例如,可能从默认的标识相等的比较切换成了值相等的比较),这时在在类定义时显式地将
__hash__()
设置成 None 就行了。这样,在使用这个子类对象作为散列键时就会抛出
TypeError
异常,或者也可以使用常规的可散列检查 isinstance(obj, collections.Hashable) 确定它的不可散列性(使用这种检查方式时,这种达到不可散列的方法与在
__hash__()
中显式抛出异常的方法是的计算结果就不一样了)。
If a class that overrides
__eq__()
needs to retain the implementation
of
__hash__()
from a parent class, the interpreter must be told this
explicitly by setting __hash__ = .__hash__. Otherwise the
inheritance of
__hash__()
will be blocked, just as if __hash__
had been explicitly set to
None
.
如果子类修改了
__eq__()
方法,但需要保留父类的
__hash__()
,它必须显式地告诉解释器 __hash__ = .__hash__ ,否则
__hash__()
的继承会被阻止,就像设置 __hash__ 为 None 。
object.__bool__(self)

Called to implement truth value testing and the built-in operation
bool(); should return False or True.  When this method is not
defined,
__len__()
is called, if it is defined, and the object is
considered true if its result is nonzero.  If a class defines neither
__len__()
nor
__bool__()
, all its instances are considered
true.
在实现真值测试和内置操作 bool()  中调用,应该返回 False 和 True 。如果没有这个定义方法,转而使用
__len__()
。非零返回值,当作“真”。如果这两个方法都没有定义,就认为该实例为“真”。
3.3.2. 对访问属性的定制(Customizing attribute access)

The following methods can be defined to customize the meaning of attribute
access (use of, assignment to, or deletion of x.name) for class instances.
以下方法可以用于定制访问类实例属性的含义(例如,赋值、或删除 x.name )
object.__getattr__(self, name)

Called when an attribute lookup has not found the attribute in the usual places
(i.e. it is not an instance attribute nor is it found in the class tree for
self).  name is the attribute name. This method should return the
(computed) attribute value or raise an
AttributeError
exception.
在正常方式访问属性无法成功时(就是说,self属性既不是实例的,在类树结构中找不到)使用。 name 是属性名。应该返回一个计算好的属性值,或抛出一个
AttributeError
异常。
Note that if the attribute is found through the normal mechanism,
__getattr__()
is not called.  (This is an intentional asymmetry between
__getattr__()
and
__setattr__()
.) This is done both for efficiency
reasons and because otherwise
__getattr__()
would have no way to access
other attributes of the instance.  Note that at least for instance variables,
you can fake total control by not inserting any values in the instance attribute
dictionary (but instead inserting them in another object).  See the
__getattribute__()
method below for a way to actually get total control
over attribute access.
注意如果属性可以通过正常方法访问,
__getattr__()
是不会被调用的(是有意将
__getattr__()

__setattr__()
设计成不对称的)。这样做的原因是基于效率的考虑,并且这样也不会让
__getattr__()
干涉正常属性。注意,至少对于类实例而言,不必非要更新实例字典伪装属性(但可以将它们插入到其它对象中)。需要全面控制属性访问,可以参考以下
__getattribute__()
的介绍。
object.__getattribute__(self, name)

Called unconditionally to implement attribute accesses for instances of the
class. If the class also defines
__getattr__()
, the latter will not be
called unless
__getattribute__()
either calls it explicitly or raises an
AttributeError
. This method should return the (computed) attribute value
or raise an
AttributeError
exception. In order to avoid infinite
recursion in this method, its implementation should always call the base class
method with the same name to access any attributes it needs, for example,
object.__getattribute__(self, name).
在访问类实例的属性时无条件调用这个方法。如果类也定义了方法
__getattr__()
,那么除非
__getattribute__()
显式地调用了它,或者抛出了
AttributeError
异常,否则它就不会被调用。这个方法应该返回一个计算好的属性值,或者抛出异常  
AttributeError
  。为了避免无穷递归,对于任何它需要访问的属性,这个方法应该调用基类的同名方法,例如, object.__getattribute__(self, name) 。
Note
This method may still be bypassed when looking up special methods as the
result of implicit invocation via language syntax or built-in functions.
See
搜索特殊方法(Special method lookup)
.
但是,通过特定语法或者内置函数,做隐式调用搜索特殊方法时,这个方法可能会被跳过,参见
搜索特殊方法(Special method lookup)

object.__setattr__(self, name, value)

Called when an attribute assignment is attempted.  This is called instead of
the normal mechanism (i.e. store the value in the instance dictionary).
name is the attribute name, value is the value to be assigned to it.
在属性要被赋值时调用。这会替代正常机制(即把值保存在实例字典中)。 name 是属性名, vaule 是要赋的值。
If
__setattr__()
wants to assign to an instance attribute, it should
call the base class method with the same name, for example,
object.__setattr__(self, name, value).
如果在
__setattr__()
里要对一个实例属性赋值,它应该调用父类的同名方法,例如, object.__setattr__(self, name, value) 。
object.__delattr__(self, name)

Like
__setattr__()
but for attribute deletion instead of assignment.  This
should only be implemented if del obj.name is meaningful for the object.

__setattr__()
类似,但它的功能是删除属性。当 del obj.name 对对象有意义时,才需要实现它。
object.__dir__(self)

Called when
dir()
is called on the object.  A list must be returned.
在对象上调用
dir()
时调用,它需要返回一个列表。
3.3.2.1. 实现描述符(Implementing Descriptors)

The following methods only apply when an instance of the class containing the
method (a so-called descriptor class) appears in the class dictionary of
another class, known as the owner class.  In the examples below, “the
attribute” refers to the attribute whose name is the key of the property in the
owner class’ __dict__.
以下方法只能使用在“描述符类”中,“描述子类”的实例出现在其他类(称为“所有者类”)的类字典中,而这个类包括以下方法。在下面的例子里,“属性”专指在所有者类字典中的属性。 【译注:注意是出现所有类的字典中,不是所有类的实例的字典。】
object.__get__(self, instance, owner)

Called to get the attribute of the owner class (class attribute access) or of an
instance of that class (instance attribute access). owner is always the owner
class, while instance is the instance that the attribute was accessed through,
or None when the attribute is accessed through the owner.  This method
should return the (computed) attribute value or raise an
AttributeError
exception.
在获取所有者类属性或实例属性时调用这个方法。 owner 是所有者类, instance 用于访问的所有者类的实例,如果是通过 owner 访问的话,这个参数为 None 。这个方法应该返回一个计算好的属性值,或者抛出异常
AttributeError

object.__set__(self, instance, value)

Called to set the attribute on an instance instance of the owner class to a
new value, value.
在给所有者类的一个实例 instance 设置属性时调用这个方法, value 代表新值。
object.__delete__(self, instance)

Called to delete the attribute on an instance instance of the owner class.
删除所有者类实例 instance 的属性时调用这个方法。
3.3.2.2. 调用描述符(Invoking Descriptors)

In general, a descriptor is an object attribute with “binding behavior”, one
whose attribute access has been overridden by methods in the descriptor
protocol:  
__get__()
,
__set__()
, and
__delete__()
. If any of
those methods are defined for an object, it is said to be a descriptor.
一般来说,描述符就是一个有“绑定行为”的对象属性,这种属性的访问操作会以描述符协议的方式替代,即方法
__get__()

__set__()

__delete__()
。如果一个对象定义了任何以上方法之一,就称它为“描述符”。
The default behavior for attribute access is to get, set, or delete the
attribute from an object’s dictionary. For instance, a.x has a lookup chain
starting with a.__dict__['x'], then type(a).__dict__['x'], and
continuing through the base classes of type(a) excluding metaclasses.
属性访问的默认行为是从对象字典中获取、设置、删除。例如, a.x 会在导致以下的搜索链:先 a.__dict__['x'] 后 type(a).__dict__['x'] ,之后再从 type(a) 的父类中搜索,但不搜索元类(metaclass)。
However, if the looked-up value is an object defining one of the descriptor
methods, then Python may override the default behavior and invoke the descriptor
method instead.  Where this occurs in the precedence chain depends on which
descriptor methods were defined and how they were called.
但是,如果搜索的是一个定义了描述符方法的对象,Python会放弃默认方案转而调用描述符方法。调用在以上搜索链上的位置取决于定义了什么描述符方法及调用方式的。
The starting point for descriptor invocation is a binding, a.x. How the
arguments are assembled depends on a:
描述符调用始于“绑定”, a.x ,方法参数的组织取决于 a :
Direct CallThe simplest and least common call is when user code directly invokes a
descriptor method:    x.__get__(a).
直接调用。这是最简单但也是最不常用的方法,用户直接调用一个描述符方法,例如 x.__get__(a) 。
Instance BindingIf binding to an object instance, a.x is transformed into the call:
type(a).__dict__['x'].__get__(a, type(a)).
实例绑定。如果与实例绑定, a.x 会转换为以下调用:  type(a).__dict__['x'].__get__(a, type(a)) 。
Class BindingIf binding to a class, A.x is transformed into the call:
A.__dict__['x'].__get__(None, A).
类绑定。如果与类绑定, A.x 会转换为以下调用: A.__dict__['x'].__get__(None, A) 。
Super BindingIf a is an instance of
super
, then the binding super(B,
obj).m() searches obj.__class__.__mro__ for the base class A
immediately preceding B and then invokes the descriptor with the call:
A.__dict__['m'].__get__(obj, A).
超级绑定。如果 a 是类
super
的一个实例,那么绑定 super(B, obj).m() 会在 obj.__class__.__mro__ 里直接搜索基类 A ,而不是先搜索  B ,并调用 A.__dict__['m'].__get__(obj, A) 。
For instance bindings, the precedence of descriptor invocation depends on the
which descriptor methods are defined.  Normally, data descriptors define both
__get__()
and
__set__()
, while non-data descriptors have just the
__get__()
method.  Data descriptors always override a redefinition in an
instance dictionary.  In contrast, non-data descriptors can be overridden by
instances.
[2]
对于实例绑定,描述符调用的优先顺序依赖于定义了什么描述符方法。正常情况下,数据描述符会定义两个方法
__get__()

__set__()
,而非数据描述符只会定义
__get__()
。数据描述符不会被实例的字典重写破坏,而非数据描述符可以因为重写实例字典而失效。[2]
Python methods (including
staticmethod()
and
classmethod()
) are
implemented as non-data descriptors.  Accordingly, instances can redefine and
override methods.  This allows individual instances to acquire behaviors that
differ from other instances of the same class.
Python方法(包括
staticmethod()

classmethod()
)是以非数据描述符实现的。因此,实例可以重新定义或者说覆盖方法。这允许同一个类的不同实例可以有不同的行为。
The
property()
function is implemented as a data descriptor. Accordingly,
instances cannot override the behavior of a property.
函数
property()
是用数据描述符实现的,因此,实例不能覆写特性(property)的行为。
3.3.2.3. __slots__

By default, instances of classes have a dictionary for attribute storage.  This
wastes space for objects having very few instance variables.  The space
consumption can become acute when creating large numbers of instances.
默认情况下,类实例使用字典管理属性。在对象只有少量实例变量时这就会占用不少空间,当有大量实例时,空间消耗会变得更为严重。
The default can be overridden by defining __slots__ in a class definition.
The __slots__ declaration takes a sequence of instance variables and reserves
just enough space in each instance to hold a value for each variable.  Space is
saved because __dict__ is not created for each instance.
这个默认行为可以通过在类定义中定义 __slots__ 修改。 __slots__ 声明只为该类的所有实例预留刚刚够用的空间。因为不会为每个实例创建 __dict__ ,因此空间节省下来了。
object.__slots__

This class variable can be assigned a string, iterable, or sequence of
strings with variable names used by instances.  If defined in a
class, __slots__ reserves space for the declared variables and prevents the
automatic creation of __dict__ and __weakref__ for each instance.
这个类变量可以赋值为一个字符串,一个可迭代对象,或者一个字符串序列(每个字符串表示实例所用的变量名)。如果定义了 __slots__ ,Python就会为实例预留出存储声明变量的空间,并且不会为每个实例自动创建 __dict__ 和 __weakref__ 。
3.3.2.3.1. 使用 __slots__ 的注意事项(Notes on using __slots__ )

  • When inheriting from a class without __slots__, the __dict__ attribute of
    that class will always be accessible, so a __slots__ definition in the
    subclass is meaningless.
    如果从一个没有定义 __slots__ 的基类继承,子类一定存在 __dict__ 属性。所以,在这种子类中定义 __slots__ 是没有意义的。
  • Without a __dict__ variable, instances cannot be assigned new variables not
    listed in the __slots__ definition.  Attempts to assign to an unlisted
    variable name raises
    AttributeError
    . If dynamic assignment of new
    variables is desired, then add '__dict__' to the sequence of strings in
    the __slots__ declaration.
    没有定义 __dict__ 的实例不支持对不在 __slot__ 中的属性赋值。如果需要支持这个功能,可以把 '__dict__' 放到 __slots__ 声明中。
  • Without a __weakref__ variable for each instance, classes defining
    __slots__ do not support weak references to its instances. If weak reference
    support is needed, then add '__weakref__' to the sequence of strings in the
    __slots__ declaration.
    没有定义 __weakref__ 的,使用 __slot__ 的实例不支持对它的“弱引用”。如果需要支持弱引用,可以把 '__weakref__' 放到 __slots__ 声明中。
  • __slots__ are implemented at the class level by creating descriptors
    (
    实现描述符(Implementing Descriptors)
    ) for each variable name.  As a result, class attributes
    cannot be used to set default values for instance variables defined by
    __slots__; otherwise, the class attribute would overwrite the descriptor
    assignment.
    __slots__ 是在类这一级实现的,通过为每个实例创建描述符(
    实现描述符(Implementing Descriptors)
    )。因此,不能使用类属性为实例的 __slots__ 中定义的属性设置默认值 。否则,类属性会覆盖描述符的赋值操作。
  • If a class defines a slot also defined in a base class, the instance variable
    defined by the base class slot is inaccessible (except by retrieving its
    descriptor directly from the base class). This renders the meaning of the
    program undefined.  In the future, a check may be added to prevent this.
    如果类定义的slot与父类中的相同,那么父类slot中的变量将成为不可访问的(除非直接从基类中获取描述符)。这使得程序行为变得有一点模糊,以后可能会增加一个防止出现这种情况的检查。
  • The action of a __slots__ declaration is limited to the class where it is
    defined.  As a result, subclasses will have a __dict__ unless they also define
    __slots__.
    __slots__ 声明的行为只限于其定义所在的类。因此,子类仍然会使用 __dict__ (如果它没有定义自己的 __slots__ 的话)。
  • Nonempty __slots__ does not work for classes derived from “variable-length”
    built-in types such as
    int
    ,
    str
    and
    tuple
    .
    从”变长”内置类型,例如
    int

    str

    tuple
    继承的子类的非空 __slots__ 不会起作用。
  • Any non-string iterable may be assigned to __slots__. Mappings may also be
    used; however, in the future, special meaning may be assigned to the values
    corresponding to each key.
    任何非字符串可迭代对象都可以赋给 __slots__ 。映射类型也是允许的,但是,以后版本的Python可能给“键”赋予特殊意义。
  • __class__ assignment works only if both classes have the same __slots__.
    只有在两个类的 __slots__ 相同时, __class__ 赋值才会正常工作。

3.3.3. 类创建的定制(Customizing class creation)

By default, classes are constructed using
type()
. A class definition is
read into a separate namespace and the value of class name is bound to the
result of type(name, bases, dict).
默认情况下,类是由
type()
构造的。类的定义会读入一个独立的名字空间,并且类名称的值会与  type(name, bases, dict) 的返回结果绑定。
When the class definition is read, if a callable metaclass keyword argument
is passed after the bases in the class definition, the callable given will be
called instead of
type()
.  If other keyword arguments are passed, they
will also be passed to the metaclass.  This allows classes or functions to be
written which monitor or alter the class creation process:
在读取类定义时,如果在基类名之后给出了可调用类型的关键字参数 metaclass (元类),这时就不再调用
type()
转而使用这个可调用对象。如果有其它关键字参数,它们也会传递给 metaclass 。这就允许我们使用类或者函数来监视或修改类创建过程:
  • Modifying the class dictionary prior to the class being created.
    在类创建之前修改类的字典。
  • Returning an instance of another class – essentially performing the role of a
    factory function.
    返回其它类的实例 – 基本上这里执行的就是工厂方法。

These steps will have to be performed in the metaclass’s
__new__()
method
– type.__new__() can then be called from this method to create a class
with different properties.  This example adds a new element to the class
dictionary before creating the class:
以上步骤必须在元类的
__new__()
方法内完成 – 然后从这个方法中调用 type.__new__() 创建具有不同特性(properties)的新类。 下面的例子会在创建类之前在类字典中增加一个新元素
class metacls(type):
    def __new__(mcs, name, bases, dict):
        dict['foo'] = 'metacls was here'
        return type.__new__(mcs, name, bases, dict)
You can of course also override other class methods (or add new methods); for
example defining a custom
__call__()
method in the metaclass allows custom
behavior when the class is called, e.g. not always creating a new instance.
你当然也可以覆盖其它类方法(或是增加新方法),例如,在元类中定制
__call__()
方法就可以控制类在调用时的行为,例如,不会每次调用都返回一个实例。
If the metaclass has a __prepare__() attribute (usually implemented as a
class or static method), it is called before the class body is evaluated with
the name of the class and a tuple of its bases for arguments.  It should return
an object that supports the mapping interface that will be used to store the
namespace of the class.  The default is a plain dictionary.  This could be used,
for example, to keep track of the order that class attributes are declared in by
returning an ordered dictionary.
如果元类具有 __prepare__() 属性(一般是用类或者静态方法实现的),它会在对类定义体(结合类名、父类和参数)估值之前调用。这个方法应该返回一个支持映射接口的对象,这个对象用于存储类的名字空间。默认是一个普通字典。例如,可以通过返回一个有序字典跟踪类属性的声明顺序。
The appropriate metaclass is determined by the following precedence rules:
使用的元类是按以下优先顺序确定的:
  • If the metaclass keyword argument is based with the bases, it is used.
    如果有在基类位置上使用 metaclass 关键字参数,就使用它。
  • Otherwise, if there is at least one base class, its metaclass is used.
    否则,如果至少有一个基类,就用基类的元类。
  • Otherwise, the default metaclass (
    type
    ) is used.
    否则,使用默认元类
    type


The potential uses for metaclasses are boundless. Some ideas that have been
explored including logging, interface checking, automatic delegation, automatic
property creation, proxies, frameworks, and automatic resource
locking/synchronization.
元类的用途非常广泛,目前已知的用法有记录日志、接口检查、自动委托、特性(property)自动创建、代理、框架、自动资源锁定及同步。
Here is an example of a metaclass that uses an
collections.OrderedDict
to remember the order that class members were defined:
这里是一个使用
collections.OrderedDict
的元类例子,它可以记住类成员的定义顺序
class OrderedClass(type):
     @classmethod
     def __prepare__(metacls, name, bases, **kwds):
        return collections.OrderedDict()
     def __new__(cls, name, bases, classdict):
        result = type.__new__(cls, name, bases, dict(classdict))
        result.members = tuple(classdict)
        return result
class A(metaclass=OrderedClass):
    def one(self): pass
    def two(self): pass
    def three(self): pass
    def four(self): pass
>>> A.members
('__module__', 'one', 'two', 'three', 'four')
When the class definition for A gets executed, the process begins with
calling the metaclass’s __prepare__() method which returns an empty
collections.OrderedDict
.  That mapping records the methods and
attributes of A as they are defined within the body of the class statement.
Once those definitions are executed, the ordered dictionary is fully populated
and the metaclass’s
__new__()
method gets invoked.  That method builds
the new type and it saves the ordered dictionary keys in an attribute
called members.
在类定义 A 执行时,进程开始于调用元类的 __prepare__() 方法并返回一个空
collections.OrderedDict
,这个映射会记录在 class 语句中定义的 A 的方法和属性。一旦执行完这个定义,有序字典就完全设置好了,并调用元类的
__new__()
方法,这个方法会创建新的类型,并把这个有序字典的键保存在属性 members 中。
               
               
               
               
               

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

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP