Python Thread class variable is blank
Question: I've been trying to fix this issue for the past few hours, and i just can't
figure out what i'm doing wrong!

I have a single python file:

    
    
    REFRESH_RATE=10.0
    MAX_SECONDS=30
    
    class user_manager:
      users={}
      def __init__(self,queue,sign_properties):
    
        self.properties=sign_properties
        self.queue=queue
        self.lock=threading.Lock()
        t=threading.Thread(target=user_timer,args=(self.lock,))
        t.daemon=True
        t.start()
    
      def add_user(self,macaddr,user_properties):
        self.lock.acquire()
        user_manager.users[macaddr]=user(user_properties)
        self.lock.release()
    
      def user_exists(self, macaddr):
        if macaddr in user_manager.users:
          return True
        return False
    
      def update_rssi_for_user(self, macaddr,rssi):
        self.lock.acquire()
        user_manager.users[macaddr].update_rssi(rssi)
        self.lock.release()
    
      def get_users(self):
        return user_manager.users
    
    
    
    def user_timer(lock):
      while True:
        print 'Test'
        lock.acquire()
        print user_manager.users
        lock.release()
        format = '%H:%M:%S'
        for user in user_manager.users:
          first_seen=user_manager.users[user].get_first_seen()
          current_time=str(datetime.datetime.now().time())
          difference=datetime.strptime(current_time, format) - datetime.strptime(first_seen[1], format)
          print 'difference'+str(difference.seconds)
          if difference.seconds >30:
            user.expire()
            del user_manager.users[user]
        time.sleep(REFRESH_RATE)
    

The idea is that the user_manager class has a class variable called users,
that is populated during runtime - this works perfectly.

Then I have a threaded function called user_timer that is started from the
user_manager, which manages these users and expires them after X amount of
time. This is removed from the context of this post as it's not relevant.

Currently, every time user_timer is called the result of `user_manager.users`
is an empty dictionary `{}` but from outside of this file other modules can
see the class variable as being populated.

What exactly am i doing wrong, and why does it work in this fashion?

James.

EDIT:

Calling class' constructor:

    
    
        class api_wrapper(object):
      def __init__(self,queue,display_queue,macaddr):
        self.properties={}
        self.queue=queue
        self.register_sign(macaddr)
        self.user_manager=user_manager(self.queue,self.properties)
        self.nearby_devices={}
        self.display_queue=display_queue
    

Calling function from the above class:

    
    
    def handle_address(self,address,postcode):
    if self.user_manager is None:
      return
    if self.user_manager.user_exists(address):
      #print user_manager.users
      self.user_manager.update_address_for_user(address,postcode)
      #self.display_queue.put(self.user_manager.get_users())
    elif macaddr not in self.nearby_devices:
      if self.check_address(address) is False:
        self.nearby_devices[address]=postcode
    


Answer: When I add enough around your code to get it to run, it works for me at least
as far as getting an `AttributeError: 'module' object has no attribute
'strptime'` where you have mixed the `datetime` module with the `datetime`
class within that module.

Not a lot of help I know, but I suspect the problem must lie outside the code
you posted. `user_timer` sees the update to `user_manager.users` just fine:

    
    
    import threading
    import datetime
    
    REFRESH_RATE=10.0
    MAX_SECONDS=30
    
    class user:
        def __init__(self, properties):
            self.properties = properties
    
        def get_first_seen(self):
            return 42
    
    class user_manager:
      users={}
      def __init__(self,queue,sign_properties):
    
        self.properties=sign_properties
        self.queue=queue
        self.lock=threading.Lock()
        t=threading.Thread(target=user_timer,args=(self.lock,))
        t.daemon=True
        t.start()
    
      def add_user(self,macaddr,user_properties):
        self.lock.acquire()
        user_manager.users[macaddr]=user(user_properties)
        self.lock.release()
    
      def user_exists(self, macaddr):
        if macaddr in user_manager.users:
          return True
        return False
    
      def update_rssi_for_user(self, macaddr,rssi):
        self.lock.acquire()
        user_manager.users[macaddr].update_rssi(rssi)
        self.lock.release()
    
      def get_users(self):
        return user_manager.users
    
    
    
    def user_timer(lock):
      while True:
        print 'Test'
        lock.acquire()
        print user_manager.users
        lock.release()
        format = '%H:%M:%S'
        for user in user_manager.users:
          first_seen=user_manager.users[user].get_first_seen()
          current_time=str(datetime.datetime.now().time())
          difference=datetime.strptime(current_time, format) - datetime.strptime(first_seen[1], format)
          print 'difference'+str(difference.seconds)
          if difference.seconds >30:
            user.expire()
            del user_manager.users[user]
        time.sleep(REFRESH_RATE)
    
    
    u = user_manager(None, None)
    u.add_user("1234", "Properties")
    raw_input()
    

Give me this output:

    
    
    C:\temp>c:\python27\python t.py
    Test
    {'1234': <__main__.user instance at 0x02583A80>}
    Exception in thread Thread-1:
    Traceback (most recent call last):
      File "c:\python27\lib\threading.py", line 810, in __bootstrap_inner
        self.run()
      File "c:\python27\lib\threading.py", line 763, in run
        self.__target(*self.__args, **self.__kwargs)
      File "t.py", line 55, in user_timer
        difference=datetime.strptime(current_time, format) - datetime.strptime(first_seen[1], format)
    AttributeError: 'module' object has no attribute 'strptime'
    
    Traceback (most recent call last):
      File "t.py", line 65, in <module>
        raw_input()
    KeyboardInterrupt
    

