0

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()?

3
  • You want them all to use one timer for all instances? Commented Nov 6, 2018 at 19:24
  • To clarify, when you say "refers to a method in the class", do you mean a static or non-static method (one that refers to instance variables would be a bit problematic to use when instantiating a class variable :-) ) Commented Nov 6, 2018 at 19:33
  • Yes, to use one timer for all instances. It would be a static method. Commented Nov 6, 2018 at 22:16

1 Answer 1

1

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
Sign up to request clarification or add additional context in comments.

3 Comments

This answers question 1 for me. But I'm still not sure how to use one thread for the class.
The suggestion in the linked question is to make it a module variable. Then there will be only one instance of it. I would think that there would be a way to make it a class variable, but if there is I have not found it.
That makes sense. The classmethod solved the more immediate of my problems. Thank you for your answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.