__getitem__ and classmethod/staticmethod

Andrew Bennetts andrew-pythonlist at puzzling.org
Fri Jun 25 14:00:37 EDT 2004


On Fri, Jun 25, 2004 at 10:18:53AM -0700, Karl Chen wrote:
> 
> Hi.  
> 
> Is it possible to make a classmethod out of __getitem__?
> 
> I.e. I want to do:
> 
> class C:
>     def __getitem__(p):
>         return 1+p
> 
>     __getitem__ = classmethod(__getitem__)
> 
> So that C[3] works (in addition to C()[3]).  But I always get 
>     TypeError: unsubscriptable object

(You seem to be confusing classmethod and staticmethod, but I'm guessing
that's just a typo in your definition of __getitem__)

The problem is that a __getitem__ in a class's __dict__ has nothing to do
with the operators defined on that class.

To define the __getitem__ operator on a class object, you need to define it
on the class's class, i.e. its metaclass;

>>> class SubscriptableType(type):
...     def __getitem__(self, x):
...         return x+1
... 
>>> class C(object):
...     __metaclass__ = SubscriptableType
...    
>>> C[3]
4

Of course, this doesn't define it for instances of C:

>>> C()[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: unindexable object

So to do both you'd have to do something like:

>>> class C(object):
...     __metaclass__ = SubscriptableType
...     def __getitem__(x):
...         return x+1
...     __getitem__ = staticmethod(__getitem__)
... 
>>> C[3]
4
>>> C()[3]
4

To avoid redefining the same method twice, you could something like this:

    def getitem(x):
        return x + 1
    
    class SubscriptableType(type):
        __getitem__ = staticmethod(getitem)
    
    class C(object):
        __metaclass__ = SubscriptableType
        __getitem__ = staticmethod(getitem)

-Andrew.





More information about the Python-list mailing list