Globals or objects?

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Thu Feb 21 17:32:37 EST 2008


On Thu, 21 Feb 2008 16:37:56 +0000, tinnews wrote:

> Aahz <aahz at pythoncraft.com> wrote:
>> In article <47bd7ffe$0$514$bed64819 at news.gradwell.net>,
>>  <tinnews at isbd.co.uk> wrote:
>> >Aahz <aahz at pythoncraft.com> wrote:
>> >> In article
>> >> <72b59db8-ec9c-480a-9ae7-92a69acb70a6 at 41g2000hsc.googlegroups.com>,
>> >>  <MartinRinehart at gmail.com> wrote:
>> >>>
>> >>>I had a global variable holding a count. One source Google found
>> >>>suggested that I wouldn't need the global if I used an object. So I
>> >>>created a Singleton class that now holds the former global as an
>> >>>instance attribute. Bye, bye, global.
>> >>>
>> >>>But later I thought about it. I cannot see a single advantage to the
>> >>>object approach. Am I missing something? Or was the original global
>> >>>a better, cleaner solution to the "I need a value I can read/write
>> >>>from several places" problem?
>> >> 
>> >> The advantage of the global singleton is that it is a container;
>> >> therefore, its contents are mutable and you don't need to keep using
>> >> the ``global`` statement.
>> >
>> >.... but you do keep having to use a longer reference to the value so
>> >what have you won?
>> 
>> Clarity, simplicity, robustness
> 
> Clarity - why is it clearer?

Consider two function calls:


x = ham(arg, counter)
y = spam(arg)

Both do exactly the same thing: ham() takes an explicit "counter" 
argument, while spam() uses a global variable. Which one makes it clear 
that it uses a counter, and which does not?

 
> Simplicity - no, you've added an extra layer.

Consider trying to run ham() and spam() twice, independently:

x1 = ham(arg, counter)
x2 = ham(arg, another_counter)

y1 = spam(arg)
saved_counter = counter  # save the global variable
counter = 0  # reset it to zero
y2 = spam(arg)
another_counter = counter
counter = saved_counter


Which is simpler?


 
> Robustness - how?

If you avoid the use of globals, this code will work as expected:

x = ham(arg, counter)
assert counter.n = 5  # or whatever value ham() sets it to...
function()
another_function()
yet_another_function()

At the end of this block of function calls, you can be confident that 
counter still has the same value.

Now consider using globals:

x = spam(arg)
assert counter = 5  # or whatever value spam() sets it to...
function()
another_function()
yet_another_function()

What value will counter have? The only way to tell is to carefully read 
through function(), another_function() and yet_another_function() and see 
whether or not they modify the global counter. Maybe they do, maybe they 
don't, who can tell?


-- 
Steven



More information about the Python-list mailing list