namespace & imported modules

Discussion in 'Python' started by Jason, Nov 24, 2004.

  1. Jason

    Jason Guest

    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
    Jason, Nov 24, 2004
    #1
    1. Advertising

  2. Jason

    Peter Otten Guest

    Jason wrote:

    > I've been having trouble understanding the difference between global
    > namespace within and between modules. For example, I can program a


    Did you know that global variables are only global to the module?

    > from subfile import thread1, thread2 # this should be the only


    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
    Peter Otten, Nov 24, 2004
    #2
    1. Advertising

  3. Jason

    Jason Guest

    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.WatchDog(timeout=3)
    bcast_watchdog.setDaemon(1)
    bcast_watchdog.start()

    # launch global arbiter
    glob_arbiter = threading.Thread(target=hb_global.global_arbiter)
    glob_arbiter.setDaemon(1)
    glob_arbiter.start()

    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(threading.Thread):
    def __init__(self, name='WatchDog', timeout=1.0):
    self._timerevent = threading.Event() # assign event to instance
    self._waitperiod = timeout # assign timeout delay to instance
    variable

    threading.Thread.__init__(self, name=name)

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

    # initialize timer and flags
    self._timerevent.clear() # BE KIND. REWIND.
    self._intervened = False # init flag denoting intervention
    occurred

    # wait for reset() method to be called or timeout
    self._timerevent.wait(self._waitperiod)

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

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

    def reset(self):
    self._intervened = True
    self._timerevent.set()


    def global_arbiter():
    threading.Thread(target=hb_stethoscope.stethoscope).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.Thread(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
    Jason, Nov 24, 2004
    #3
  4. Jason

    Peter Otten Guest

    Jason wrote:

    > def main():
    > # launch WatchDog timer thread
    > bcast_watchdog = hb_global.WatchDog(timeout=3)


    [...]

    > 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.


    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.WatchDog(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
    Peter Otten, Nov 25, 2004
    #4
    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. Owen Wong
    Replies:
    1
    Views:
    384
    Karl Seguin [MVP]
    Mar 17, 2006
  2. Tomasz Lisowski
    Replies:
    4
    Views:
    351
    Tomasz Lisowski
    May 25, 2005
  3. Martin M.
    Replies:
    4
    Views:
    335
    Simon Brunning
    Dec 15, 2005
  4. Dun Peal
    Replies:
    10
    Views:
    443
    Chris Rebert
    May 3, 2011
  5. Volker Nicolai
    Replies:
    9
    Views:
    906
    Fabian Pilkowski
    Jul 4, 2005
Loading...

Share This Page