Importing variables non-deterministic?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Aug 19 12:57:37 EDT 2013


On Mon, 19 Aug 2013 10:16:36 +0200, Antoon Pardon wrote:

> Op 19-08-13 09:45, Dave Angel schreef:
>> Antoon Pardon wrote:
>> 
>>> Op 17-08-13 17:01, Steven D'Aprano schreef:
>>>>
>>>> And here you re-import the name "y" from struct_global. That rebinds
>>>> the current module's "y" with whatever value struct_global.y has
>>>> *now*, rather than a second (or a minute, or an hour) earlier when
>>>> the first import took place. Obviously at some point between the
>>>> first import and the second import, struct_global.y must have been
>>>> reassigned from -1 to 62.
>>>>
>>>> This goes to show why global variables are considered harmful, and
>>>> why clean, modern program design tries to reduce the use of them as
>>>> much as possible. Global variables are too easily modified by, well,
>>>> *anything*. The sort of behaviour you are seeing is sometimes called
>>>> "action at a distance" -- something, anything, anywhere in your
>>>> program, possibly buried deep, deep down inside some function you
>>>> might never suspect, is changing the global variable.
>>>
>>> I think you are overstating your case. Classes and functions are
>>> variables too and in general nobody seems to have a problem with them
>>> being global.
>>>
>>>
>> It's global *variables* that are to be avoided.  constants like clsases
>> and functions are fine.  On the other hand, class attributes can be
>> variable, and thus are to be avoided when reasonable.
> 
> Python has no constants. Classes and functions can be changed just like
> any other variable. I agree that classes and function are generally
> meant to be constant, but often enought so are global int variables.

You are technically correct, but missing the point. If I wrote code that 
went around reassigning names from one function to another function, I 
would very likely soon work myself into a state of utter confusion:

def func(x):
    ...

# later
save_func = func
func = lambda x, y: do_stuff(x, 3*y)-4
result = something_that_calls_func()
func = save_func


Nasty, horrible code, yes? But it's nasty and horrible because "func" is 
bound to a function, it would be equally nasty and horrible if it was a 
data type (a string, a list, an int, a flag, ...) instead.

Since classes and functions are First Class objects in Python, naturally 
if you treat them as global *variables* rather than global *constants* 
you can end up with problems. The problem is not the global part alone. 
Global constants, or pseudo-constant-by-convention-only, are fine.


> And some of those that do change, only do so in the initialisation phase
> and should be considered constant for the rest of the program.
> 
> My point was that Steven has no way of knowing what exactly is going on
> here and so shouldn't be making such a sweeping statement.

On the contrary, I can read the Original Poster's description of the 
problem, and then use my ability to reason to deduce what the most likely 
explanation was.

Now of course I might be wrong. I don't claim infallibility or 
omniscience. But I'm not an idiot, and if the OP says that a global 
variable has one value at one time, and then some time later has a 
different value, there are two likely possibilities:

* The variable was changed by some other piece of code, i.e. it 
  actually was being used as a *global variable*.

* The OP is completely confused, and (inadvertently, we hope) 
  reporting things which are actually not true.

Much less likely:

* Despite 15+ years of experience with Python, and reading the
  documentation, I have failed to notice that, yes, the OP is 
  correct and importing variables is non-deterministic.

* There's a bug in Python.


Both of these are theoretically possible, but the chance of them is 
somewhere between Buckley's and None.


Of course, if you have an alternate explanation for the issue the OP 
reported, I would love to hear it. Maybe I have completely misunderstood 
the situation.



-- 
Steven



More information about the Python-list mailing list