Steven D'Aprano
2/21/2008 10:33:00 PM
On Thu, 21 Feb 2008 16:37:56 +0000, tinnews wrote:
> Aahz <aahz@pythoncraft.com> wrote:
>> In article <47bd7ffe$0$514$bed64819@news.gradwell.net>,
>> <tinnews@isbd.co.uk> wrote:
>> >Aahz <aahz@pythoncraft.com> wrote:
>> >> In article
>> >> <72b59db8-ec9c-480a-9ae7-92a69acb70a6@41g2000hsc.googlegroups.com>,
>> >> <MartinRinehart@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