RuntimeWarning: включите tracemalloc, чтобы получить трассировку выделения объекта, как исправить?
Работаю с PyQt5. Делаю приложение для логирования. Возникает проблема с потоком и asyncio.
При нажатии на кнопку должна запуститься асинхронная функция, которая получает через условия в постоянном цикле файлы на проверку и выводит полученные данные.
Асинхронная функция, которую я вызываю через поток:
async def deathcount():
PLAYER_DEATH = '.*?Got character ZDOID from (\w+) : 0:0'
log = "c:/.../files/log.txt"
while True:
with open(log, encoding='utf-8', mode='r') as f:
f.seek(0,2)
while True:
line = f.readline()
if(re.search(PLAYER_DEATH, line)):
pname = re.search(PLAYER_DEATH, line).group(1)
with open(file, 'a', newline='', encoding='utf-8') as dl:
... ...
log(f"{gettime}{pname} умер!")
await asyncio.sleep(0.2)
PLAYER_DEATH - переменная, хранящая в себе строчку с регулярным выражением.
В постоянном цикле проверяется log.txt, на наличие строки из PLAYER_DEATH.
При нажатии на кнопку должна сработать функция deathcount(), которая в итоге, при положительном ответе, должна вывести результат - log(f"{gettime}{pname} умер!")
Результат выводится с помощью потока, там же и вызываем функцию (deathcount()):
basic.py:
class QTextEditLogger(logging.Handler):
def __init__(self, parent):
super().__init__()
self.PVELogs = QtWidgets.QPlainTextEdit(parent.centralwidget)
self.PVELogs.setGeometry(QtCore.QRect(40, 50, 801, 491))
font = QtGui.QFont()
font.setFamily("Consolas")
font.setPointSize(10)
self.PVELogs.setFont(font)
self.PVELogs.setStyleSheet("background-color: rgb(30, 30, 30); color: rgb(255, 255, 255);")
self.PVELogs.setReadOnly(True)
self.PVELogs.setPlainText("")
self.PVELogs.setObjectName("PVELogs")
def emit(self, record):
msg = self.format(record)
self.PVELogs.appendPlainText(msg)
class PVP(QtWidgets.QMainWindow, QWidget, MainInterface):
def __init__(self):
super().__init__()
self.setupUi(self) #init gui
# logging
logTextBox = QTextEditLogger(self)
#logTextBox.setFormatter(logging.Formatter(f'{gettime}%(message)s'))
logging.getLogger().addHandler(logTextBox)
logging.getLogger().setLevel(logging.DEBUG)
root_logger= logging.getLogger()
root_logger.setLevel(logging.DEBUG)
handler = logging.FileHandler('PVPLog.log', 'w', 'utf-8')
handler.setFormatter(logging.Formatter('%(name)s, %(asctime)s, [%(levelname)s], %(message)s'))
root_logger.addHandler(handler)
self.PVELogs.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
self.thread = WorkThread()
self.thread.threadSignal.connect(self.func2)
self.onPVE.clicked.connect(self.func1)
def func1(self):
self.thread.start()
def func2(self, value):
deathcount() # Вызываем функцию ! ! !
class WorkThread(QtCore.QThread):
threadSignal = QtCore.pyqtSignal(int)
def __init__(self):
super().__init__()
def run(self):
for i in range(10):
self.msleep(200)
self.threadSignal.emit(i)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
mw = PVP()
mw.show()
sys.exit(app.exec())
loop = asyncio.new_event_loop()
loop.create_task(deathcount())
asyncio.set_event_loop(loop)
В конце файла создал новый цикл событий, советуясь данной темы
В конце асинхронной функции стоит ожидание (await asyncio.sleep(0.2)).
Но в итоге всё равно что-то не так.
c:\..\..\..\programma\basic.py:132: RuntimeWarning: coroutine 'deathcount' was never awaited
deathcount()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Попробовал вызвать цикл в самой функции func2:
def func2(self, value):
loop = asyncio.new_event_loop()
loop.create_task(deathcount())
asyncio.set_event_loop(loop)
Уже другой результат, так ещё в приложение появились интересные строчки:
C:\Users\Stepan\AppData\Local\Programs\Python\Python39\lib\asyncio\base_events.py:667: RuntimeWarning: coroutine 'deathcount' was never awaited
self._ready.clear()
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Ответы (1 шт):
Вы совсем неправильно используете asyncio. И deathcount совсем не асинхронная. Тут серьезный пробел и нет смысла пересказывать, как работает и использовать asyncio.
Если коротко, то первая ошибка возникает, потому, что async функцию нужно вызывать используя await из цикла созданного с помощью asyncio.run или подобным образом.
Вторая ошибка (после попытки исправить) возникает из-за того, что попытка запустить asyncio цикл, неправильная. Смотрите как это делает asyncio.run тут.
Можно, конечно, подружить обычные потоки и asyncio, но я думаю вам не это нужно.
Создайте обычный QThread по аналогии с WorkThread и в нем вызывайте deathcount без всяких async/await.
Если вы хотите именно asyncio, то нужно задать отдельный сфокусированный вопрос, т.к. ответ будет довольно обширный.
