[Python-Dev] __getitem__ & slice question

Tim Peters tim.one@comcast.net
Fri, 15 Mar 2002 01:47:42 -0500


[Skip Montanaro]
> I checked in what I thought was a fix for calendar.py and
> test_calendar.py, then realized it didn't handle slices.

Why does that matter?  calendar.__all__ doesn't export _localized_name or
any of the gimmicks built from it, so it's purely an internal issue, and the
internals never need slices here (granted that day_name etc are poorly named
for module privates -- or perhaps the __all__ list and the docs are in
error).

> I've never dealt with __getitem__ and slices before.  Would someone try
> out this modified version of calendar._localized_name and let me know
> what I'm doing wrong?
>
>     class _localized_name:
>         def __init__(self, format, len):
>             self.data = []
>             for i in range(len):
>                 self.data.append(strftime(format, (i,)*9).capitalize())
>             # months are one-based - match 2.1 behavior
>             if format == '%b':
>                 self.data[0] = "   "
>             elif format == '%B':
>                 self.data[0] = ""

Now this changes the current semantics in a major way:  if you're going to
precompute all the values, construct plain tuples instead and be done with
it.  I assume that whoever patched this to begin with deliberately
recomputed localized values on each dynamic reference so that they would
respond appropriately to dynamic locale changes.

>         def __getitem__(self, item):
>             if type(item) is types.SliceType:
>                 return self.data[item.start:item.stop]
>             return self.data[item]
>
>         def __len__(self):
>             return len(self.data)
>
> For example, try something like
>
>     calendar.month_abbr[-20:]
>
> Also, should I worry about the slice's step attribute?

To both, I don't think you should be changing this code to do static
precomputation at all.  But, if we must, toss the class and build plain
tuples instead, e.g.

day_name = tuple([strftime('%A', (i,)*9) for i in range(7)])

In the static case, trying to build a class that emulates a tuple is
pointless.