From: kj on
In <mailman.1018.1269125666.23598.python-list(a)python.org> Chris Rebert <clp2(a)rebertia.com> writes:

>On Sat, Mar 20, 2010 at 3:15 PM, kj <no.email(a)please.post> wrote:
>> I need to create a class solely for the purpose of encapsulating
>> a large number of disparate data items. =C2=A0At the moment I have no
>> plans for any methods for this class other than the bazillion
>> accessors required to access these various instance variables.
>> (In case it matters, this class is meant to be a private helper
>> class internal to a module, and it won't be subclassed.)

>If it's just a completely dumb struct-like class, you might consider
>something like:
>http://docs.python.org/library/collections.html#collections.namedtuple

Very cool. Thanks! The class I have in mind is *almost* that
dumb, but performance is a consideration in this case, which may
rule out namedtuple. But I'm glad to learn about it; there are
many places where I can put them to good use.

~K
From: Steve Holden on
kj wrote:
> In <mailman.1018.1269125666.23598.python-list(a)python.org> Chris Rebert <clp2(a)rebertia.com> writes:
>
>> On Sat, Mar 20, 2010 at 3:15 PM, kj <no.email(a)please.post> wrote:
>>> I need to create a class solely for the purpose of encapsulating
>>> a large number of disparate data items. =C2=A0At the moment I have no
>>> plans for any methods for this class other than the bazillion
>>> accessors required to access these various instance variables.
>>> (In case it matters, this class is meant to be a private helper
>>> class internal to a module, and it won't be subclassed.)
>
>> If it's just a completely dumb struct-like class, you might consider
>> something like:
>> http://docs.python.org/library/collections.html#collections.namedtuple
>
> Very cool. Thanks! The class I have in mind is *almost* that
> dumb, but performance is a consideration in this case, which may
> rule out namedtuple. But I'm glad to learn about it; there are
> many places where I can put them to good use.
>
You may well find that namedtuple is faster than what you put together
yourself, as the collections module is implemented in C.

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
See PyCon Talks from Atlanta 2010 http://pycon.blip.tv/
Holden Web LLC http://www.holdenweb.com/
UPCOMING EVENTS: http://holdenweb.eventbrite.com/

From: kj on
In <4ba58503$0$27838$c3e8da3(a)news.astraweb.com> Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> writes:

>On Sat, 20 Mar 2010 22:15:54 +0000, kj wrote:

>> I need to create a class solely for the purpose of encapsulating a large
>> number of disparate data items.

>There's a built-in for that. It's called "dict". Syntax for item access
>is a tiny bit different, but still very common:

>data['foo']

>instead of

>data.foo

I find the latter more readable than the former. All those extra
elements (the brackets and the quotes, vs the single dot) add
Perl-like visual noise to the code, IMHO.

And dicts are vulnerable to this sort of bug:

data['typo'] = type(foobar)

Also, AFAIK, initialization of a dictionary is never as simple as

i = myclass(*fields)

But in a sense you're right: aside from these objections,
*functionality-wise* what I'm looking for is not very different
from a dictionary, or a C struct.

>> At the moment I have no plans for any
>> methods for this class other than the bazillion accessors required to
>> access these various instance variables.

>Huh? If you have instance variables, why don't you refer to them by name?

I'm sorry, I used the wrong terminology. I see now that the correct
term is "(instance) attribute", not "instance variable".

>Leave the repetitive accessor code out. Python isn't Java.

>http://dirtsimple.org/2004/12/python-is-not-java.html

Thanks for the link! The bit about "Guido's time machine" is pretty
funny.

~K
From: Steven D'Aprano on
On Sun, 21 Mar 2010 16:57:40 +0000, kj wrote:

> Just accessing attributes looks a bit dangerous to me, due to bugs like
> typing
>
> i.typo = 'foo'
>
> when what you meant is
>
> i.type = 'foo'

That's the price you pay for using a dynamic language like Python with no
declarations. But honestly, the price isn't very high, particularly if
you use an editor or IDE with auto-completion. I can't think of the last
time I had an error due to the above sort of mistake.

Besides, is that error really so much more likely than this?

i.type = 'fpo'

when you meant 'foo'? The compiler can't protect you from that error, not
in any language.


> I tried fixing this by mucking with __setattr__, but I didn't hit on a
> satisfactory solution (basically, I couldn't find a good,
> self-maintaining, way to specify the attributes that were OK to set from
> those that weren't). Is there anything built-in?

No.

You could abuse __slots__, but it really is abuse: __slots__ are a memory
optimization, not a typo-checker.

In Python 3.x, you can (untested) replace the class __dict__ with a
custom type that has more smarts. At the cost of performance. This
doesn't work in 2.x though, as the class __dict__ is always a regular
dictionary.

Something like this might work, at some minor cost of performance:

# Untested
def __setattr__(self, name, value):
if hasattr(self, name):
super(MyClassName, self).__setattr__(name, value)
else:
raise TypeError('cannot create new attributes')

Then, in your __init__ method, to initialise an attribute use:

self.__dict__['attr'] = value

to bypass the setattr.


Or you can use something like PyChecker or PyLint to analyse your code
and warm about likely typos.

But really, it's not a common form of error. YMMV.



> Regarding properties, is there a built-in way to memoize them? For
> example, suppose that the value of a property is obtained by parsing the
> contents of a file (specified in another instance attribute). It would
> make no sense to do this parsing more than once. Is there a standard
> idiom for memoizing the value once it is determined for the first time?

Google for "Python memoization cookbook". This will get you started:

http://code.activestate.com/recipes/52201/

Then just apply the memoize decorator to the property getter.




--
Steven
From: Christian Heimes on
Steve Holden wrote:
> You may well find that namedtuple is faster than what you put together
> yourself, as the collections module is implemented in C.

But namedtuple isn't, Steve. Namedtuple is a class generator that
creates fast and efficient classes.