注意:我的问题可能是重复的或不必要的,或者我什至可能一直都是错的。但我无法搜索它,因为它是一个兔子洞,我需要有人的建议。
嗨,这是我第一次使用其他模块和类的继承。因此,每当我创建一个继承自定义良好的类(如
tkinter.Frame
、pandas.Dataframe
或 sqlite3.Connection
)的子类时,我都会获得带有类型提示的所有参数(我正在使用 vscode
并按tab
它会自动完成def __init_
并生成它们)。但类型命中总是被破坏,尤其是省略号...
。
我知道它可以通过导入类型提示来解决 如果存在
TypeVar
或 TypeAlias
,或者完全删除它们,甚至删除所有我并不真正需要的额外参数请使用 *args, **kwargs
来代替。
但我不想这样
我希望我的子类以与超类相同的方式运行,并且仅扩展其功能。我发现带有类型提示的明确参数可以更好地使用类及其功能。
示例:
import tkinter
from tkinter import ttk
class MyFrame(ttk.Frame):
def __init__(self, master: tkinter.Misc | None = ..., *, border: tkinter._ScreenUnits = ...,
borderwidth: tkinter._ScreenUnits = ..., class_: str = ..., cursor: tkinter._Cursor = ...,
height: tkinter._ScreenUnits = ..., name: str = ..., padding: _Padding = ...,
relief: tkinter._Relief = ..., style: str = ..., takefocus: tkinter._TakeFocusValue = ...,
width: tkinter._ScreenUnits = ...) -> None:
super().__init__(master, border, borderwidth, class_, cursor, height, name,
padding, relief, style, takefocus, width)
在此示例中,所有省略号都会导致问题,并且某些类型提示不会显示。例如
_Padding
。
并用此类运行正常代码会引发此错误:
AttributeError: module 'tkinter' has no attribute '_ScreenUnits'
或者
AttributeError: module 'tkinter' has no attribute '_Cursor'
如果我决定删除所有类型提示,我会因为省略号而收到此错误。
TypeError: can only concatenate str (not "ellipsis") to str
意味着 ...
正在作为 str
值传递
正如我所说,我知道我可以用其他方式修复它,但是有没有一种简单的方法可以从超类继承类型提示,而不破坏我的代码?
还是我做错了什么??
这应该对你有用:)
import tkinter
from tkinter import ttk
from typing import ParamSpec, TypeVar, Callable
_P = ParamSpec("_P")
_T = TypeVar("_T")
def inherit_signature_from(
_to: Callable[_P, _T]
) -> Callable[[Callable[..., _T]], Callable[_P, _T]]:
"""Set the signature checked by pyright/vscode to the signature of another function."""
return lambda x: x # type: ignore
class MyFrame(ttk.Frame):
@inherit_signature_from(ttk.Frame.__init__)
def __init__(self, *args, **kwargs) -> None:
# do stuff?
super().__init__(*args, **kwargs)
VSCode 现在会认为
MyFrame.__init__
与 ttk.Frame.__init__
具有相同的签名/参数,并相应地检查它们。