# Globals or objects?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Fri Feb 22 15:01:47 CET 2008

```On Fri, 22 Feb 2008 03:16:12 -0800, MartinRinehart wrote:

> D'Aprano's discussion is persuasive but only in the case where you do
> not want multiple actors updating a single value. In my case multiple
> actors have legitimate interest in updating the value. (Actors within a

You missed the point. It's not whether you only have *one* actor has to
update the value, or more than one. It's about having loose coupling
between the actors and the value.

Consider a thought experiment. Suppose somebody wrote a math library that
worked something like this:

# contents of maths.py
x = 0.0  # default value for global x

def sin():
taylor = x + x**2/2 + x**3/6
# Taylor's expansion of sine. (I think.)
return taylor

and so forth. To use this library, you would have to do this:

savex = maths.x
maths.x = 0.1
y = maths.sin()  # multiple actors with a legitimate need
z = maths.cos()  # to access a single global value
maths.x = savex

The functions are tightly coupled to x, and can't operate on anything
else other than x, so your program ends up being filled with wasteful
code storing the value of x, setting it to a value, then restoring it.

I think we will all agree that the above is a ridiculous way to write
code. But what you're doing differs from it only in degree, not kind: all
you're doing is replacing x with counter.

In your example, you say you have "multiple actors [with a] legitimate
interest in updating the [global] value." That's fine. But that *group*
of actors still behaves as a single entity. What happens when you have
two *groups*?

savecounter = counter
foo(actor1)  # All these actors are in the same group:
foo(actor3)  # "Odd" actors.
foo(actor5)
print counter
counter = savecounter
# But these are in a different group:
foo(actor2)  # "Even" actors.
foo(actor4)

As soon as you have multiple groups, globals become a millstone around
operate on any value except counter. That makes testing very hard,
because your test functions can't provide their own counters.

Now, there are times where using globals is acceptable *in spite of* this
problem. For example, I will often use globals to write a piece of quick-
and-dirty through-away code. Or as a first draft: write a bit of code
using a global, get the basic algorithm working, then modify it to work
with a parameter instead. Or perhaps you've decided that you really
*want* that tight coupling. And you can't avoid globals altogether,
because there's always going to be a global scope.

--
Steven

```