__init__ method for containers

N

Neil Cerutti

List and deque disagree on what __init__ does. Which one is
right?

Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
from collections import deque
x = deque([0, 1])
x.__init__([2, 3])
x deque([0, 1, 2, 3])
y = list([0, 1])
y.__init__([2, 3])
y
[2, 3]

test_deque.py even contains a test verifying its __init__
behavior, so perhaps deque has a good reason to differ from the
behavior of list.

Moreover, both methods use the same doc string, i.e.:

__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature

When implementing a list-like container extension type, is there
any reason to choose anything other than list-like behavior,
i.e., if you call __init__, you'll initialize the container?
deque's behavior doesn't make sense to me.
 
C

Calvin Spealman

I agree that the behavior should be more consistant, but you also
should not be calling __init__ more than once on any given instance
and that in and of itself should probably constitute undefined behavior.

List and deque disagree on what __init__ does. Which one is
right?

Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit
(Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
from collections import deque
x = deque([0, 1])
x.__init__([2, 3])
x deque([0, 1, 2, 3])
y = list([0, 1])
y.__init__([2, 3])
y
[2, 3]

test_deque.py even contains a test verifying its __init__
behavior, so perhaps deque has a good reason to differ from the
behavior of list.

Moreover, both methods use the same doc string, i.e.:

__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for
signature

When implementing a list-like container extension type, is there
any reason to choose anything other than list-like behavior,
i.e., if you call __init__, you'll initialize the container?
deque's behavior doesn't make sense to me.

--
Neil Cerutti
One of the causes of the American Revolution was the English put
tacks in
their tea. --History Exam Blooper
 
N

Neil Cerutti

I agree that the behavior should be more consistant, but you
also should not be calling __init__ more than once on any
given instance and that in and of itself should probably
constitute undefined behavior.

That seems wise to me, too, but the the explicit __init__ test in
test_deque seems to argue otherwise. Maybe the test in error.

Moreover, the behavior of deque.__init__ may actually contradict
its doc string.
Help on wrapper_descriptor:

__init__(...)
x.__init__(...) initializes x; see x.__class__.__doc__ for signature
 
C

Calvin Spealman

That seems wise to me, too, but the the explicit __init__ test in
test_deque seems to argue otherwise. Maybe the test in error.

Moreover, the behavior of deque.__init__ may actually contradict
its doc string.

It documents that deque.__init__ initializes it, as all __init__
methods do. All init methods are also assumed to _only_ be called at
the start of the life of the object and never more than once, so
breaking that breaks assumption and thus the documentation isn't
wrong because you are trying to apply it to a state that shouldn't
exist. This like saying saying claims of cigarettes causing cancer
are false if you shoot someone before they get the cancer. Well, you
aren't supposed to shoot people, so that doesn't count.
 
R

Raymond Hettinger

It documents that deque.__init__ initializes it, as all __init__
methods do. All init methods are also assumed to _only_ be called at
the start of the life of the object and never more than once, so
breaking that breaks assumption and thus the documentation isn't
wrong because you are trying to apply it to a state that shouldn't
exist.

That's overstating the case somewhat. The init methods are
*typically* called only once but they are not *assumed* to be called
only once. They are in-fact just like any other method except that
their first invocation is automatic. The clear and re-initialize
behavior of __init__ for lists is evidence. If list.__init__ was
assumed to be called only once, there would be no need for the step
that clears-out previous values.

Also, it is not obvious what the "right" behavior is. While
list.__init__ clears previous values, dict.__init__ does not.

In the case of deque.__init__, the lack of clearing behavior is a bug
because the API aspires to mimic lists as much as possible.


Raymond
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top