跳转到主要内容

提供对click的即插即用替换,扩展其在各种面向对象上下文中的应用

项目描述

objclick

pypi python versions documentation pipeline status

objclickclick提供即插即用替换,将其扩展到各种面向对象上下文。

click是一个非常好的包,可以通过在实现命令“主”功能的函数上堆叠装饰器,以声明式的方式快速轻松地定义可组合的命令行界面。

然而,按照设计,它不适合面向对象上下文。特别是,将类的一个实例方法提升为click命令并不容易。这个包通过提供与click一起良好工作的包装器来尝试解决这个问题,在某些情况下也能与类良好协作。

为了给出一个有说服力的例子,假设你有一个实现了CLI的基类

>>> import objclick as click
>>> import abc
>>> class BaseService(metaclass=abc.ABCMeta):
...     def explain(self):
...         """Explain this service; must be implemented by subclasses."""
...
...     @click.command()
...     def main(self):
...         print('Hello, let me tell you about myself.')
...         self.explain()
...

这个类现在必须通过实现explain来子类化,但子类无需重新实现其余的CLI

>>> class MyService(BaseService):
...     def explain(self):
...         print(f'I am an instance of {self.__class__.__name__}.')
...

由于MyService.main是一个实例方法,我们无法简单地调用MyService.main()来运行CLI的“主”函数。就像类的一个普通实例方法一样,我们必须首先实例化类,然后在实例上调用该方法

>>> service = MyService()
>>> service.main([], standalone_mode=False)
Hello, let me tell you about myself.
I am an instance of MyService.

(注意:standalone_modeclick主函数的一个标准参数,对于测试命令非常有用。)

这个包的初始版本仍然是实验性的,但它实现了许多其他有用的案例。

其中一种情况由classgroup装饰器给出。它允许在一个类似于类方法的类方法上定义命令组,这个方法绑定到类而不是类的实例。在常见的类方法实现类的一个替代构造函数的情况下,如果类组返回它定义的类的实例,那么这个实例将作为参数传递给任何作为组子命令添加的实例方法的self参数。

例如,这里是一个带有--config选项的命令组,因为需要配置来实例化Service类。然后,所有Service.main的子命令都可以访问配置

>>> import objclick as click
>>> import json, pprint
>>> class Service:
...     def __init__(self, config):
...         """Instantiate `Service` with a configuration dict."""
...
...         self.config = config
...
...     @click.classgroup()
...     @click.option('--config', type=click.File())
...     def main(cls, config=None):
...         if config is not None:
...             with config as f:
...                 config = json.load(f)
...         else:
...             config = {}
...
...         print(f'Starting up {cls.__name__}...')
...         return cls(config)
...
...     @main.command()
...     def show_config(self):
...         print('Config:', end=' ')
...         pprint.pprint(self.config)
...

现在可以通过以下方式调用由Service定义的CLI

>>> import tempfile
>>> config = {'option1': 'a', 'option2': 'b'}
>>> with tempfile.NamedTemporaryFile(mode='w') as f:
...     json.dump(config, f)
...     f.flush()
...     # like `service.py --config <config-file> show-config`
...     args = ['--config', f.name, 'show-config']
...     Service.main(args, standalone_mode=False)
...
Starting up Service...
Config: {'option1': 'a', 'option2': 'b'}

objclick 更新日志

v0.1.1 (2020-10-02)

错误修复

  • 修复了在子类中通过super()调用classcommandclassgroup回调的错误。

v0.1.0 (2020-10-01)

  • 首次发布。

项目详情


下载文件

下载适合您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分布

objclick-0.1.1.tar.gz (14.1 kB 查看散列)

上传时间

构建分布

objclick-0.1.1-py3-none-any.whl (10.1 kB 查看散列)

上传时间 Python 3

由以下组织支持