【问题标题】:writing command line for class methods using python and typer使用 python 和 typer 为类方法编写命令行
【发布时间】:2022-01-20 21:49:33
【问题描述】:

我正在使用 Typer 使用 python 编写命令行程序。

这是包的链接:https://typer.tiangolo.com/

这是我遇到麻烦的示例脚本。

import typer

app = typer.Typer()

@app.command()
def hello(name):
    typer.echo(f'Hello!')

@app.command()
def goodbye():
    typer.echo(f'Goodbye.')

class Grettings:

    @app.command()
    def aloha(self):
        typer.echo('Aloha!')

    @app.command()
    def bonjour(self):
        typer.echo('Bonjour!')

if __name__ == '__main__':
    app()

当以下命令输入终端时,会给出预期的输出。

$ python main.py 你好
$ python main.py 再见

但是,当调用类方法时,出现以下异常。

$ python main.py aloha
$ python main.py 你好

Usage: main.py aloha [OPTIONS] SELF
Try 'main.py aloha --help' for help.

Error: Missing argument 'SELF'.

显然,这是来自尚未初始化的类。但这似乎是一个常见问题,所以我认为这个问题有一个简单的解决方案。我发现的可能解决方案包括在正在使用的类/方法上使用装饰器,或者使用需要继承的特殊类以“公开”类方法。
Can a decorator of an instance method access the class?

https://stackoverflow.com/questions/2366713/can-a-decorator-of-an-instance-method-access-the-class#:~:text=Any%20decorator%20is%20called%20BEFORE,any%20necessary%20post%2Dprocess%20later.

任何帮助表示赞赏。谢谢。

【问题讨论】:

  • 使其成为静态方法,则不需要类实例。
  • 这不是一件特别明智的事情。 typer 必须知道如何创建该类的实例,而这确实是您的工作。您只需要一个短垫片方法:@app.command/def aloha():/Grettings().aloha()

标签: python command-line-interface typer


【解决方案1】:

装饰实例方法的问题

Typer 尝试以Grettings().aloha() 调用回调。 这将在 Python 中失败并出现错误:

TypeError: hallo() 缺少 1 个必需的位置参数:'self'

Typer 中的命令调用演示

请看以下 Python shell 中记录的演示:

第 1 部分:它是如何工作的(使用静态函数,没有 self 参数)

>>> import typer
>>> app = typer.Typer()
>>> app
<typer.main.Typer object at 0x7f0713f59c18>
>>> app.__dict__
{'_add_completion': True, 'info': <typer.models.TyperInfo object at 0x7f0713f59c50>, 'registered_groups': [], 'registered_commands': [], 'registered_callback': None}
>>> @app.command()
... def hello():
...     typer.echo('hello')
... 
>>> app.__dict__['registered_commands']
[<typer.models.CommandInfo object at 0x7f0711e69cf8>]
>>> app.__dict__['registered_commands'][0].cls
<class 'typer.core.TyperCommand'>
>>> app.__dict__['registered_commands'][0].callback
<function hello at 0x7f070f539378>
>>> app.__dict__['registered_commands'][0].callback()
hello

第 2 部分:它是如何工作的(使用实例方法,需要 self 参数)

>>> class German:
...     @app.command()
...     def hallo(self):
...         typer.echo('Hallo')
... 
>>> app.__dict__['registered_commands'][1]
<typer.models.CommandInfo object at 0x7f070f59ccf8>
>>> app.__dict__['registered_commands'][1].callback
<function German.hallo at 0x7f070f539158>
>>> app.__dict__['registered_commands'][1].callback()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: hallo() missing 1 required positional argument: 'self'
>>> app.__dict__['registered_commands'][1].callback(German())
Hallo

注意:在最后一条语句中,我将一个新实例作为参数 self 传递给回调,调用成功并获得预期输出。

固定代码

我改变了三件事:

  1. 将您的班级 Grettings 重命名为 Greetings(拼写)
  2. 将 2 个现有方法重新定义为静态类方法,例如 Barmar's comment suggested
  3. 另外我添加了一个新的实例方法nihao(self)来演示失败。
import typer

app = typer.Typer()


@app.command()
def hello(name):
    typer.echo(f'Hello!')

@app.command()
def goodbye():
    typer.echo(f'Goodbye.')

class Greetings:
    @app.command()
    def aloha():              # function or class-method (implicitly static)
        typer.echo('Aloha!')

    @staticmethod             # explicitly static
    @app.command()
    def bonjour():            # no self argument!
        typer.echo('Bonjour!')

    @app.command()
    def nihao(self):          # callback invocation fails because missing self argument
        typer.echo('Nihao!')


if __name__ == '__main__':
    app()

行为和输出符合预期

尽管提供的命令仍将nihao 列为可用,但调用它的失败与您所经历的一样。

但是现在可以调用命令修饰的静态方法。

$ python3 SO_typer.py --help
Usage: SO_typer.py [OPTIONS] COMMAND [ARGS]...

Options:
  --install-completion [bash|zsh|fish|powershell|pwsh]
                                  Install completion for the specified shell.
  --show-completion [bash|zsh|fish|powershell|pwsh]
                                  Show completion for the specified shell, to
                                  copy it or customize the installation.

  --help                          Show this message and exit.

Commands:
  aloha
  bonjour
  goodbye
  hello
  nihao

??️ 中文问候语失败,因为没有参数 self 通过调用传递:

$ python3 SO_typer.py nihao
Usage: SO_typer.py nihao [OPTIONS] SELF
Try 'SO_typer.py nihao --help' for help.

Error: Missing argument 'SELF'.

??????夏威夷问候语有效,因为现在可以进行静态调用:

$ python3 SO_typer.py aloha
Aloha!

另见

【讨论】:

    猜你喜欢
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-05
    • 1970-01-01
    • 2023-03-05
    • 2017-09-08
    • 2020-07-21
    相关资源
    最近更新 更多