Problem of Readability of Python

Alex Martelli aleax at mac.com
Sun Oct 7 19:58:45 EDT 2007


Steven D'Aprano <steve at REMOVE-THIS-cybersource.com.au> wrote:

> On Sun, 07 Oct 2007 13:24:14 -0700, Alex Martelli wrote:
> 
> > And yes, you CAN save about 1/3 of those 85 nanoseconds by having
> > '__slots__=["zop"]' in your class A(object)... but that's the kind of
> > thing one normally does only to tiny parts of one's program that have
> > been identified by profiling as dramatic bottlenecks
> 
> Seems to me that:
> 
> class Record(object):
>     __slots__ = ["x", "y", "z"]
> 
> 
> has a couple of major advantages over:
> 
> class Record(object):
>     pass
> 
> 
> aside from the micro-optimization that classes using __slots__ are faster
> and smaller than classes with __dict__.
> 
> (1) The field names are explicit and self-documenting;
> (2) You can't accidentally assign to a mistyped field name without Python
> letting you know immediately.
> 
> 
> Maybe it's the old Pascal programmer in me coming out, but I think 
> they're big advantages.

I'm also an old Pascal programmer (ask anybody who was at IBM in the
'80s who was the most active poster on the TURBO FORUM about Turbo
Pascal, and PASCALVS FORUM about Pascal/Vs...), and yet I consider these
"advantages" to be trivial in most cases compared to the loss in
flexibility, such as the inability to pickle (without bothering to code
an explicit __getstate__) and the inability to "monkey-patch" instances
on the fly -- not to mention the bother of defining a separate 'Record'
class for each and every combination of attributes you might want to put
together.

If you REALLY pine for Pascal's records, you might choose to inherit
from ctypes.Structure, which has the additional "advantages" of
specifying a C type for each field and (a real advantage;-) creating an
appropriate __init__ method.

>>> import ctypes
>>> class Record(ctypes.Structure):
...  _fields_ =
(('x',ctypes.c_float),('y',ctypes.c_float),('z',ctypes.c_float)
)
... 
>>> r=Record()
>>> r.x
0.0
>>> r=Record(1,2,3)
>>> r.x
1.0
>>> r=Record('zip','zop','zap')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError:  float expected instead of str instance

See?  You get type-checking too -- Pascal looms closer and closer!-)

And if you need an array of 1000 such Records, just use as the type
Record*1000 -- think of the savings in memory (no indirectness, no
overallocations as lists may have...).

If I had any real need for such things, I'd probably use a metaclass (or
class decorator) to also add a nice __repr__ function, etc...


Alex



More information about the Python-list mailing list