along the lines, hash and obj. id.

castironpi at gmail.com castironpi at gmail.com
Wed Feb 27 18:38:09 EST 2008


On Feb 27, 4:16 pm, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
wrote:
> En Tue, 26 Feb 2008 05:58:52 -0200, <castiro... at gmail.com> escribió:
>
> > It works to keep a reference to the object, then access the member
> > again.  If your only reference to the object is the member itself,
> > obj.a= {} breaks d, but obj.a.clear() keeps it alive.
>
> > In the case of immutables, there is no such .clear() equivalent.

Reemphisize:

> > If obj.a is a tuple, string, or integer.

Very important for the deduction.  /IF/ it /IS/.

> > [THEN] d is always broken when obj.a is changed.

> "when obj.a is changed": That may have two meanings:
>
> a) "when the object itself referenced by obj.a is modified" or
> b) "when obj.a is made to refer to another object"

Since obj.a is immutable, (b) is guaranteed for any change.

... Unless what you're saying is, 'this guy sucks with words.'  In
that case, <sighs, bows, shakes head, sulks>.  Make that, "when obj.a
is -rebound-," and it can't be changed at all.

> For a), you use something like obj.a.somemethod(). "obj.a" still refers to
> the same object, even if it changed internally; if obj.a and foo.bar both
> were refering to the same object, they still do. [1]
> For b), you have to rebind the name using any statement with such effects
> (assignment, for, with, import...); in this example, as obj.a is an
> attribute reference, the only allowed forms are assignments: obj.a =
> something (including augmented assignments obj.a += something). If obj.a
> and foo.bar both were previously refering to the same object, you can't
> guarantee that after executing such statements.
>
> > The generic solution involves a second level of indirection: tuple* d=
> > &obj.a.  I can't land a clean solution to it though.
>
> (Forget about C and pointers... you'll just confuse things this way.
> Python has objects and names that refer to them, not pointers and
> variables with allocated storage and type.)
>
> Depending on the requirements, there are several answers. You may
> distinghish "some" place as "the" official place where the object lives,
> and make all other retrieve it from there when needed.

While this breaks encapsulation, it may mean the right thing
sometimes.

> Or use a
> notification mechanism when its value changes.

Then, not only do "you" rebind a, but "everyone else" does too.  IOW,
not only does the target rebind a, but all the Notify-ees / Observers
have to rebind their slates.

> Or wrap the value into another shared object.

Probably the most general.

Call it ReftoImmutable.  a= ref( ( 2, ) ); b= a; a.val= ( 3, ); assert
b.val== ( 3, ).  You still can't use a.val in sets, but you can use
a.  assert b in { a: True }, since assert b== a.

> [1] Assuming somemethod() isn't evil and rebinds obj.a itself...

(<cough cough>)

However, it can get a little tedious.  RefToImmutableList is the next
step on the road, which takes a list, and makes its elements
RefToImmutable instances.  You can call a function on rtiList[n], and
it can still set the element there: elem.val= 0, elem.val+= 1, &c., in
cases in which it's better than passing a ( list, index ) pair.  You
have to know that rtiElem is a RefToImmutable in the former, but you
had to know the meaning of list and index in the latter too.  And as
mutables can be stored in rti.val too, you can always just call them
ref.

In other news, ? is also "not used in Python. [Its] occurrence outside
string literals and comments is an unconditional error:".  Reserved
for the next function decorators.  <evil cackle>





More information about the Python-list mailing list