【问题标题】:returning another class when instantiating a class in python在python中实例化一个类时返回另一个类
【发布时间】:2012-03-26 20:07:35
【问题描述】:

我正在尝试使用日志记录的memory handler 将日志消息缓冲到我的实际日志记录处理程序。您可以通过使用一些参数对其进行实例化来使用内存处理程序,如下所示:

import logging
buffered_handler = logging.handlers.MemoryHandler(capacity=5,target=myActualHandler)

但是,我不希望我的应用程序必须直接从日志记录实例化处理程序,或者传递任何参数;我希望这段代码看起来像这样:

import myhandlers
buffered_handler = myhandlers.BufferedRemoteHandler()

问题是:我该怎么做?我想尝试将我的BufferedRemoteHandler 实例化为实际上 返回带有一些特定参数的日志记录的 MemoryHandler。我只想让BufferedRemoteHandler 成为一个返回我想要的处理程序的函数;这是正确的方法吗?有没有办法创建一个类,当你实例化它时,它实际上返回一个完全不同的类?

【问题讨论】:

    标签: python oop metaprogramming


    【解决方案1】:

    也许 PEP 8 的第 3 点就是答案:

    Simple is better than complex.
    

    我会去功能的方式。也许可以称它为get_handler()(或get_buffered_remote_handler())之类的东西,所以乍一看你会发现它不是真正的课程。

    【讨论】:

    • 通常这种类型的函数称为工厂函数。在这种情况下,您可以将其称为 Handler Factory
    【解决方案2】:

    要回答您的确切问题,如果您愿意,可以在您的子类上覆盖 __new__() 以返回一个与您不同的类的实例。

    import logging
    
    class BufferedRemoteHandler(object):
       def __new__(cls):
           return logging.handlers.MemoryHandler(capacity=5,target=myActualHandler)
    

    但我实际上建议使用该功能。

    【讨论】:

    • 感谢您回答问题!这看起来很优雅;推荐功能路线除了简单还有其他原因吗?
    • @Igor,最小惊讶原则怎么样?
    • 我同意。返回某个其他类的实例对于类实例化操作来说是一种令人惊讶的结果。
    【解决方案3】:

    是的,只是让它成为一个函数。 getMemoryHandler() 之类的东西。这是最好的方法。此外,如果周围只有一个 MemoryHandler 实例,您可能希望将其设为单例。

    【讨论】:

    • 本例中的单例已经是 logging 模块本身;您使用处理程序和设置设置一次,随后的每个实例化/导入都使用这些。
    【解决方案4】:

    嗯,直接回答你,是的,有__new__()。但是,我认为更简单的解决方案可能是硬编码或允许将特殊处理程序定义注册到 myhandlers。您可以在 myhandlers 中为您想要的每个处理程序定义一个成员方法,该方法只是根据需要实例化 MemoryHandler 并返回它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 2015-08-26
      • 1970-01-01
      • 2013-02-23
      相关资源
      最近更新 更多