Global Variables in OOP and Python

Discussion in 'Python' started by newbie, Dec 30, 2005.

  1. newbie

    newbie Guest

    Hello,

    I have questions about global variables in OOP (in general) and Python
    (in specific). I understand (I think) that global variables are
    generally not a good idea. However, if there are variables that need to
    be accessed by a number of classes that exists in separate namespaces
    (files), what would be the best way to do this?

    So far, I have approached the problem by making the variables
    attributes of one class and passing instances of the class as variables
    to the other class' methods.

    The other way I thought of is to create a separate class that consists
    of the variables and to use the

    from <file name> import *

    in all of the files (namespaces) where it is needed.

    Is there a better way?

    Are the two ideas presented above acceptable? If so, is one better than
    the other from an OOP POV?
    newbie, Dec 30, 2005
    #1
    1. Advertising

  2. On Fri, 30 Dec 2005 15:03:54 -0800, newbie wrote:

    > Hello,
    >
    > I have questions about global variables in OOP (in general) and Python
    > (in specific). I understand (I think) that global variables are
    > generally not a good idea. However, if there are variables that need to
    > be accessed by a number of classes that exists in separate namespaces
    > (files), what would be the best way to do this?
    >
    > So far, I have approached the problem by making the variables
    > attributes of one class and passing instances of the class as variables
    > to the other class' methods.



    Do you mean something like this?

    # Module care_and_feeding

    import birds
    import foods

    def feed_my_pet():
    pet = birds.Parrot("Norwegian Blue")
    snack = foods.Spam("A tasty meat-like treat")
    pet.eats(snack)
    return "Yummy!"


    That is a good way of handling the problem.



    > The other way I thought of is to create a separate class that consists
    > of the variables and to use the
    >
    > from <file name> import *
    >
    > in all of the files (namespaces) where it is needed.


    That's a bad way of handling it. It has all the worst aspects of using
    global variables, plus the worst aspects of import * (namespace pollution
    and shadowing of existing names).

    Unless I'm badly mistaken, Guido has decided that "from module import *"
    was a mistake, and that will be removed from the (legendary) Python 3, if
    and when it gets created. In the meantime, it is highly recommended that
    you don't use that form.


    > Is there a better way?
    >
    > Are the two ideas presented above acceptable? If so, is one better than
    > the other from an OOP POV?



    I think the first way is fine, but of course the Devil is in the details:
    I can't judge your code without seeing it.


    --
    Steven.
    Steven D'Aprano, Dec 31, 2005
    #2
    1. Advertising

  3. newbie

    Mike Meyer Guest

    "newbie" <> writes:
    > So far, I have approached the problem by making the variables
    > attributes of one class and passing instances of the class as variables
    > to the other class' methods.


    That's the standard way to do it in OO languages.

    > The other way I thought of is to create a separate class that consists
    > of the variables and to use the
    >
    > from <file name> import *
    >
    > in all of the files (namespaces) where it is needed.


    Except for one detail, this is a Pythonesque method. The detail is
    that "from <module> import *" is generally considered a bad
    idea. There are two reasons for this:

    1) Blindly adding everything in a module to your namespace is liable
    to cause collisions. If the module you're doing this to is stable,
    this isn't much of a problem.

    2) It makes finding where a variable came from harder. Having to
    search extra modules for globals is a pain. If the exported names have
    a prefix on them to identify the module, that goes away. But in that
    case, you might as well do "import <module> as <prefix>", and leave
    the prefix off the variable names in the module.

    A better way to do this is to give your module a name that denotes
    it's function ("config", for instances, or maybe even "globals") and
    use that.

    > Are the two ideas presented above acceptable? If so, is one better than
    > the other from an OOP POV?


    With the one change, they are. From an OO point of view, they're
    almost identical. In Python, a module is an object, so the difference
    is whether you want to instantiate a custom class to hold your
    globals, or use the builtin module type for that purpose.

    <mike

    --
    Mike Meyer <> http://www.mired.org/home/mwm/
    Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
    Mike Meyer, Dec 31, 2005
    #3
  4. newbie

    Gary Herron Guest

    newbie wrote:

    >Hello,
    >
    >I have questions about global variables in OOP (in general) and Python
    >(in specific). I understand (I think) that global variables are
    >generally not a good idea. However, if there are variables that need to
    >be accessed by a number of classes that exists in separate namespaces
    >(files), what would be the best way to do this?
    >
    >So far, I have approached the problem by making the variables
    >attributes of one class and passing instances of the class as variables
    >to the other class' methods.
    >
    >The other way I thought of is to create a separate class that consists
    >of the variables and to use the
    >
    >from <file name> import *
    >
    >

    That form is deprecated. Better (and certainly clearer to any reader of
    the code) is to leave them in the module.

    Define a module, say Parameters, that defines any number of variables
    containing useful values. Then
    import Parameters
    wherever you want and refer to
    Parameters.a
    and
    Parameters.b

    You can even add runtime parameters (say options and paths from the
    command line) to the module during your initialization code, and those
    will be available wherever Parameters is imported:
    Parameters.xyzzy = 'whatever'
    Parameters.startDirectory = os.getcwd() # Get working directory at startup
    (Even if the import of Parameters in some file occurs before the
    initialization code has a chance to run.)

    Gary Herron

    >in all of the files (namespaces) where it is needed.
    >
    >Is there a better way?
    >
    >Are the two ideas presented above acceptable? If so, is one better than
    >the other from an OOP POV?
    >
    >
    >
    Gary Herron, Dec 31, 2005
    #4
  5. Gary Herron said unto the world upon 30/12/05 08:03 PM:
    > newbie wrote:
    >
    >
    >>Hello,
    >>
    >>I have questions about global variables in OOP (in general) and Python
    >>(in specific). I understand (I think) that global variables are
    >>generally not a good idea. However, if there are variables that need to
    >>be accessed by a number of classes that exists in separate namespaces
    >>(files), what would be the best way to do this?
    >>
    >>So far, I have approached the problem by making the variables
    >>attributes of one class and passing instances of the class as variables
    >>to the other class' methods.
    >>
    >>The other way I thought of is to create a separate class that consists
    >>of the variables and to use the
    >>

    >
    >>from <file name> import *

    >
    >>
    >>

    >
    > That form is deprecated. Better (and certainly clearer to any reader of
    > the code) is to leave them in the module.
    >
    > Define a module, say Parameters, that defines any number of variables
    > containing useful values. Then
    > import Parameters
    > wherever you want and refer to
    > Parameters.a
    > and
    > Parameters.b


    <snip>

    An other variant seems rarely to come up.

    import Parameters as P

    provides almost all the brevity of the * variant and none of the dangers.

    Best to all,

    Brian vdB
    Brian van den Broek, Dec 31, 2005
    #5
  6. On Fri, 30 Dec 2005 20:00:51 -0500, Mike Meyer wrote:


    >> The other way I thought of is to create a separate class that consists
    >> of the variables and to use the
    >>
    >> from <file name> import *
    >>
    >> in all of the files (namespaces) where it is needed.

    >
    > Except for one detail, this is a Pythonesque method. The detail is
    > that "from <module> import *" is generally considered a bad
    > idea. There are two reasons for this:


    Agree about from module import * being bad, but it is still generally poor
    practice for the same reason using global variables is generally poor
    practice.


    > 1) Blindly adding everything in a module to your namespace is liable
    > to cause collisions. If the module you're doing this to is stable,
    > this isn't much of a problem.


    How does stability come in to it? If I have a module spam with an object
    parrot, and it imports another module with an object parrot, there will be
    a namespace collision regardless of whether the two modules are 0.1 alpha
    versions or 3.2 stable versions. If the collision is subtle enough, the
    bug might take years to discover.

    If you mean that namespace collisions are less likely to have remained
    undetected by the time the modules reach stability, then I will cautiously
    agree with you. But if you mean what you say, that collisions are not a
    problem for stable modules, then I disagree strongly.



    > 2) It makes finding where a variable came from harder. Having to
    > search extra modules for globals is a pain. If the exported names have
    > a prefix on them to identify the module, that goes away. But in that
    > case, you might as well do "import <module> as <prefix>", and leave
    > the prefix off the variable names in the module.


    Agreed.


    > A better way to do this is to give your module a name that denotes
    > it's function ("config", for instances, or maybe even "globals") and
    > use that.


    And an even better way is to use the absolute minimum number of global
    variables possible. In general, that means global functions and classes
    Good, global instances and other data Bad.

    In other words, any time you feel the need to put "global name" in a
    function or method, think twice, have a cold shower, do fifty push-ups,
    and then re-write the function to not use globals. 99 times out of a 100,
    you'll end up with better code.


    --
    Steven.
    Steven D'Aprano, Dec 31, 2005
    #6
  7. On Sat, 31 Dec 2005 11:37:38 +1100, Steven D'Aprano
    <> declaimed the following in
    comp.lang.python:

    >
    > Do you mean something like this?
    >
    > # Module care_and_feeding
    >
    > import birds
    > import foods
    >
    > def feed_my_pet():
    > pet = birds.Parrot("Norwegian Blue")
    > snack = foods.Spam("A tasty meat-like treat")
    > pet.eats(snack)
    > return "Yummy!"
    >
    >
    > That is a good way of handling the problem.
    >

    Except for the minor facet that you are buying a new parrot each
    time, and the bird dies after going "Yummy!" <G>
    --
    > ============================================================== <
    > | Wulfraed Dennis Lee Bieber KD6MOG <
    > | Bestiaria Support Staff <
    > ============================================================== <
    > Home Page: <http://www.dm.net/~wulfraed/> <
    > Overflow Page: <http://wlfraed.home.netcom.com/> <
    Dennis Lee Bieber, Dec 31, 2005
    #7
  8. On Sat, 31 Dec 2005 21:21:29 +0000, Dennis Lee Bieber wrote:

    > On Sat, 31 Dec 2005 11:37:38 +1100, Steven D'Aprano
    > <> declaimed the following in
    > comp.lang.python:
    >
    >>
    >> Do you mean something like this?
    >>
    >> # Module care_and_feeding
    >>
    >> import birds
    >> import foods
    >>
    >> def feed_my_pet():
    >> pet = birds.Parrot("Norwegian Blue")
    >> snack = foods.Spam("A tasty meat-like treat")
    >> pet.eats(snack)
    >> return "Yummy!"
    >>
    >>
    >> That is a good way of handling the problem.
    >>

    > Except for the minor facet that you are buying a new parrot each
    > time, and the bird dies after going "Yummy!" <G>


    It's a Norwegian Blue with beautiful plumage. It's not dead, it's just
    pining for the fjords.



    --
    Steven.
    Steven D'Aprano, Jan 1, 2006
    #8
  9. newbie

    Kay Schluehr Guest

    Steven D'Aprano wrote:
    > On Fri, 30 Dec 2005 20:00:51 -0500, Mike Meyer wrote:
    >
    >
    > >> The other way I thought of is to create a separate class that consists
    > >> of the variables and to use the
    > >>
    > >> from <file name> import *
    > >>
    > >> in all of the files (namespaces) where it is needed.

    > >
    > > Except for one detail, this is a Pythonesque method. The detail is
    > > that "from <module> import *" is generally considered a bad
    > > idea. There are two reasons for this:

    >
    > Agree about from module import * being bad, but it is still generally poor
    > practice for the same reason using global variables is generally poor
    > practice.


    No, I don't think so. The general wisdom is that global variables are
    bad not because they are global, but because they are variable.
    Responsibility about state mutation is scattered across the code and
    spaghetti is the likely consequence. This cannot be prevented by
    changing the access protocoll ( getters / setters ) or using static
    variables. Mutable OO-singletons are not less harmfull than good old
    globals.

    Namespace pollution or name clashes are another issue and we have to
    make a tradeoff between easeness of following references and namespace
    security on the one hand conciseness on the other. I'm not completely
    unhappy using "True" instead of "__builtins__.True" allthough the
    latter would be more pure.
    Kay Schluehr, Jan 1, 2006
    #9
  10. On Sun, 01 Jan 2006 06:48:48 -0800, Kay Schluehr wrote:

    >> Agree about from module import * being bad, but it is still generally poor
    >> practice for the same reason using global variables is generally poor
    >> practice.

    >
    > No, I don't think so. The general wisdom is that global variables are
    > bad not because they are global, but because they are variable.
    > Responsibility about state mutation is scattered across the code and
    > spaghetti is the likely consequence. This cannot be prevented by
    > changing the access protocoll ( getters / setters ) or using static
    > variables. Mutable OO-singletons are not less harmfull than good old
    > globals.


    Now that you mention it, how obvious it is. That is good thinking,
    thanks.



    --
    Steven.
    Steven D'Aprano, Jan 1, 2006
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wayne
    Replies:
    2
    Views:
    469
    Wayne
    Nov 11, 2003
  2. jubelbrus
    Replies:
    5
    Views:
    615
    JohnQ
    Jul 20, 2007
  3. mark4asp
    Replies:
    1
    Views:
    216
  4. global variables in oop

    , Sep 15, 2005, in forum: Perl Misc
    Replies:
    5
    Views:
    110
    John Bokma
    Sep 15, 2005
  5. king
    Replies:
    2
    Views:
    169
    Tad McClellan
    Jun 27, 2006
Loading...

Share This Page