Cleared up the XXX comments I added earlier today, and fixed some
additional typos.
This commit is contained in:
parent
5b6409adaf
commit
1264fe2202
112
pep-0307.txt
112
pep-0307.txt
|
@ -183,8 +183,8 @@ Extended __reduce__ API
|
|||
|
||||
Unpickling invokes function(*arguments) to create an initial object,
|
||||
called obj below. If the remaining items are left off, that's the end
|
||||
of unpickling and obj is the result. Else obj is modified at
|
||||
unpickling time by each item specified, as follows.
|
||||
of unpickling for this object and obj is the result. Else obj is
|
||||
modified at unpickling time by each item specified, as follows.
|
||||
|
||||
state Optional.
|
||||
Additional state. If this is not None, the state is
|
||||
|
@ -367,12 +367,12 @@ Case 2: pickling new-style class instances using protocols 0 or 1
|
|||
name in that module) is substituted.
|
||||
|
||||
The default __reduce__ implementation will fail at pickling time
|
||||
for built-in types not mentioned above.
|
||||
for built-in types not mentioned above, and for new-style classes
|
||||
implemented in C: if they want to be picklable, they must supply
|
||||
a custom __reduce__ implementation under protocols 0 and 1.
|
||||
|
||||
For new-style classes implemented in Python, the default
|
||||
__reduce__ implementation works as follows:
|
||||
XXX We seem to be missing a section for new-style classes implemented
|
||||
XXX in C.
|
||||
__reduce__ implementation (copy_reg._reduce) works as follows:
|
||||
|
||||
Let D be the class on the object to be pickled. First, find the
|
||||
nearest base class that is implemented in C (either as a
|
||||
|
@ -384,38 +384,49 @@ Case 2: pickling new-style class instances using protocols 0 or 1
|
|||
__reduce__ implementation. B must not be the same class as D
|
||||
(if it were, it would mean that D is not implemented in Python).
|
||||
|
||||
The new object is created at unpickling time using the following
|
||||
code:
|
||||
The callable produced by the default __reduce__ is
|
||||
copy_reg._reconstructor, and its arguments tuple is
|
||||
(D, B, basestate), where basestate is None if B is the builtin
|
||||
object class, and basestate is
|
||||
|
||||
obj = B.__new__(D, state)
|
||||
B.__init__(obj, state)
|
||||
basestate = B(obj)
|
||||
|
||||
where state is a value computed at pickling time as follows:
|
||||
if B is not the builtin object class. This is geared toward
|
||||
pickling subclasses of builtin types, where, for example,
|
||||
list(some_list_subclass_instance) produces "the list part" of
|
||||
the list subclass instance.
|
||||
|
||||
state = B(obj)
|
||||
The object is recreated at unpickling time by
|
||||
copy_reg._reconstructor, like so:
|
||||
|
||||
XXX How does the above relate to the steps explained earlier for
|
||||
XXX __reduce__? For example, what here corresponds to the earlier
|
||||
XXX description's function(*arguments) step?
|
||||
obj = B.__new__(D, basestate)
|
||||
B.__init__(obj, basestate)
|
||||
|
||||
XXX Below, does __getstate__() customization replace the source of
|
||||
XXX the value called "state" just above, or is this customization a
|
||||
XXX distinct step?
|
||||
Objects for which this default __reduce__ implementation is used
|
||||
can customize it by defining __getstate__ and/or __setstate__
|
||||
methods. These work almost the same as described for classic
|
||||
classes above, except that if __getstate__ returns an object (of
|
||||
any type) whose value is considered false (e.g. None, or a number
|
||||
that is zero, or an empty sequence or mapping), this state is not
|
||||
pickled and __setstate__ will not be called at all.
|
||||
Objects using the default __reduce__ implementation can customize
|
||||
it by defining __getstate__ and/or __setstate__ methods. These
|
||||
work almost the same as described for classic classes above, except
|
||||
that if __getstate__ returns an object (of any type) whose value is
|
||||
considered false (e.g. None, or a number that is zero, or an empty
|
||||
sequence or mapping), this state is not pickled and __setstate__
|
||||
will not be called at all. If __getstate__ exists and returns a
|
||||
true value, that value becomes the third element of the tuple
|
||||
returned by the default __reduce__, and at unpickling time the
|
||||
value is passed to __setstate__. If __getstate__ does not exist,
|
||||
but obj.__dict__ exists, then obj.__dict__ becomes the third
|
||||
element of the tuple returned by __reduce__, and again at
|
||||
unpickling time the value is passed to obj.__setstate__. The
|
||||
default __setstate__ is the same as that for classic classes,
|
||||
described above.
|
||||
|
||||
Note that this strategy ignores slots. Instances of new-style
|
||||
classes that have slots but no __getstate__ method cannot be
|
||||
pickled by protocols 0 and 1; the code explicitly checks for
|
||||
this condition.
|
||||
|
||||
XXX Is it the case that "pickling new-style class instances using
|
||||
XXX protocols 0 or 1" ignores __getinitargs__?
|
||||
Note that pickling new-style class instances ignores __getinitargs__
|
||||
if it exists (and under all protocols). __getinitargs__ is
|
||||
useful only for classic classes.
|
||||
|
||||
|
||||
Case 3: pickling new-style class instances using protocol 2
|
||||
|
||||
|
@ -423,12 +434,15 @@ Case 3: pickling new-style class instances using protocol 2
|
|||
from the 'object' base class is *ignored*. Instead, a different
|
||||
default implementation is used, which allows more efficient
|
||||
pickling of new-style class instances than possible with protocols
|
||||
0 or 1, at the cost of backward incompatibility with Python 2.2.
|
||||
0 or 1, at the cost of backward incompatibility with Python 2.2
|
||||
(meaning no more than that a protocol 2 pickle cannot be unpickled
|
||||
before Python 2.3).
|
||||
|
||||
The customization uses three special methods: __getstate__,
|
||||
__setstate__ and __getnewargs__. It is fine if a class implements
|
||||
one or more but not all of these, as long as it is compatible with
|
||||
the default implementations.
|
||||
__setstate__ and __getnewargs__ (note that __getinitargs__ is again
|
||||
ignored). It is fine if a class implements one or more but not all
|
||||
of these, as long as it is compatible with the default
|
||||
implementations.
|
||||
|
||||
The __getstate__ method
|
||||
|
||||
|
@ -443,20 +457,20 @@ Case 3: pickling new-style class instances using protocol 2
|
|||
But if a new-style class's __getstate__ returns None, its
|
||||
__setstate__ won't be called at all as part of unpickling.
|
||||
|
||||
If no __getstate__ method exists, a default state is assumed.
|
||||
If no __getstate__ method exists, a default state is computed.
|
||||
There are several cases:
|
||||
|
||||
- For a new-style class that has no instance __dict__ and no
|
||||
__slots__, the default state is None.
|
||||
|
||||
- For a new-style class that has an instance __dict__ and no
|
||||
__slots__, the default state is self.__dict__.
|
||||
|
||||
- For a new-style class that has no instance __dict__ and no
|
||||
__slots__, the default __state__ is None.
|
||||
|
||||
- For a new-style class that has an instance __dict__ and
|
||||
__slots__, the default state is a tuple consisting of two
|
||||
dictionaries: the first being self.__dict__, and the second
|
||||
being a dictionary mapping slot names to slot values. Only
|
||||
slots that have a value are included in the latter.
|
||||
dictionaries: self.__dict__, and a dictionary mapping slot
|
||||
names to slot values. Only slots that have a value are
|
||||
included in the latter.
|
||||
|
||||
- For a new-style class that has __slots__ and no instance
|
||||
__dict__, the default state is a tuple whose first item is
|
||||
|
@ -465,9 +479,10 @@ Case 3: pickling new-style class instances using protocol 2
|
|||
|
||||
The __setstate__ method
|
||||
|
||||
The __setstate__ should take one argument; it will be called
|
||||
with the value returned by __getstate__ or with the default
|
||||
state described above if no __setstate__ method is defined.
|
||||
The __setstate__ method should take one argument; it will be
|
||||
called with the value returned by __getstate__ or with the
|
||||
default state described above if no __getstate__ method is
|
||||
defined.
|
||||
|
||||
If no __setstate__ method exists, a default implementation is
|
||||
provided that can handle the state returned by the default
|
||||
|
@ -484,10 +499,11 @@ Case 3: pickling new-style class instances using protocol 2
|
|||
|
||||
obj = C.__new__(C, *args)
|
||||
|
||||
where args is either the empty tuple, or the tuple returned by
|
||||
the __getnewargs__ method, if defined. __getnewargs__ must
|
||||
return a tuple. The absence of a __getnewargs__ method is
|
||||
equivalent to the existence of one that returns ().
|
||||
where C is the class of the pickled object, and args is either
|
||||
the empty tuple, or the tuple returned by the __getnewargs__
|
||||
method, if defined. __getnewargs__ must return a tuple. The
|
||||
absence of a __getnewargs__ method is equivalent to the existence
|
||||
of one that returns ().
|
||||
|
||||
|
||||
The __newobj__ unpickling function
|
||||
|
@ -672,7 +688,7 @@ The copy module
|
|||
Pickling Python longs
|
||||
|
||||
Pickling and unpickling Python longs takes time quadratic in
|
||||
the number of digits, in protocols 1 and 2. Under protocol 2,
|
||||
the number of digits, in protocols 0 and 1. Under protocol 2,
|
||||
new opcodes support linear-time pickling and unpickling of longs.
|
||||
|
||||
|
||||
|
@ -681,7 +697,9 @@ Pickling bools
|
|||
Protocol 2 introduces new opcodes for pickling True and False
|
||||
directly. Under protocols 0 and 1, bools are pickled as integers,
|
||||
using a trick in the representation of the integer in the pickle
|
||||
so that an unpickler can recognize that a bool was intended.
|
||||
so that an unpickler can recognize that a bool was intended. That
|
||||
trick consumed 4 bytes per bool pickled. The new bool opcodes
|
||||
consume 1 byte per bool.
|
||||
|
||||
|
||||
Pickling small tuples
|
||||
|
|
Loading…
Reference in New Issue