From: Patrick Maupin on
On Mar 21, 11:57 am, kj <no.em...(a)please.post> 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'
>
> 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?
>

If you *really* want static typing and validation for attributes in
Python, you might check out enthought traits: http://code.enthought.com/projects/traits/

Regards,
Pat
From: Steve Holden on
Christian Heimes wrote:
> 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.
>
Ah, right, thanks.

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 <4ba66311$0$27838$c3e8da3(a)news.astraweb.com> Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> writes:

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

> self.__dict__['attr'] = value

>to bypass the setattr.

Ah, that's the trick! Thanks!

~K
From: kj on
In <mailman.1030.1269194878.23598.python-list(a)python.org> Dennis Lee Bieber <wlfraed(a)ix.netcom.com> writes:

>On Sun, 21 Mar 2010 16:57:40 +0000 (UTC), kj <no.email(a)please.post>
>declaimed the following in gmane.comp.python.general:

>> 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?
>>
> Pickle, Shelve? Maybe in conjunction with SQLite3...

I was thinking of something less persistent; in-memory, that is.
Maybe something in the spirit of:

@property
def foo(self):
# up for some "adaptive auto-redefinition"?
self.foo = self._some_time_consuming_operation()
return self.foo

....except that that assignment won't work! It bombs with "AttributeError:
can't set attribute".

~K

PS: BTW, this is not the first time that attempting to set an
attribute (in a class written by me even) blows up on me. It's
situations like these that rattle my grasp of attributes, hence my
original question about boring, plodding, verbose Java-oid accessors.
For me these Python attributes are still waaay too mysterious and
unpredictable to rely on. Sometimes one can set them, sometimes
not, and I can't quite tell the two situations apart. It's all
very confusing to the Noob. (I'm sure this is all documented
*somewhere*, but this does not make using attributes any more
intuitive or straightforward. I'm also sure that *eventually*,
with enough Python experience under one's belt, this all becomes
second nature. My point is that Python attributes are not as
transparent and natural to the uninitiated as some of you folks
seem to think.)
From: Alf P. Steinbach on
* kj:
> In <mailman.1030.1269194878.23598.python-list(a)python.org> Dennis Lee Bieber <wlfraed(a)ix.netcom.com> writes:
>
>> On Sun, 21 Mar 2010 16:57:40 +0000 (UTC), kj <no.email(a)please.post>
>> declaimed the following in gmane.comp.python.general:
>
>>> 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?
>>>
>> Pickle, Shelve? Maybe in conjunction with SQLite3...
>
> I was thinking of something less persistent; in-memory, that is.
> Maybe something in the spirit of:
>
> @property
> def foo(self):
> # up for some "adaptive auto-redefinition"?
> self.foo = self._some_time_consuming_operation()
> return self.foo
>
> ...except that that assignment won't work! It bombs with "AttributeError:
> can't set attribute".

Since foo is a read only property you can assign to it.

But it doesn't matter: if it worked technically it wouldn't give you what you're
after, the once-only evaluation.

A simple way to do that, in the sense of copying code and having it work, is to
use a generator that, after evaluating the expensive op, loops forever yielding
the resulting value.

A probably more efficient way, and anyway one perhaps more easy to understand,
is as follows:


<code>
from __future__ import print_function

class LazyEval:
def __init__( self, f ):
self._f = f
self._computed = False

@property
def value( self ):
if not self._computed:
self._value = self._f()
self._computed = True
return self._value

class HiHo:
def _expensive_op( self ):
print( "Expensive op!" )
return 42

def __init__( self ):
self._foo = LazyEval( self._expensive_op )

@property
def foo( self ):
return self._foo.value

o = HiHo()
for i in range( 5 ):
print( o.foo )
</code>


Cheers & hth.,

- Alf