A scoping question

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • It's me

    #1

    A scoping question

    This must be another newbie gotchas.

    Consider the following silly code, let say I have the following in file1.py:

    #=============
    import file2
    global myBaseClass
    myBaseClass = file2.BaseClass ()
    myBaseClass.Add Child(file2.Nex tClass())
    #=============

    and in file2.py, I have:

    #=============
    global myBaseClass
    class BaseClass:
    def __init__(self):
    self.MyChilds = []
    ...
    def AddChild(NewChi ld):
    self.MyChilds.a ppend(NewChild)
    ...
    class NextClass:
    def __init__(self):
    for eachChild in myBaseClass.MyC hilds: # <- ERROR
    ...
    #=============

    When I run this, Python complains that myBaseClass is undefined in the last
    line above.

    What am I doing wrong? (Yes, I know I am thinking too much in C). I
    thought the global declaration would have been sufficient but it's obviously
    not.

    Thanks,


  • Premshree Pillai

    #2
    Re: A scoping question

    On Tue, 28 Dec 2004 19:34:36 GMT, It's me <itsme@yahoo.co m> wrote:[color=blue]
    > This must be another newbie gotchas.
    >
    > Consider the following silly code, let say I have the following in file1.py:
    >
    > #=============
    > import file2
    > global myBaseClass
    > myBaseClass = file2.BaseClass ()
    > myBaseClass.Add Child(file2.Nex tClass())
    > #=============[/color]

    You have declared myBaseClass to be global, but it doesn't exist.

    Consider the following code:

    global name
    print name.__len__()

    This will return a NamError

    However, the following code will run just fine:

    global name
    name = "python"
    print name.__len__()

    will return 6
    [color=blue]
    >
    > and in file2.py, I have:
    >
    > #=============
    > global myBaseClass
    > class BaseClass:
    > def __init__(self):
    > self.MyChilds = []
    > ...
    > def AddChild(NewChi ld):
    > self.MyChilds.a ppend(NewChild)
    > ...
    > class NextClass:
    > def __init__(self):
    > for eachChild in myBaseClass.MyC hilds: # <- ERROR
    > ...
    > #=============
    >
    > When I run this, Python complains that myBaseClass is undefined in the last
    > line above.
    >
    > What am I doing wrong? (Yes, I know I am thinking too much in C). I
    > thought the global declaration would have been sufficient but it's obviously
    > not.
    >
    > Thanks,
    >
    > --
    > http://mail.python.org/mailman/listinfo/python-list
    >[/color]

    HTH

    --
    Premshree Pillai

    Comment

    • It's me

      #3
      Re: A scoping question


      "Premshree Pillai" <premshree.pill ai@gmail.com> wrote in message
      news:mailman.85 24.1104263434.5 135.python-list@python.org ...[color=blue]
      > On Tue, 28 Dec 2004 19:34:36 GMT, It's me <itsme@yahoo.co m> wrote:[color=green]
      > > This must be another newbie gotchas.
      > >
      > > Consider the following silly code, let say I have the following in[/color][/color]
      file1.py:[color=blue][color=green]
      > >
      > > #=============
      > > import file2
      > > global myBaseClass
      > > myBaseClass = file2.BaseClass ()
      > > myBaseClass.Add Child(file2.Nex tClass())
      > > #=============[/color]
      >
      > You have declared myBaseClass to be global, but it doesn't exist.
      >[/color]

      No, myBaseClass exists in file1.py. The question is how can I tell
      file2.py that the global variable is in file1 (without doing a silly
      file1.myBaseCla ss....

      Since I am invoking file2 from file1, I would have thought that global
      variables in file1 exists automatically.. ..(too much C thinking, I know)


      Comment

      • Premshree Pillai

        #4
        Re: A scoping question

        On Tue, 28 Dec 2004 19:59:01 GMT, It's me <itsme@yahoo.co m> wrote:[color=blue]
        >
        > "Premshree Pillai" <premshree.pill ai@gmail.com> wrote in message
        > news:mailman.85 24.1104263434.5 135.python-list@python.org ...[color=green]
        > > On Tue, 28 Dec 2004 19:34:36 GMT, It's me <itsme@yahoo.co m> wrote:[color=darkred]
        > > > This must be another newbie gotchas.
        > > >
        > > > Consider the following silly code, let say I have the following in[/color][/color]
        > file1.py:[color=green][color=darkred]
        > > >
        > > > #=============
        > > > import file2
        > > > global myBaseClass
        > > > myBaseClass = file2.BaseClass ()
        > > > myBaseClass.Add Child(file2.Nex tClass())
        > > > #=============[/color]
        > >
        > > You have declared myBaseClass to be global, but it doesn't exist.
        > >[/color]
        >
        > No, myBaseClass exists in file1.py. The question is how can I tell[/color]

        Umm, from the sample code (for file2.py) that you provided, I don't
        see myBaseClass. You've only declared it to be global in file2.py, but
        it does not exist -- does not exist in the sense that it has no type
        associated with it, which in turn means meaning you cannot apply
        methods to it.
        [color=blue]
        > file2.py that the global variable is in file1 (without doing a silly
        > file1.myBaseCla ss....
        >
        > Since I am invoking file2 from file1, I would have thought that global
        > variables in file1 exists automatically.. ..(too much C thinking, I know)
        >
        >
        > --
        > http://mail.python.org/mailman/listinfo/python-list
        >[/color]


        --
        Premshree Pillai

        Comment

        • Steven Bethard

          #5
          Re: A scoping question

          It's me wrote:[color=blue]
          > This must be another newbie gotchas.
          >
          > Consider the following silly code, let say I have the following in file1.py:
          >
          > #=============
          > import file2
          > global myBaseClass
          > myBaseClass = file2.BaseClass ()
          > myBaseClass.Add Child(file2.Nex tClass())
          > #=============
          >
          > and in file2.py, I have:
          >
          > #=============
          > global myBaseClass
          > class BaseClass:
          > def __init__(self):
          > self.MyChilds = []
          > ...
          > def AddChild(NewChi ld):
          > self.MyChilds.a ppend(NewChild)
          > ...
          > class NextClass:
          > def __init__(self):
          > for eachChild in myBaseClass.MyC hilds: # <- ERROR
          > ...
          > #=============
          >
          > When I run this, Python complains that myBaseClass is undefined in the last
          > line above.
          >
          > What am I doing wrong? (Yes, I know I am thinking too much in C). I
          > thought the global declaration would have been sufficient but it's obviously
          > not.[/color]

          I think you're confused about what the global keword does. Declaring a
          name as global makes that name global *to the module*:




          What you probably want instead is:

          -------------------- file1.py --------------------
          import file2
          myBaseClass = file2.BaseClass ()
          myBaseClass.Add Child(file2.Nex tClass())
          --------------------------------------------------

          -------------------- file2.py --------------------
          class BaseClass:
          def __init__(self):
          self.MyChilds = []
          def AddChild(self, NewChild):
          self.MyChilds.a ppend(NewChild)
          class NextClass:
          def __init__(self):
          from file1 import myBaseClass # IMPORT
          for eachChild in myBaseClass.MyC hilds:
          pass
          --------------------------------------------------

          Note that I import myBaseClass in __init__. If I imported it at the top
          of the module, then file1 would import file2 which would then import
          file1 and you'd have a circular dependency.

          As it is, your code is very tightly coupled. Why don't you put all this
          code into a single module?

          Steve

          Comment

          • Steven Bethard

            #6
            Re: A scoping question

            It's me wrote:[color=blue]
            > This must be another newbie gotchas.
            >
            > Consider the following silly code[/color]
            [snip tightly coupled code]

            A few options that also might work better than such tightly coupled modules:

            -------------------- file1.py --------------------
            import file2
            myBaseClass = file2.BaseClass ()
            class NextClass:
            def __init__(self):
            for eachChild in myBaseClass.MyC hilds:
            pass
            myBaseClass.Add Child(file2.Nex tClass())
            --------------------------------------------------

            -------------------- file2.py --------------------
            class BaseClass:
            def __init__(self):
            self.MyChilds = []
            def AddChild(self, NewChild):
            self.MyChilds.a ppend(NewChild)
            --------------------------------------------------


            or


            -------------------- file1.py --------------------
            import file2
            myBaseClass = file2.BaseClass ()
            myBaseClass.Add Child(file2.Nex tClass(myBaseCl ass))
            --------------------------------------------------

            -------------------- file2.py --------------------
            class BaseClass:
            def __init__(self):
            self.MyChilds = []
            def AddChild(self, NewChild):
            self.MyChilds.a ppend(NewChild)
            class NextClass:
            def __init__(self, myBaseClass):
            for eachChild in myBaseClass.MyC hilds:
            pass
            --------------------------------------------------

            Comment

            • It's me

              #7
              Re: A scoping question

              Thanks, Steve.

              So, global is only to within a module (I was afraid of that). Those words
              flashed by me when I was reading it but since the word "module" didn't
              translate to "file" in my C mind, I didn't catch that.

              In that case, you are correct that I have to do an import of file1 in file2.

              Not that this is not real code, I am still trying to learn the ins and outs
              of Python by writing some silly code - but will be important to help me
              understand how I would write the real code.

              Regarding the question of not placing everything in one module, I wouldn't
              think that that's how I would do it. I might get ambitous later and write
              code for a larger project. In that case, I will need to know more about
              scoping across multiple modules. So, this helps me understand what to do.

              Thanks again.

              "Steven Bethard" <steven.bethard @gmail.com> wrote in message
              news:I5jAd.2467 42$5K2.73425@at tbi_s03...

              <snip>
              [color=blue]
              >
              > I think you're confused about what the global keword does. Declaring a
              > name as global makes that name global *to the module*:
              >
              > http://docs.python.org/ref/global.html
              > http://docs.python.org/lib/built-in-funcs.html#l2h-32
              >
              > What you probably want instead is:
              >
              > -------------------- file1.py --------------------
              > import file2
              > myBaseClass = file2.BaseClass ()
              > myBaseClass.Add Child(file2.Nex tClass())
              > --------------------------------------------------
              >
              > -------------------- file2.py --------------------
              > class BaseClass:
              > def __init__(self):
              > self.MyChilds = []
              > def AddChild(self, NewChild):
              > self.MyChilds.a ppend(NewChild)
              > class NextClass:
              > def __init__(self):
              > from file1 import myBaseClass # IMPORT
              > for eachChild in myBaseClass.MyC hilds:
              > pass
              > --------------------------------------------------
              >
              > Note that I import myBaseClass in __init__. If I imported it at the top
              > of the module, then file1 would import file2 which would then import
              > file1 and you'd have a circular dependency.
              >
              > As it is, your code is very tightly coupled. Why don't you put all this
              > code into a single module?
              >
              > Steve[/color]


              Comment

              • Steven Bethard

                #8
                naming conventions (WAS: A scoping question)

                It's me wrote:[color=blue]
                > #=============
                > import file2
                > global myBaseClass
                > myBaseClass = file2.BaseClass ()
                > myBaseClass.Add Child(file2.Nex tClass())
                > #=============[/color]
                [snip][color=blue]
                > #=============
                > global myBaseClass
                > class BaseClass:
                > def __init__(self):
                > self.MyChilds = []
                > ...
                > def AddChild(NewChi ld):
                > self.MyChilds.a ppend(NewChild)
                > ...
                > class NextClass:
                > def __init__(self):
                > for eachChild in myBaseClass.MyC hilds: # <- ERROR
                > ...
                > #=============[/color]

                Also worth mentioning if you're just starting with Python. Python has
                some official naming conventions:

                This document gives coding conventions for the Python code comprising the standard library in the main Python distribution. Please see the companion informational PEP describing style guidelines for the C code in the C implementation of Python.


                These are just recommendations of course, but if you have the option
                (e.g. you're not constrained by style enforced by your employer), and
                you'd like your code to look more like standard Python modules, you
                might consider using these suggestions. This would make your code look
                something like:

                #=============
                import file2
                global my_base_class
                my_base_class = file2.BaseClass ()
                my_base_class.a dd_child(file2. NextClass())
                #=============

                #=============
                global my_base_class
                class BaseClass:
                def __init__(self):
                self.my_childs = []
                ...
                def add_child(new_c hild):
                self.my_childs. append(new_chil d)
                ...
                class NextClass:
                def __init__(self):
                for each_child in my_base_class.m y_childs: # <- ERROR
                ...
                #=============

                Steve

                Comment

                • Dennis Lee Bieber

                  #9
                  Re: A scoping question

                  On Tue, 28 Dec 2004 19:34:36 GMT, "It's me" <itsme@yahoo.co m> declaimed
                  the following in comp.lang.pytho n:
                  [color=blue]
                  > This must be another newbie gotchas.
                  >
                  > Consider the following silly code, let say I have the following in file1.py:
                  >
                  > #=============
                  > import file2
                  > global myBaseClass[/color]

                  #1 "global" only applies within a function definition,
                  where it signals that the subsequent name will be modified within the
                  function AND exists in the scope external to the function... If the
                  object name ONLY appears on the right side of an assignment (within the
                  function), "global" is not needed, as the scope rules will look-up the
                  external item. However, if the object name appears on the left hand
                  side, and there is NO "global", Python creates a local object (and will
                  then complain if you used the name on a right-side before the assignment
                  creating it).

                  aGlobalItem = [1, 2, 3]

                  def aFunction():
                  global aGlobalItem
                  aGlobalItem = ('a', 'b', 'c')
                  return None

                  Without the "global", the function would create a function-local
                  called aGlobalItem, and never see the outside object.
                  [color=blue]
                  > myBaseClass = file2.BaseClass ()
                  > myBaseClass.Add Child(file2.Nex tClass())
                  > #=============
                  >
                  > and in file2.py, I have:
                  >
                  > #=============
                  > global myBaseClass
                  > class BaseClass:
                  > def __init__(self):
                  > self.MyChilds = []
                  > ...
                  > def AddChild(NewChi ld):
                  > self.MyChilds.a ppend(NewChild)
                  > ...
                  > class NextClass:
                  > def __init__(self):
                  > for eachChild in myBaseClass.MyC hilds: # <- ERROR
                  > ...
                  > #=============
                  >
                  > When I run this, Python complains that myBaseClass is undefined in the last
                  > line above.
                  >[/color]
                  Which is correct. "global" only works within function
                  definitions /within/ a module (file). To access stuff in other modules
                  you must "import" the module.
                  [color=blue]
                  > What am I doing wrong? (Yes, I know I am thinking too much in C). I
                  > thought the global declaration would have been sufficient but it's obviously
                  > not.
                  >[/color]
                  #2 You are trying to create a set of recursive
                  dependencies. File1 is getting an object definition from File2, but
                  File2 needs the object created in File1...

                  Terrible design, IMHO...


                  And why is NextClass a "class"? Does it return a "NextClass"
                  object?

                  Either way... I'd probably change the __init__ to take two
                  arguments: self (which is the NextClass object being created) and 'o'
                  (the other argument), then use it as

                  nc = NextClass(myBas eClass)

                  --[color=blue]
                  > =============== =============== =============== =============== == <
                  > wlfraed@ix.netc om.com | Wulfraed Dennis Lee Bieber KD6MOG <
                  > wulfraed@dm.net | Bestiaria Support Staff <
                  > =============== =============== =============== =============== == <
                  > Home Page: <http://www.dm.net/~wulfraed/> <
                  > Overflow Page: <http://wlfraed.home.ne tcom.com/> <[/color]

                  Comment

                  Working...