On 5/24/21 9:53 PM, hw wrote: > That seems like an important distinction. I've always been thinking of > variables that get something assigned to them, not as something that is > being assigned to something.
Your thinking is not incorrect. Assignment is how you set a variable to something. For the most part the details of how the variables work doesn't matter all that much. An expression in Python works about the same as it does in other languages. Where it becomes important to understand the name binding mechanism is in situations like you found yourself. What happens, for example, when you do something like float=5? Hence the discussion about name shadowing. The reason I brought up the distinction of how python's variables work compared to a language like C is because under the hood Python's assignment doesn't "alter" the variable. Assignment replaces it entirely in the name space. This is consistent with a more formal definition of variable found in lambda calculus. I learned in uni there are some formal languages that don't allow any variable names to be rebound at all, which makes formal proofs and analysis easier. But I digress. There are also implications for parameter passing. All of this is in the language reference documentation of course. But even still there have been many arguments about whether Python is pass by value or pass by reference. Consider: def foo(bar): bar += 1 a = 5 foo(a) print(a) or def frob(foo): foo.append('bar') a = [ 'one', 'two' ] frob(a) print(a) The truth is Python might be said to "pass by object." In other words when you call a function, it goes through the names table and extracts references to all the objects involves with the arguments and passes those objects to the function. Objects that are mutable can be changed by a function, and those changes are visible in the code that called it, since both caller and callee are dealing with the *same object*, just by different names (aliases). Strings and other values like ints are *immutable*. They cannot be changed. Assignment will not change them, only overwrite the names in the locals table. > I would think of it as assigning a string to a variable and then > changing the content of the variable by assigning something else to the > same variable. When variables are typeless, it doesn't matter if a > string or an integer is assigned to one (which is weird but can be very > useful). Yes that's how it's done in many lower-level languages. Python does not assign that way, though. It's not clearing the contents and placing something else there. Instead assignment overwrites the binding in the name table, connecting the name to the new string object that was created. The old object is dereferenced, and the garbage collector will eventually remove it. > It seems much more practical to assign different strings to the same > variable rather than assigning a different variable to each string, or > to assign a string to a variable and then to assign an integer to it. How exactly would one overwrite an integer in memory with a string, though? You would have to either preallocate a lot of memory for it in case something large were to be written to the variable, or you'd allocate it on the heap on demand and use a reference for it. Under the hood, Python does the second. How else would you do it? > Isn't that what variables are for? In the formal sense, variables are just names that stand in for values. Don't get too hung up on the mechanics of how one implements that as being a formal part of the definition, and don't think that one language's implementation of variables is the only way to do it. -- https://mail.python.org/mailman/listinfo/python-list