Python 计时器线程作为 class 变量从不同的 class 实例调用 timer.start() 和 timer.cancel()

Python timer thread as class variable call timer.start() and timer.cancel() from different class instances

我对 python 有点陌生,对线程处理也很陌生。我正在尝试为客户端网络服务器接口编写客户端,并且我正在使用状态设计模式。我坚持使用 class 中的定时器对象作为 class 变量。我正在使用 threading.Timer class 实现该对象,但是在将 set_time 方法作为参数传递给构造函数时,我 运行 遇到了麻烦。如果我使用 threading.Timer(5.0, self.set_time) 我会收到 "NameError: name 'self' is not defined" 错误。如果我使用 threading.Timer(5.0, set_time) 我会收到 "NameError: name 'set_time' is not defined" 错误。下面是我的代码:

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

我用谷歌搜索并查看了 and Python threading.timer - repeat function every 'n' seconds。这些有帮助,但我仍然有两个问题。一个是笼统的,另一个更针对我的问题。

一:我应该如何实例化一个 class 变量,该变量使用引用 class.

中的方法的构造函数

二:如何将线程用作 class 变量以供从我的状态 class 继承的 classes 使用?例如,假设我有一个继承自 State 的 class Wait_For_Call。我实例化一个对象 wait_for_call = Wait_For_Call()。我可以只做 wait_for_call.start_timer() 或 wait_for_call.stop_timer() 吗?

一个: this question 中对此进行了讨论。 您可以使用模块变量(见下文)。

两个: 使用@classmethod 装饰器来声明一个class 方法。该方法的第一个参数(通常命名为 'cls')使您可以访问 class 个变量。

由于在回答您的第一个问题时,我建议使用模块变量(如我所引用问题的答案中所述),因此您不需要 class 方法或 class访问它的变量。如果您将其保留为 class 变量,您可能仍然需要它们来访问 timeout

在这里您可以看到如何从 class 方法中访问 class 变量:

class Base :
    my_number = 1

    @classmethod
    def class_method(cls):
        print (cls.my_number)
        cls.my_number = cls.my_number + 3