[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Globals or objects?

Martin Rinehart

2/21/2008 12:16:00 PM

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?
18 Answers

Steve Holden

2/21/2008 12:41:00 PM

0

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?

Look up "coupling" and "cohesion" in Wikipedia or similar, and you will
find out that global variables are bad because they introduce tight
coupling between different pieces of functionality in your code.

If a function uses a global variable then you have to initialize the
same global variable in another program that uses it: yet another piece
of setup you will forget to do.

Having said that, where are you storing the reference to the singleton
instance? It wouldn't be a global, would it?

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC http://www.hold...

Hrvoje Niksic

2/21/2008 1:02:00 PM

0

Steve Holden <steve@holdenweb.com> writes:

> If a function uses a global variable then you have to initialize the
> same global variable in another program that uses it: yet another
> piece of setup you will forget to do.

If the global variable belongs to the module, then it is up to the
module to initialize it. A different program program will simply
import the same module and automatically get the same variable,
properly initialized.

One reason why a singleton's attribute may be better than a global
variable is that it's easier to later add a callback when the value is
changed without breaking the interface. A module cannot react to
module.somevar = value; on the other hand, a singleton can implement
__setattr__ that reacts to module.singleton.attr = value.

aahz

2/21/2008 1:26:00 PM

0

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.
--
Aahz (aahz@pythoncraft.com) <*> http://www.python...

"All problems in computer science can be solved by another level of
indirection." --Butler Lampson

tinnews

2/21/2008 1:41:00 PM

0

Steve Holden <steve@holdenweb.com> wrote:
> 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?
>
> Look up "coupling" and "cohesion" in Wikipedia or similar, and you will
> find out that global variables are bad because they introduce tight
> coupling between different pieces of functionality in your code.
>
I think the OP was asking rather how the Object is any different from
the global if it's simply used as a wrapper for a single value.

In usage, philosophy or whatever it's effectively identical and
introduces all the same problems as a global does, it just gives it a
longer name.

Objects only become useful when the encapsulate more than on thing.

--
Chris Green

tinnews

2/21/2008 1:43:00 PM

0

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?

--
Chris Green

Duncan Booth

2/21/2008 1:48:00 PM

0

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?

A singleton is simply another form of global. The benefit of a singleton
is that it can be used to encapsulate several related values and methods
in a single globally accessible space. The easiest way in Python to
implement a singleton is just to use a module: all modules are
singletons and there is a defined mechanism (import) for accessing them.

It sounds as though you simply replaced a value stored in a singleton
object (global in a module) with a value stored in a singleton object
(attribute of your class) which is referenced from a singleton object
(your module).

The real benefit from using an object comes when you stop making it a
singleton. Create it at some high level in your code and pass it around
as a parameter, or hold a reference to it in some other object which is
passed around. When you do this you no longer have a global, and the
benefits you get include:

* for your counter example, you can have multiple counters counting
different things without having to duplicate counter code for each thing
you want to count.

* it becomes much easier to write tests for your code, because each test
can create its own context and be completely independant from the other
tests. e.g. you can test a generic counter without having to know you
are testing the foo counter or the bar counter, and you can test
something which counts foos without having to worry that other tests may
already have counted some foos.

There is another lesser (and Python specific) benefit to storing a value
as an attribute of a class rather than a global in a module: if you
later want to intercept assignments to the attribute you can turn it
into a property, but doing the same thing on a module is much harder.

aahz

2/21/2008 3:42:00 PM

0

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
--
Aahz (aahz@pythoncraft.com) <*> http://www.python...

"All problems in computer science can be solved by another level of
indirection." --Butler Lampson

tinnews

2/21/2008 4:38:00 PM

0

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?

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

Robustness - how?

--
Chris Green

Steven D'Aprano

2/21/2008 10:33:00 PM

0

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

Martin Rinehart

2/22/2008 11:16:00 AM

0

A fascinating, well-informed discussion. Thanks to all.

Holden's suggestion re coupling and cohesion was most informative. I
conclude that whether you use an object or a global (within a module,
not across modules) is an implementation detail that has no impact on
either cohesion or coupling.

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 single thread, fortunately.)

I conclude that intra-module globals are NOT always evil. They get a
bad rap because some of them are evil.

Anecdote proving nothing: My count got wrapped into an object. I found
additional uses for the object, so it stayed there. Finally, the count
and the object got designed out of the module. RIP.