namespace & imported modules

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

    #1

    namespace & imported modules

    Hi,

    I've been having trouble understanding the difference between global
    namespace within and between modules. For example, I can program a
    subthread to see a global name (a threaded event to be specific);
    however, somehow when I break up my code into different modules, the
    subthread can no longer see the global name in the main program.

    Here's an example of what I'm trying to accomplish:

    Working script pseudo-code:
    =============== =============== =============== =========
    # main.py
    ---------------------------
    import std modules

    def thread1
    def thread2

    launch thread1: wait for event
    launch thread2: signal thread1's event
    =============== =============== =============== =========
    #END: Broken script pseudo-code

    and here's it's seemingly equivalent part...

    #START: Broken script pseudo-code
    =============== =============== =============== =========
    # subfile.py:
    ---------------------------
    import std modules

    def thread1
    def thread2

    ---------------------------
    # main.py
    import std modules
    from subfile import thread1, thread2 # this should be the only
    difference

    launch thread1: wait for event
    launch thread2: signal thread1's event
    =============== =============== =============== =========
    #END: Broken script pseudo-code

    The broken code would yield the following exception when thread2 tries
    to signal thread1's event:
    "NameError: global name 'myName' is not defined"

    I hope I didn't simplify the problem too much, but I didn't want to
    paste 200 lines of code for no one to read.

    Obviously I'm missing something regarding namespace and global scopes.
    Would anyone be able to point out what I've overlooked? Any help is
    appreciated.

    -Jason
  • Peter Otten

    #2
    Re: namespace & imported modules

    Jason wrote:
    [color=blue]
    > I've been having trouble understanding the difference between global
    > namespace within and between modules. For example, I can program a[/color]

    Did you know that global variables are only global to the module?
    [color=blue]
    > from subfile import thread1, thread2 # this should be the only[/color]

    This will bind the names thread1 and thread2 in the importing module, i. e.
    you have now two distinct thread1 variables no longer pointing to the same
    object after a thread1 = something assignment in one of the modules. Do

    import subfile

    instead and access the variables with qualified names

    subfile.thread1 = something

    in all modules except subfile.py, and everything should be OK.

    Peter

    Comment

    • Jason

      #3
      Re: namespace & imported modules

      Thanks for your quick reply, Peter.

      I had to dust off my Learning Python book, which I had read cover to
      cover many months ago. After re-reading some key sections I now
      understand what 'global' scope really means and why you suggested
      importing the module directly, rather than copying the namespace with
      the 'from' statement.

      When importing the module directly as 'import module' in lieu of 'from
      module import *', this doesn't seem to address the issue I'm having.

      My main program now imports the submodule names that must be qualified
      with the module name, but the function in one submodule still can't
      see the function (class instance method to be exact) defined in the
      other submodule.

      I suppose I can post the test code I was using. The multithreaded
      hierarchy mimics that of my 'real' program that I need to integrate my
      code into, so don't let this complexity confuse you.

      =============== =============== =============== ==============
      # main.py
      #
      #!/usr/bin/env python
      #
      # A customized class to terminate a thread using the threading
      module's event-
      # based functionality.
      #
      ############### ############### ############### ############### ############### ####

      import threading, time

      from hb_imports import *
      import hb_imports
      import hb_global

      def main():
      # launch WatchDog timer thread
      bcast_watchdog = hb_global.Watch Dog(timeout=3)
      bcast_watchdog. setDaemon(1)
      bcast_watchdog. start()

      # launch global arbiter
      glob_arbiter = threading.Threa d(target=hb_glo bal.global_arbi ter)
      glob_arbiter.se tDaemon(1)
      glob_arbiter.st art()

      time.sleep(7)
      cfg['ISROOT'] = False # simulation: no longer root again

      time.sleep(7)

      if __name__ == '__main__':
      main()

      =============== =============== =============== ==============
      # hb_global.py

      import threading, time
      import hb_stethoscope
      from hb_imports import *

      class WatchDog(thread ing.Thread):
      def __init__(self, name='WatchDog' , timeout=1.0):
      self._timereven t = threading.Event () # assign event to instance
      self._waitperio d = timeout # assign timeout delay to instance
      variable

      threading.Threa d.__init__(self , name=name)

      def run(self):
      while 1:
      while not cfg['ISROOT']:
      print now() + 'Timer started. %s seconds to receive ping.' %
      self._waitperio d

      # initialize timer and flags
      self._timereven t.clear() # BE KIND. REWIND.
      self._intervene d = False # init flag denoting intervention
      occurred

      # wait for reset() method to be called or timeout
      self._timereven t.wait(self._wa itperiod)

      # if _intervened flag not set AND still not a root server (status
      could change in countdown)
      if not self._intervene d and not cfg['ISROOT']:
      print now() + "No broadcasts received in %s seconds! Becoming a
      root server." % (self._waitperi od,)
      cfg['ISROOT'] = True # modify root status

      time.sleep(0.1) # sleep 100ms to avoid constant polling

      def reset(self):
      self._intervene d = True
      self._timereven t.set()


      def global_arbiter( ):
      threading.Threa d(target=hb_ste thoscope.stetho scope).start()

      =============== =============== =============== ==============
      # hb_stethoscope. py

      import threading, time
      import hb_global
      from hb_imports import *

      def stethoscope():
      for i in range(6):
      if i == 3:
      time.sleep(4)
      sim_delay = 1
      time.sleep(sim_ delay)
      threading.Threa d(target=bcast_ handle).start()

      def bcast_handle():
      print now() + 'Receiving broadcast ping. Reseting watchdog timer.'
      hb_global.bcast _watchdog.reset ()

      =============== =============== =============== ==============
      # hb_imports.py

      import time

      otime = time.time()

      def now():
      ctime = time.time()
      return '%.2f :: ' % (ctime-otime,)

      cfg = dict()
      cfg['ISROOT'] = False

      =============== =============== =============== ==============

      The last line in hb_stethoscope. py, hb_global.bcast _watchdog.reset (),
      is _supposed_ to call the WatchDog.reset( ) class instance method in
      hb_global.py.

      I've been very frustrated trying to find out why I can't access this
      method.

      Thanks for anyone taking a look at this problem.

      Happy Thanksgiving,

      Jason

      Comment

      • Peter Otten

        #4
        Re: namespace & imported modules

        Jason wrote:
        [color=blue]
        > def main():
        > # launch WatchDog timer thread
        > bcast_watchdog = hb_global.Watch Dog(timeout=3)[/color]

        [...]
        [color=blue]
        > The last line in hb_stethoscope. py, hb_global.bcast _watchdog.reset (),
        > is _supposed_ to call the WatchDog.reset( ) class instance method in
        > hb_global.py.[/color]

        It seems you are creating bcast_watchdog as a local variable in
        __main__.main() . How would you suppose it to become magically inserted in
        the hb_global namespace? Do

        def main():
        bcast_watchdog = hb_global.Watch Dog(timeout=3)
        hb_global.bcast _watchdog = bcast_watchdog

        to insert the WatchDog instance into the hb_global module. (Note that there
        may be other problems as I didn't look any further)

        Peter

        Comment

        Working...