我在 FastAPI 上开发我的宠物项目,我想编写类似 django 的管理器(manage.py 及其命令)。我在这个 CLI 中使用 Typer,并且我的应用程序中的管理子模块具有以下结构:
...
./management
├── __init__.py
├── app.py
├── collector.py
└── commands
├── __init__.py
├── base.py
├── echo.py
└── runserver.py
所以,我有
app.py
作为管理CLI应用程序的构建器,collector.py
作为我的命令的导入器(当我创建新命令时,不要每次都进行手动导入。它使用来自importlib
的import_module)和子子-module commands
,包含我的所有命令及其界面。所有命令都应该实现 1 个方法 action
,所以我的问题如下:“如果该方法每个子类没有特定数量的参数,我如何指定带有操作方法的抽象 BaseCommand 类?(例如,echo
只有 echo 字符串参数,runserver
的端口为 int,主机为字符串和一些其他参数)”。 **kwargs
不是解决方案,因为 Pylance 将其标记为错误。例如,对于以下命令的实现:
# base.py
class BaseCommand(ABC):
@abstractmethod
def action(self, **kwargs: Any) -> Any:
pass
# echo.py
class Echo(BaseCommand):
def action(self, echo: str):
"""Common echo command. Just """
print(echo)
Pylance 向我显示以下错误:
Method "action" overrides class "BaseCommand" in an incompatible manner
Positional parameter count mismatch; base method has 2, but override has 2
因此,如果我的 CLI 应用程序结构不正确,那么另一个问题如下:“我应该如何构建我的应用程序?”
为了说服 Pyright(以及 Pylance)你所做的事情是合法的,你需要对事情做:
Echo.action
关键字(以适应父级中的 **kwargs
)Echo.action
中任意 kwargs(也适合父级中的 **kwargs
)这两个改变的结果是这样的:
class BaseCommand(ABC):
@abstractmethod
def action(self, **kwargs) -> Any:
pass
class Echo(BaseCommand):
def action(self, *, echo: str, **kwargs):
"""Common echo command. Just """
print(echo)
*
中的第一个action
表示:“此后的所有内容都仅限关键字”。
如果您不喜欢 IDE 告诉您
kwargs
在 Echo.action
中未使用,您可以将 **kwargs
替换为 **_
。