I am somewhat new to python and very new to threading. I am trying to write a client for a client-webserver interface and I am using the State design pattern. I am stuck on using a timer object inside my class as a class variable. I am implementing the object using the threading.Timer class, but I run into trouble when passing set_time method as an argument to the constructor. If I use threading.Timer(5.0, self.set_time) I get a "NameError: name 'self' is not defined" error . If I use threading.Timer(5.0, set_time) I get a "NameError: name 'set_time' is not defined" errror. Below is my code:
import time
import threading
import sys
from packet import Packet
from check import ip_checksum
class State():
timer = threading.Timer(5.0, self.set_time)
timeout = False
def __init__(self):
time = False
def time_out(self):
return time
def set_time(self):
global timeout
timeout = True
def start_timer(self):
timer.start()
def stop_timer(self):
global timeout
timer.cancel()
timeout = False
def send_packet(self, data):
print("Parent state send: " + data)
self.start_timer()
return True
def receive_packet(self, packet):
print("Parent state receive packet")
self.stop_timer()
return True
I googled and have looked at Python class instance vs. class variables and Python threading.timer - repeat function every 'n' seconds. These have have helped, but still I have two questions. One is in general , the other more specific to my issue.
One: how should I instantiate a class variable that uses a constructor that refers to a method in the class.
Two: how can I use a thread as a class variable to be used by classes that inherit from my State class? For example, say I have a class Wait_For_Call that inherits from State. I instantiate an object wait_for_call = Wait_For_Call(). Could I just do wait_for_call.start_timer() or wait_for_call.stop_timer()?
One: This is discussed in this question. You can use a module variable (see below).
Two: Use @classmethod decorator to declare a class method. The first parameter of the method (usually named 'cls') gives you access to the class variables.
Since, in the answer to your first question, I suggested using a module variable (as described in answers to the question I referenced), you do not need a class method or class variables to access it. You may still need them to access timeout
, if you keep it as a class variable.
Here you can see how to access a class variable from within a class method:
class Base :
my_number = 1
@classmethod
def class_method(cls):
print (cls.my_number)
cls.my_number = cls.my_number + 3