Postpone creation of attributes until needed

Frank Millman frank at chagford.com
Tue Jun 12 11:53:11 EDT 2007


On Jun 12, 1:18 pm, Steven D'Aprano
<s... at REMOVE.THIS.cybersource.com.au> wrote:
> On Mon, 11 Jun 2007 22:35:46 -0700, Frank Millman wrote:
> > On Jun 12, 1:46 am, Steven D'Aprano
> > <s... at REMOVE.THIS.cybersource.com.au> wrote:
>
> >> >> You haven't told us what the 'compute' method is.
>
> >> >> Or if you have, I missed it.
>
> >> > Sorry - I made it more explicit above. It is the method that sets up
> >> > all the missing attributes. No matter which attribute is referenced
> >> > first, 'compute' sets up all of them, so they are all available for
> >> > any future reference.
>
> >> If you're going to do that, why not call compute() from your __init__ code
> >> so that initializing an instance sets up all the attributes?
>
> > Because, as I have tried to explain elsewhere (probably not very
> > clearly), not all the information required to perform compute() is
> > available at __init__ time.
>
> I'm sorry, but this explanation doesn't make sense to me.
>
> Currently, something like this happens:
>
> (1) the caller initializes an instance
> =>  instance.x = some known value
> =>  instance.y is undefined
> (2) the caller tries to retrieve instance.y
> (3) which calls instance.__getattr__('y')
> (4) which calls instance.compute()
> =>  which forces the necessary information to be available
> =>  instance.__dict__['y'] = some value
> (5) finally returns a value for instance.y
>
> Since, as far as I can tell, there is no minimum time between creating the
> instance at (1) and trying to access instance.y at (2), there is no
> minimum time between (1) and calling compute() at (4), except for the
> execution time of the steps between them. So why not just make compute()
> the very last thing that __init__ does?
>

I wrote a long reply to this about an hour ago, but Google Groups
seems to have eaten it. I hope I can remember what I wrote.

This is more like what I am doing -

(t=table, c=column, p=pseudo column)

(1) the caller initializes table t1 and columns c1-c10
(2) the caller initializes table t2 and columns c11-c20
(3) t2.__init__() creates a link to t1, and updates t1 with a link to
t2
(4) t2.__init__() creates a link from c12 to c3, and updates c3 with a
link to c12
(5) t2.__init__() creates pseudo column p1 on table t1, creates a link
from c14 to p1, updates p1 with a link to c14

This all works well, and has been working for some time.

You can already see a difference between your scenario and mine.
Various attributes are set up *after* the original __init__() method
has completed.

I have now added a complication.

I want to create a t3 instance, with columns c21-c30, and I want to
create a pseudo column p2 on table t2, exactly as I did in steps 2 to
5 above. I also want to change step 5 so that instead of linking p1 on
table 1 to c14 on table 2, I link it to p2 on table 2. However, at
that point, p2 does not exist.

I hope that describes the problem a bit better. I'm going to leave it
at that for now, as I am getting a glimmer of an idea as to how I can
refactor this. I will tackle it again in the morning when I am feeling
fresh, and will report back then.

Frank




More information about the Python-list mailing list