gpt4 book ai didi

python - 如何使用 __new__ 创建基于另一个类的实例的类?

转载 作者:行者123 更新时间:2023-12-01 00:22:18 26 4
gpt4 key购买 nike

我正在尝试根据另一个类的实例创建一个类。为此,我使用 __new__ 方法:

import logging

class Logger:
def __new__(cls):
logger = logging.getLogger('main')

# make a queue in a thread to put log messages in a PyQt text browser console
return logger

def close(self):
pass
# close the thread

def main():
logger = Logger()
# more things
logger.close()

if __name__ == '__main__':
main()

我收到一个属性错误:

AttributeError: 'Logger' object has no attribute 'close'

我的想法是创建一个类来包装从logging.getLogger('main')返回的实例,并且能够调用它的原始方法(如setLevel)并添加我自己的方法。

日志记录模块的使用对于我的问题来说并不重要,但它是我不知道如何在这种情况下使用子类化的一个例子。

我的问题是:

  1. 出了什么问题?如何在使用 __new__ 方法时完成这项工作?
  2. 我一直想更频繁地这样做。首先这是一件愚蠢的事情吗?什么是更好的方法?

最佳答案

您可能应该将它们子类化:

from logging import Logger

def MyLogger(Logger):

def close(self):
pass

if __name__ == "__main__":
logger = MyLogger("some_name")
logger.close()

也就是说,我不知道为什么您需要手动关闭记录器。它们将在对象删除时处理自己的关闭,退出 Python 时也会发生这种情况。如果您出于某种原因想中途删除它们,则可以毫无问题地从它们自己的结构中删除它们。

<小时/>

PyQt5

在评论中,OP 澄清说这适用于 PyQt5。这是我过去一年一直在使用的东西。

用于显示日志记录的小部件:

# my_package.gui.logwidget.py

from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QTextEdit
from PyQt5.QtCore import QSize

from my_package.logger import handler


class LogWidget(QTextEdit):
"""
Creates a simple textEdit widget that will automatically subscribe to the QLogger.
"""
# pylint: disable=R0903, R0201
def __init__(self, parent=None):
super().__init__(parent)
handler.recordReady.connect(self.append)
self.setReadOnly(True)
# For reasons mere mortals like me cannot imagine, to get a real Monospaced font,
# we need to set it on a font that doesn't exist.
font = QFont("MichaelMcDoesntExist")
font.setStyleHint(QFont.Monospace)
self.setFont(font)

def minimumSizeHint(self) -> QSize:
return QSize(800, 200)

实际记录器:

# my_package.logger.py

import logging

from PyQt5.QtCore import QObject, pyqtSignal


class QLogHandler(QObject, logging.Handler):
"""
QObject subclass of logging.Handler. Will emit the log messages so QObjects can listen to it to catch log
messages.

Signal:
recordReady:
Will emit a string that is the formatted log message.
"""
recordReady = pyqtSignal(str)

def emit(self, record):
self.recordReady.emit(self.format(record))

def __repr__(self):
return f"<{self.__class__.__name__} : {logging.getLevelName(self.level)}>"


handler = QLogHandler() # Global ref to connect to it's signals

Python 的内置 logging模块已经支持线程安全日志对象,因此要让它工作,您需要的只是拥有一个日志处理程序和任意数量的日志显示小部件。

关于python - 如何使用 __new__ 创建基于另一个类的实例的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58875605/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com