Q about assignment and references

Alf P. Steinbach alfps at start.no
Wed Apr 7 05:44:00 CEST 2010

* jdbosmaus:
> Pretty new to Python, but I thought I understood what is meant by "an
> assignment is a reference."
> Until I tried to understand this.
> Here is a (fragment of an) event handler for a group of three wxPython
> toggle buttons. The idea is to change the appearance of the label of
> the button that was pressed, and reset the appearance of the other
> two. Because all three buttons send messages to this handler, it uses
> the event argument to figure out which button was activated. (In the
> original there is additonal code that enforces some button-state
> logic, but that's not relevant to this question so it has been
> removed.)
> [code]
> def ScanModeHdlr(self, event):
>         esource = event.GetEventObject() #return button that was
> pressed
>         fontUn = esource.Font
>         fontSel = esource.Font
>         fontUn.Style = wx.NORMAL
>         fontSel.Style = wx.ITALIC
>         fontUn.PointSize = 9
>         fontSel.PointSize = 12
>         btnlist = (self.TBN_NewScan, self.TBN_CheckScan,
> self.TBN_ReScan)
>         for x in btnlist:
>             if x is esource:
>                 x.Font = fontSel
>             else:
>                 x.Font = fontUn
> [/code]
> Now, what bothers me is that in the 3rd and 4th lines, the RHS
> "esource.Font" returns a wx.Font object that is a *copy* of the font
> object of the button. The next four lines set the size and slant of
> these objects - using semantics that ought to, in the ordinary Python
> way, be changing "esource.Font". They don't, proving that fontUn and
> fontSel are copies, not references. OK, esource.Font is a class
> property, not a list, so maybe that's fair, though confusing.

As a property 'esource.Font' can produce a copy, yes.

Then 'fontUn' is set to refer to that new font object.

And 'fontSel' is set to refer to another new font object.

> Then in
> the for-loop we assign the font object to a LHS object that ...
> semantically, looks exactly like the thing that returned a *copy* up
> above.

You mean "syntactically, looks exactly". But whether it is depends on what it 
is. If it's a simple attribute then it's just like a simple assignment. But most 
likely it's a property because the assignment needs to have the side effect of 
updating the button's screen presentation. And as a property it may copy the 
font object or not. The syntax doesn't tell you. The documentation may tell you.

> Not only that, but the for-loop variable "x" is assigned
> sequentially to the button objects, yet the "is" comparison (which
> does work as desired) proves that one value of x is the same *object*
> as esource, not a copy - and look at line 2 where esource was
> assigned.

No problem here.  'btnList' is a 'tuple' array of three object references. x is 
assigned each reference in turn. Since it is a simple assignment to a variable 
no "behind the scenes" actions are possible. It's just simple references.

> I could understand if the setting-semantics in the for-loop needed to
> be something like "x.SetFont(fontUn)", or even "x.SetFont = fontUn".
> (for "could understand" read "would be much happier.")

Well, I don't think those names connote copying.

> I could also understand if the 3rd and 4th lines needed to look like
> "fontUn = copy(esource.Font)". (which doesn't work; "copy" doesn't
> know what to do.)

Don't know about that. It's not a language problem though. It's about the wex 

> What I can't understand is how the semantics that actually works makes
> sense in terms of Python's assignment conventions.
> Can anybody square this circle for me? Thx...

Assignments to plain variables are simple reference copyings.

Assignment to a property can do anything (including just printing "Hello, world!").

Using a property in an expression, e.g. on the rhs of an assignment, can 
likewise do anything. It all depends on the properties in question. Or as Niels 
Bohr remarked when asked how many tails a dog has, "It depends on the dog".

Cheers & hth.,

- Alf

More information about the Python-list mailing list