【问题标题】:Should I use a class when it only makes sense to have one instance?当只有一个实例有意义时,我应该使用一个类吗?
【发布时间】:2019-02-04 18:41:19
【问题描述】:

我是一名 Python 初学者,正在研究基于 this tutorial 的 Flask 视频服务器的设置。我有问题的代码用于初始化计算机网络摄像头并输出帧:

class Camera(object):
    thread = None  # background thread that reads frames from camera
    frame = None  # current frame is stored here by background thread
    last_access = 0  # time of last client access to the camera
    start_time = 0  # time at which the camera is started

    def __init__(self):
        """Start the background camera thread if it isn't running yet."""
        ...

    def get_frame(self):
        """Return the current camera frame."""
        ...

    @staticmethod
    def frames():
        """"Generator that returns frames from the camera."""
        ...

    @classmethod
    def _thread(cls):
        """Camera background thread."""
        ...

对我来说,为此使用一个类是没有意义的,因为 Camera 对象应该只有一个实例。因此,每次向服务器发出请求时,都会无缘无故地创建一个新对象。

我已经研究了重构它的可能方法。到目前为止我发现了什么:

  • 使用单例类,但在 Python 中似乎不推荐这样做
  • 将所有内容放在一个单独的模块中。然后所有的类变量都会变成全局变量,这从我读到的很糟糕

【问题讨论】:

  • 类属性对我来说似乎不对,应该是实例属性。
  • @Daniel 你可能是对的,但在原始代码中是这样写的
  • 使用相机模块或相机类主要是个人喜好问题。除了我们都喜欢上课。如果您使用import camera as cam,则全局变量问题并不是那么糟糕,因为您仍然需要使用模块别名cam 来限定变量。

标签: python class oop object


【解决方案1】:

创建一个您希望有一个实例的类并没有错。类是组织和划分代码的绝佳方式。您可以为此使用模块,但如果您正在为实际对象建模(并且“相机”当然似乎是一个对象),那么类是完成这项工作的正确工具。

此外,使用类可以更轻松地测试代码,因为您可以在测试用例中导入类并在程序本身之外与它进行交互。

【讨论】:

  • 我理解你的意思,但在这种情况下,“相机”不是我想要建模的实际对象。它主要用作包装与我的计算机网络摄像头相关的功能的一种方式
  • @Undead:我认为你正在分裂头发。您仍在为对象建模。它不一定是现实世界中的物理对象(即使它看起来是,因为你说它为你的网络摄像头包装了功能)。一个对象只是一个概念性的东西,它具有一组与之相关的行为和属性。
  • 你可能是对的......在这种情况下,对线程等使用类变量是否合适,还是应该使用实例变量?
  • @Undead:就个人而言,我会使用实例变量。
【解决方案2】:

创建一个类的一个很好的理由是在一个地方拥有所有的方法(将作为对象的属性)。这可以完全控制对象可能发生的动态,尤其是当您的程序变大时。一个引人注目的例子,可能是当你包括说,登录到你的代码并在类外的所有函数之上使用@get_log(对于你的类内的get_log() 包装方法)装饰器。此日志记录将提供必要的调试信息。

使用类对代码进行模块化可以补偿一个对象的内存使用带来的轻微开销,尤其是在长期代码维护、质量和控制是关键时。

【讨论】:

    猜你喜欢
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多