Globals or objects?
Steve Holden
steve at holdenweb.com
Sat Feb 23 08:16:44 EST 2008
Steven D'Aprano wrote:
> On Fri, 22 Feb 2008 18:53:54 +0000, tinnews wrote:
>
>>>> But you're not comparing what the OP posted. He was comparing a
>>>> global with an object with a single variable inside it. Either would
>>>> work with the y = spam(arg) example above.
>>> What do you mean by "an object with a single variable inside it"? I
>>> don't understand what that is supposed to mean, or why you think it is
>>> the same as a global. Do you mean a Singleton?
>>>
>>> If so, then the answer is simple: using a Singleton argument instead of
>>> a global is better, because with a global you are stuck to always using
>>> the global (at least until you can re-write the code), but with the
>>> Singleton argument, you may be enlightened and *not* use a Singleton.
>>>
>> But if you stop using the Singleton the code no longer does the same as
>> it would with a global does it?
>
> That's a *good* thing, not a problem. The whole idea is to get away from
> the bad behaviour of globals, not find some other way to implement it.
>
I think that advocation of a global singleton is not really solving the
problem. Not the problem I perceive, anyway. From your comments it's
difficult to see whether we share the same perceptions, so let me elucidate.
The issue I have with globals is primarily that use of a global
introduces a tight coupling between a function and its environment,
since any environment that uses the function has to provide the global.
It's true that a global singleton is a half-way step to a solution of
the problem because it portends the true solution, which also solves the
problem of multiple counts. That solution, of course, is to have the
"function" become a method of some counter object, which can then be
used to count many things.
In other words (untested, so ignore the many Holden types that this will
inevitably incur):
--------
bad.py:
counter = 0
def count(n):
global counter
counter += n
--------
justasbadifnotworse.py:
class bunch: pass;
counter = bunch()
bunch.count = 0
def count(n):
counter.count += n
--------
better.py:
class Counter:
def __init__(self):
self.count = 0
counter1 = Counter()
counter2 = Counter()
def count(n, counter):
counter.count += n
--------
best.py:
class Counter:
def __init__(self):
self.count = 0
def count(self, n):
self.count += n
--------
Now the names I have chosen are pejorative, but this is typically the
development you see in someone's programming style as they slowly (or
not slowly) start to understand the value of the object-oriented approach.
Unfortunately this sometimes goes too far, and people end up writing
"monster objects", with dozens of methods and lots of instance variables
used to communicate between them. With that style of programming the
instance variables introduce the same tight coupling between the methods
that globals do in a less object-oriented style, and the code becomes
just as difficult to understand. Only now there can be multiple
instances of the badly-written function!
Sometimes this is inevitable, but good programming style is about trying
to strike the right balance between contexts. It is truly possible to
write good and bad programs in any language you like, and rules like
"globals are bad" need to be taken in context just like any other rule.
After all, some things *have* to be global for our programs to make any
sense at all, unless you want to adopt a truly functional style that has
never appealed to me. I like my programs to have state.
regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.holdenweb.com/
More information about the Python-list
mailing list