Global variables, Classes, inheritance

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • DaveM

    #1

    Global variables, Classes, inheritance

    Although I've programmed for fun - on and off - since the mid 70's, I'm
    definitely an OO (and specifically Python) beginner.

    My first question is about global variables. Are they, as I'm starting to
    suspect, a sin against God or just best avoided? Having got my current
    application working using them, I'm not sure whether I want to refactor it,
    but equally, I'd like to write the best code I can.

    Secondly (and this is related), if you have multiple instances of the same
    class, but need them all to have access to a dictionary created at run-time,
    is there a class way to this without calling the creation method multiple
    times? The best thought I've come up with is for the class instance to check
    its name and only if it's the first one do the dictionary creation, but I
    haven't tried it yet.

    My third difficulty is with variables in a class. What's the difference
    between the following?:

    class Foo:
    i = 12345
    ...

    class Foo:
    self.i = 12345
    ...

    class Foo:
    def __init__(self):
    self.i = 12345
    ...

    class Foo:
    def __init(self):
    i = 12345
    ...

    DaveM
  • Claudio Grondi

    #2
    Re: Global variables, Classes, inheritance

    DaveM wrote:[color=blue]
    > Although I've programmed for fun - on and off - since the mid 70's, I'm
    > definitely an OO (and specifically Python) beginner.
    >
    > My first question is about global variables. Are they, as I'm starting to
    > suspect, a sin against God or just best avoided? Having got my current
    > application working using them, I'm not sure whether I want to refactor it,
    > but equally, I'd like to write the best code I can.[/color]
    For me global variables in Python are not that much sin as global
    variables in another languages (as e.g. C/C++).[color=blue]
    >
    > Secondly (and this is related), if you have multiple instances of the same
    > class, but need them all to have access to a dictionary created at run-time,
    > is there a class way to this without calling the creation method multiple
    > times? The best thought I've come up with is for the class instance to check
    > its name and only if it's the first one do the dictionary creation, but I
    > haven't tried it yet.
    >
    > My third difficulty is with variables in a class. What's the difference
    > between the following?:
    >
    > class Foo:
    > i = 12345
    > ...
    >
    > class Foo:
    > self.i = 12345
    > ...
    >
    > class Foo:
    > def __init__(self):
    > self.i = 12345
    > ...
    >
    > class Foo:
    > def __init(self):
    > i = 12345
    > ...
    >
    > DaveM[/color]

    Before some expert will enlighten you and provide appropriate links, you
    can just try to run what you have listed (e.g. to see what is broken)
    and watch the outcome.

    Maybe it is a good idea to try to look at globals() and locals() to see
    what and when happens and take a look at the documentation to see what
    this functions are about.

    Claudio

    Comment

    • Michael Spencer

      #3
      Re: Global variables, Classes, inheritance

      DaveM wrote:[color=blue]
      > Although I've programmed for fun - on and off - since the mid 70's, I'm
      > definitely an OO (and specifically Python) beginner.
      >
      > My first question is about global variables. Are they, as I'm starting to
      > suspect, a sin against God or just best avoided? Having got my current
      > application working using them, I'm not sure whether I want to refactor it,
      > but equally, I'd like to write the best code I can.[/color]

      Use them sparingly IMO
      [color=blue]
      >
      > Secondly (and this is related), if you have multiple instances of the same
      > class, but need them all to have access to a dictionary created at run-time,
      > is there a class way to this without calling the creation method multiple
      > times? The best thought I've come up with is for the class instance to check
      > its name and only if it's the first one do the dictionary creation, but I
      > haven't tried it yet.
      >[/color]

      Make the dictionary an attribute of the class, not the instance. Then it will
      be visible by all the instances. See below:

      [color=blue]
      > My third difficulty is with variables in a class. What's the difference
      > between the following?:
      >
      > class Foo:
      > i = 12345
      > ...
      >[/color]

      this sets i as an attribute of the class.

      [color=blue]
      > class Foo:
      > self.i = 12345
      > ...
      >[/color]

      this probably raises a NameError, unless you happen to have bound 'self' in the
      scope containing Foo, which would be a really bad idea

      [color=blue]
      > class Foo:
      > def __init__(self):
      > self.i = 12345
      > ...
      >[/color]

      this sets i as an attribute of the instance, self, when it is initialized
      [color=blue]
      > class Foo:
      > def __init(self):
      > i = 12345
      > ...[/color]

      this assigns the name 'i' in the local scope of the __init__ function. It has
      no effect on self


      So, to get your shared dictionary, you could write:[color=blue][color=green][color=darkred]
      >>> class A(object):[/color][/color][/color]
      ... shared_dict = {}
      ...[color=blue][color=green][color=darkred]
      >>>
      >>> a1 = A()
      >>> a2 = A()
      >>> a1.shared_dict is a2.shared_dict[/color][/color][/color]
      True[color=blue][color=green][color=darkred]
      >>> a1.shared_dict["a"] = 42
      >>> a2.shared_dict["a"][/color][/color][/color]
      42[color=blue][color=green][color=darkred]
      >>>[/color][/color][/color]

      Note also, that you create "classic" classes by writing `class Foo:`, and "new
      style" classes by writing `class Foo(object):`. There are several subtle
      differences between the two, and, since you are just starting, you might as well
      learn with the new ones.

      HTH

      Michael


      Comment

      • Kirk McDonald

        #4
        Re: Global variables, Classes, inheritance

        DaveM wrote:[color=blue]
        > Although I've programmed for fun - on and off - since the mid 70's, I'm
        > definitely an OO (and specifically Python) beginner.
        >
        > My first question is about global variables. Are they, as I'm starting to
        > suspect, a sin against God or just best avoided? Having got my current
        > application working using them, I'm not sure whether I want to refactor it,
        > but equally, I'd like to write the best code I can.[/color]

        Python globals are actually remarkably safe, at least compared to some
        other languages. The key is that, when you import a module, its globals
        stay in its namespace. I've got nothing against them.
        [color=blue]
        >
        > Secondly (and this is related), if you have multiple instances of the same
        > class, but need them all to have access to a dictionary created at run-time,
        > is there a class way to this without calling the creation method multiple
        > times? The best thought I've come up with is for the class instance to check
        > its name and only if it's the first one do the dictionary creation, but I
        > haven't tried it yet.[/color]

        A class attribute would do this easily:

        class Foo(object):
        d = {}

        a = Foo()
        b = Foo()
        Foo.d = { 'a' : 'apple' }
        print a.d
        print b.d

        That will print out {'a':'apple'} twice.
        [color=blue]
        >
        > My third difficulty is with variables in a class. What's the difference
        > between the following?:
        >
        > class Foo:
        > i = 12345
        > ...
        >[/color]

        i is a class attribute. It is bound to the class (which is, itself, an
        object). You can access i both from the class itself as well as from an
        instance of the class, i.e., Foo.i and Foo().i will both work.
        [color=blue]
        > class Foo:
        > self.i = 12345
        > ...
        >[/color]

        This does not work. There is no name 'self' bound to class Foo.
        [color=blue]
        > class Foo:
        > def __init__(self):
        > self.i = 12345
        > ...
        >[/color]

        This binds the name 'i' to all instances of class Foo; if this were C++,
        we'd call self.i a member variable.
        [color=blue]
        > class Foo:
        > def __init(self):
        > i = 12345
        > ...
        >[/color]

        (You forgot the trailing __, but whatever. :-) This binds the name 'i'
        to the local namespace of the __init__ function. It is just like any
        other local variable in a function.

        Namespaces in Python are really great. It is worth reading up on
        globals() and locals() if you don't get them yet.

        -Kirk McDonald

        Comment

        • DaveM

          #5
          Re: Global variables, Classes, inheritance

          Thanks very much for the help to all who replied.
          I'd completely missed the difference between:

          class Foo:
          i = 12345

          a = Foo()
          b = Foo()

          a.i = 678

          and Foo.i = 678

          Yeah, I know...

          DaveM

          Comment

          Working...