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/ -- http://mail.python.org/mailman/listinfo/python-list