如何在类方法中使用Python @click命令装饰器?

6rqinv9w  于 2023-02-20  发布在  Python
关注(0)|答案(1)|浏览(163)

我的Python脚本有一个名为Command的类,我想用CLI命令调用类的方法(类似于python cli-comand.py net get-public-ip)。
我使用了Python click库,但是当我试图执行它时,它抛出了错误TypeError: get_public_ip() missing 1 required positional argument: 'self'
正如预期的那样,我无法传递self。有没有办法将参数传递到类方法中,或者其他方法?click主要用于函数。
我的Python脚本如下所示:

cli-command文件名.py

import click
import urllib.request
from typing import List, AnyStr
from urllib.error import URLError

from ttn_cli.utils.constants import FETCH_PUBLIC_IP_URL

@click.group()
def cli():
    """
    This is the root function of cli module.
    """
    pass

@cli.group()
def net():
    """
    function act as a group which is linked to root cli function.
    """
    pass

class Command:

    def __init__(self):
        pass

    @net.command()  #  <-- click command
    def get_public_ip(self, *args) -> AnyStr:  # I want to use this method as a cli command
        """
        Function used to get public ip of your host.
        args: List of arguments provided
        """
        try:
            ip = urllib.request.urlopen(FETCH_PUBLIC_IP_URL).read().decode(
                "utf-8")
            return ip
        except URLError:
            return "Please check your internet connectivity"

cmd_network = Command()

def main() -> None:
    """
    This is the main function which returns a shell to user as well
    as can run cli commands directly.
    """
    cli()

if __name__ == "__main__":
    main()
qkf9rpyu

qkf9rpyu1#

这是对一个老问题的迟来的回答,但我希望将来有人会发现它有用。
您可以使用两个装饰器来帮助您实现这一点:

  • click.pass_context应用于一个组,该组将为其提供一个上下文,您可以在该上下文上创建Command类的示例。
  • click.pass_obj应用于将该示例作为第一个参数传递的类的方法。

在您的示例中,它将如下所示:

import click

@click.group()
def cli():
    pass

@cli.group()
@click.pass_context
def net(ctx):
    ctx.obj = Command()

class Command:
    @net.command()
    @click.pass_obj
    def get_public_ip(self, *args):
        ...

def main() -> None:
    cli()

if __name__ == "__main__":
    main()
    • 注:**
  • 它假设您有某种理由使用main函数,因为否则您可以直接在if __name__ == "__main__"块中调用cli()
  • 这是在click8.1.3中测试过的,我不知道装饰器是在哪个版本中引入的。

相关问题