() vs. [] operator

Chris Rebert clp2 at rebertia.com
Thu Oct 15 09:54:02 CEST 2009


On Thu, Oct 15, 2009 at 12:14 AM, Ole Streicher <ole-usenet-spam at gmx.net> wrote:
> Hi,
>
> I am curious when one should implement a "__call__()" and when a
> "__getitem__()" method.
>
> For example, I want to display functions and data in the same plot. For
> a function, the natural interface would to be called as "f(x)", while
> the natural interface for data would be "f[x]". On the other hand,
> whether a certain data object is a function or a data table is just an
> inner detail of the object (imagine f.e. a complex function that
> contains a data table as cache), and there is no reason to distinguish
> them by interface.
>
> So what is the reason that Python has separate __call__()/() and
> __getitem__()/[] interfaces and what is the rule to choose between them?

Because it'd seem somewhat weird to "call" a container (e.g.
list/dict) as if it were a function, in order to subscript it. And,
like many things, the syntax/distinction is inherited from C.
Also, I'm not entirely sure on this, but I don't believe subscripting
allows for the full function call syntax (with e.g. keyword
parameters, etc).
Further, subscripting generally implies the related notion of
keys/indices and values, whereas callables carry no such association.

So that's why there's both.

Personally, I'd say you should choose subscripting if the notion of
"keys" and "values" makes sense in whatever your use case is, and call
syntax if the notion of "operation that performs work/computation" or
"non-simple query" is more applicable, especially if side-effects are
involved; subscripting is generally for fairly cheap operations, call
syntax for non-generally-cheap ones.
In the particular example you gave, I'd favor call syntax because it
ties more strongly to the notion of functions, whereas subscripting
lightly implies the data-table representation, which you rightly point
out should probably be an implementation detail.

However, there's absolutely nothing stopping you from implementing
both __call__ and __getitem__ and just having them do the same thing,
so that's also an option (though the redundancy isn't satisfying from
an aesthetic point of view).

Cheers,
Chris
--
http://blog.rebertia.com



More information about the Python-list mailing list