英文:
How to correctly type-hint a function with `pyqtSlot()` decorator inside `QRunnable` class?
问题
**状态**:
1. 我正在学习如何在`PyQt`库中使用并发/线程,来自[www.pythonguis.com][1]。下面是来自此教程的简化/部分代码。
2. 我希望在我的代码中使用严格的类型提示。但我从`mypy`得到了关于此代码的错误消息(显示在第二个源代码块中)。
**问题**:
- 在使用`pyqtSlot()`装饰器时,如何正确地给函数添加类型提示?
- `Superclass`(返回`None`)是什么,`Subclass`(返回`str|None`)在这种情况下是什么?
**我尝试解决的问题**:
- 我的自闭症使我无法接受在我的文本编辑器上显示错误。我浪费了太多时间来解决单行问题。我在互联网上找不到任何有用的信息。
- 定义(或者我应该说是`stub`文件)中说`pyqtSlot()`是:
`def pyqtSlot(*types, name: typing.Optional[str] = ..., result: typing.Optional[str] = ...) -> typing.Callable[..., typing.Optional[str]]: ...`,由于我对装饰器没有经验,无法解释这个。
- `stub`文件:`QtCore.pyi`中说`Class QRunnable`的`run`是:`def run(self) -> None: ...`。
$ mypy /tmp/tmp.py
/tmp/tmp.py:22: error: “run”的签名与超类型“QRunnable”不兼容 [override]
/tmp/tmp.py:22: note: 超类:
/tmp/tmp.py:22: note: def run(self) -> None
/tmp/tmp.py:22: note: 子类:
/tmp/tmp.py:22: note: str | None
在 1 个文件中找到 1 个错误(共检查了 1 个源文件)
编辑:
-
以下猜测是否正确?
pyqtSlot()
接受返回typing.Optional[str]
(即str | None
)的函数。也许这是“子类”?QRunnable
的方法run()
只返回None
。也许这是“超类”?- 在这种情况下,正确的问题是:如果“装饰器的返回值”和“函数的返回值”不同,如何使用装饰器?这是否是正确的问题?
<details>
<summary>英文:</summary>
**Status**:
1. I'm learning how to use concurrency/threads within `PyQt` library from here [www.pythonguis.com][1]. Below is the simplified/part of code from this tutorial.
2. I want strict type hinting in my code. And I'm getting error messages on this code from `mypy`. (Shown on the 2-nd source-code block).
**Question**:
- How to correctly type-hint the function while using `pyqtSlot()` decorator?
- What is `Superclass` (that return `None`), and what is `Subclass` (that returns `str|None`) in this case?
**What I tried to solve:**
- My autistic ass doesn't sit well with error is showing on my text-editor. And I wasted too much time to solve single line. I couldn't find anything useful on the internet.
- The definition (or should I say `stub` file) says `pyqtSlot()` is:
`def pyqtSlot(*types, name: typing.Optional[str] = ..., result: typing.Optional[str] = ...) -> typing.Callable[..., typing.Optional[str]]: ...`, I'm unable to interpret this due to no-experience on decorators.
- `stub` file: `QtCore.pyi` says that `Class QRunnable`'s `run` is: `def run(self) -> None: ...`.
```lang-python
from typing import Callable
from PyQt5.QtCore import QObject, QRunnable, pyqtSignal, pyqtSlot
import traceback
import sys
class WorkerSignal(QObject):
finished = pyqtSignal()
error = pyqtSignal(tuple)
result = pyqtSignal(object)
progress = pyqtSignal(int)
class Worker(QRunnable):
def __init__(self, fn: Callable[[], str]) -> None:
super(Worker, self).__init__()
self.fn:Callable[[], str] = fn
self.signals: WorkerSignal = WorkerSignal()
@pyqtSlot()
def run(self) -> None: # <====================== this line
try:
result: str = self.fn()
except Exception:
traceback.print_exc()
exctype, value = sys.exc_info()[:2]
self.signals.error.emit((exctype, value, traceback.format_exc()))
else:
self.signals.result.emit(result)
finally:
self.signals.finished.emit()
$ mypy /tmp/tmp.py
/tmp/tmp.py:22: error: Signature of "run" incompatible with supertype "QRunnable" [override]
/tmp/tmp.py:22: note: Superclass:
/tmp/tmp.py:22: note: def run(self) -> None
/tmp/tmp.py:22: note: Subclass:
/tmp/tmp.py:22: note: str | None
Found 1 error in 1 file (checked 1 source file)
EDIT:
-
Is the following guess correct?
pyqtSlot()
takes function that returnstyping.Optional[str]
(i.e.str | None
). Perhaps its thesubclass
?QRunnable
's methodrun()
only returnNone
, Perhaps it's thesuperclass
?- In this case, correct question would be: How to use decorator, if
decorator's return
andfunction's return
are different? Would this be the correct question?
答案1
得分: 2
除了类型提示,你不应该在QRunnable方法中使用pyqtSlot。
pyqtSlot装饰器仅在继承自QObject的类的方法中使用,而QRunnable不是。我已经审查了几个教程,它们诉诸于这种不好的实践,因为它不带来任何好处。
英文:
Other than the typehint you should not use pyqtSlot in a QRunnable method.
The pyqtSlot decorator is only used in methods of classes that inherit from QObject and QRunnable is not. I have reviewed several tutorials that resort to this bad practice since it does not bring any benefit.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论