Scope rule pecularities

Andrew Bennetts andrew-pythonlist at puzzling.org
Thu May 13 07:40:34 EDT 2004


On Thu, May 13, 2004 at 10:41:45AM +0000, Antoon Pardon wrote:
> Op 2004-05-13, Andrew Bennetts schreef <andrew-pythonlist at puzzling.org>:
> > On Thu, May 13, 2004 at 07:40:45AM +0000, Antoon Pardon wrote:
> >> 
> >> But I don't ask for rebinding, I ask for easy in place copying.
> >> 
> >> Lets name a new operator "@=" Now given variables A and C
> >> of the same class I would like to see the following:
> >> 
> >> >>> B = A
> >> >>> A @= C
> >> >>> A is B
> >> True
> >> >>> A is C
> >> False
> >> >>> A == C
> >> True
> >
> > It's already easy:
> >
> >     from copy import copy
> >
> >     b = a
> >     a = copy(c)
> 
> Sorry, you are wrong.  After this you get
> 
> >>> a is b
> False

Oh, sorry, I misread -- as you can see, I assumed you meant that C was a
copy of A, when actually you wanted A to be a copy of C.

Now I understand what you mean about an "in-place copy".

> >> And maybe if D is of an other class
> >> 
> >> >>> D @= C
> >> TypError
> >
> > Assignments in Python don't care about what the name is currently bound to,
> > if anything.
> 
> This is not assignment (as is understood in python).

Indeed!  But it *looks* like assignment -- it has an equals sign.  In fact,
it's only one character different to Python's assignment.  My point is that
the proposed syntax is confusing.

> > They just (re)bind the name to an object -- so having an
> > assignment to D depend on the type of D's old value would be inconsistent
> > with the rest of Python.
> >
> > Many classes support a convention where you can pass a single argument to
> > their constructor to construct a copy, e.g.:
> >
> >     l2 = list(l1)
> >
> > So your example could become:
> >
> >     d = d.__class__(c)
> 
> No to get the same effect as what I want you need something like this:
> 
> class M:
> 
>   def cp_from(self, a):
>     for key in dir(self):
>       value = getattr(a,key)
>       setattr(self,key,value)
> 
> d.cp_from(c)

You can do that already, without defining any new methods:
    
    d.__dict__.update(c.__dict__)

[This won't work for the minority of types that don't have __dict__s on
their instances, but it does work for virtually all user-defined classes.]

Assuming that d and c have the same set of instance variable names (which I
would expect most code following good style would do), I don't see why
modifying an existing instance of d to be a copy of c is any better than
simply making a copy from scratch with the clearer:

    d = copy(c)

What's the big advantage to mutating an existing instance?

-Andrew.





More information about the Python-list mailing list