python class behaves like dictionary-or-list-data-like
<p>In python3 console, input those:</p>

<pre><code>&gt;&gt;&gt; import sys
&gt;&gt;&gt; sys.version_info
sys.version_info(major=3, minor=4, micro=3, releaselevel='final', serial=0)
&gt;&gt;&gt; type(sys.version_info)  # this is class type
&lt;class 'sys.version_info'&gt;
&gt;&gt;&gt; sys.version_info[0:2]  # ?? But it acts like a list-data-like
(3, 4)
</code></pre>

<p>My questions are:</p>

<ol>
<li>How can a class act like dictionary-or-list-data-like? </li>
<li>May give an example to construct a class like this? </li>
<li>Is there some documentation about
this?</li>
</ol>

<p>It's quite easy ... All you need to do is define a <code>__getitem__</code> method that handles slicing or integer/string lookup.  You can do pretty much whatever you want...</p>

<pre><code>class Foo(object):
    def __init__(self, bar, baz):
        self.bar = bar
        self.baz = baz
    def __getitem__(self, ix):
        return (self.bar, self.baz).__getitem__(ix)
</code></pre>

<p>Here's a cheat sheet of what will be passed to <code>__getitem__</code> as <code>ix</code> in the following situations:</p>

<pre><code>f[1]  # f.__getitem__(1)
f[1:]  # f.__getitem__(slice(1, None, None))
f[1:, 2]  # f.__getitem__( (slice(1, None, None), 2) )
f[1, 2]  # f.__getitem__( (1, 2) )
f[(1, 2)]  # f.__getitem__( (1, 2) )
</code></pre>

<p>The trick (which can be slightly non-trivial) is simply writing <code>__getitem__</code> so that it looks at the type of the object that was passed and then does the right thing.  For my answer, I cheated by creating a <code>tuple</code> in my <code>__getitem__</code> and then I called <code>__getitem__</code> on the tuple (since it already does the right thing in all of the cases that I wanted to support)</p>

<p>Here's some example usage:</p>

<pre><code>&gt;&gt;&gt; f = Foo(1, 2)
&gt;&gt;&gt; f[1]
2
&gt;&gt;&gt; f[0]
1
&gt;&gt;&gt; f[:]
(1, 2)
</code></pre>

<p>note that you don't <em>typically</em> need to even do this yourself.  You can create a <a href="https://docs.python.org/2/library/collections.html#collections.namedtuple" rel="nofollow">named tuple</a> to do the job for you:</p>

<pre><code>from collections import namedtuple
Foo = namedtuple('Foo', 'bar, baz')
</code></pre>

<p>And usage is pretty much the same:</p>

<pre><code>&gt;&gt;&gt; f = Foo(1, 2)
&gt;&gt;&gt; f[1]
2
&gt;&gt;&gt; f[0]
1
&gt;&gt;&gt; f[:]
(1, 2)
</code></pre>

<p>The main difference here is that our namedtuple is immutable.  Once created, we can't change it's members.</p>

python list class dictionary