"Brian Elmegaard" <be at mek.dtu.dk> wrote in message news:3ACC4EB1.376225AF at mek.dtu.dk... [snip] > non-CS-engineer it's too hard to get a meaningful explanation. Can it be > written in a few words, so I may understand why lists are (and have to > be) so different from "normal" variables? [snip] > > I'll leave it to alex to write the long, pedagogical explanation. > > Looking forward to it. Hmmm, OK, let's have a try. The Python world is made up of "objects", aka "values", and "references", that are bound to those objects. OK so far? All you can do to a 'reference' is bind it to some object. If a reference was already bound to an object, and you are now binding it to another object, this is also called 're-binding' the reference. Binding (and re-binding) is most often done through the so-called "assignment statement": the reference that is affected is indicated by what is on the left of the '=' sign in such a statement, the object being bound, by what is on the right of said sign. (For completeness: "un-binding" a reference is also possible; the 'del' statement is used for that purpose; a reference 'exists' if and only if it's bound to some object -- it starts 'existing' when a binding is first done, it ceases to 'exist' if and when un-bound; conversely, one could also say that an object exists if and only if one or more references are bound to it, and be _almost_ right). The key thing to remember: in se and per se, the fact of re-binding a reference, which was previously bound to object X, so that it is now bound to object Y, _has NO observable effect on either X or Y_ (except for such things as the possible 'side effect' of an object going away completely if no references whatsoever are bound to it, a garbage-collection issue which may work differently in different Python implementations). Some objects can 'contain' references: for example, if an object has "attributes", you can think of those as references which have names and are contained by the object; what you can think of as (global) variables are nothing more (and nothing less) than the attributes of an object (a module-object, i.e., an object whose type is types.ModuleType). [_Local_ variables of a function are treated in a special way -- in some sense, they 'exist' even when not yet bound, which is why you can get an UnboundLocalError if you refer to them when they are not bound]. Not all references 'contained' in an object need be there as named attributes of the object. A dictionary object contains 'items', which are key-value pairs: each key, and each value, is a reference. A list object contains 'items' which are just references, held in some specific order and identifiable by progressive number ('index'). Some objects are *mutable*, which means their state may be changed (others, such as strings, tuples, and numbers, are immutable). So, coming to your original example, you had: """ In apply I do: def apply(self,button,buttons,setting): setting= button.cget('text') """ The body of this 'apply' is just re-binding a reference which happens to be a local variable of this apply function. It is, specifically, an 'argument' of it, but arguments are just local variables whose initial binding on a given function-call is effected before the function-body starts executing (to either default values, or values supplied by the caller). Re-binding a local variable (be it an argument, or not) can never have any possible effect on anything outside this specific function, anyway. This is a simple consequence of what I identified above as "the key thing to remember": re-binding a reference affects only that reference, NOT the object which that reference happened to be previously bound to. You say you now changed things: """ I use a list instead of a "variable" for the CurrentCanvasSetting. This allows me to use it as a global variable, and I can get the wanted """ I _think_ you mean you are now doing something like: def apply(self,button,buttons,setting): setting[0] = button.cget('text') This is re-binding, *NOT* the (local-variable) reference named 'setting', but, rather, the (indexed) "0-th slot" of whatever (e.g., a list) 'setting' is bound to. This *mutates* the object that 'setting' is bound to -- thus, it may indeed be 'observable from outside', since there may be any number of other references to said object, besides the local one (argument) named 'setting'. You are re-binding a reference *CONTAINED* in the object that 'setting' is bound to: and that is the crucial difference. It's not between "lists" and "variables": you could perfectly well mutate a module-object by re-binding one of its variables (named attributes), just as you can mutate a list-object by re-binding one of its items (indexed 'slots'). To achieve such an effect, you would pass the module-object as 'setting' argument to this 'apply', then have a body such as: setting.foobar = button.cget('text') (Or, you could use a 'grab-bag instance object' -- it does not have to be a module-object; see for example http://www.activestate.com/ASPN/Python/Cookbook/Recipe/52308). Alex
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4