如何在Python 3.6中将我的子命令拆分为多个文件,然后单击7.1.2



为了更清楚起见,我想在不同的文件中实现每个子命令
现在我只有一个,但我的想法是随着时间的推移增加更多。

为此,我尝试了两种方法,结果以一次大失败告终。。。

基本上,我试图得到这样的结果:

$ test_cli
Usage: test_cli [OPTIONS] COMMAND [ARGS]...
Cli command
Options:
--help  Show this message and exit.
Commands:
test  Test command.

$ test_cli test hello
Hello !

以下是文件

$ tree
.
├── cli.py
├── setup.py
└── test.py

我正在使用virtualenv,并使用以下命令来测试我的应用程序:

$ pip install --editable .

setup.py的代码对两者都是相同的:

from setuptools import setup
setup(
name = 'test_cli',
version = '1.0',
py_modules = [ 'cli', 'test' ],
install_requires = [
'Click',
],
entry_points = '''
[console_scripts]
test_cli=cli:cli
''',
)

尝试1-失败

基于此链接的代码,但它不适用于我…

以下是每个文件的代码:

cli.py

import click
import test
@click.group()
def cli():
''' Cli command '''
pass
cli.add_command(test)

测试.py

import click

@click.group()
def test():
''' Test command. '''
pass

@test.command()
def hello():
click.echo('Hello !')

这是我的错误:

Traceback (most recent call last):
File "/tmp/myenv/bin/test_cli", line 33, in <module>
sys.exit(load_entry_point('test-cli', 'console_scripts', 'test_cli')())
File "/tmp/myenv/bin/test_cli", line 25, in importlib_load_entry_point
return next(matches).load()
File "/tmp/myenv/lib/python3.6/site-packages/importlib_metadata/__init__.py", line 105, in load
module = import_module(match.group('module'))
File "/usr/lib64/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/tmp/toto/cli.py", line 9, in <module>
cli.add_command(test)
File "/tmp/myenv/lib/python3.6/site-packages/click/core.py", line 1347, in add_command
name = name or cmd.name
AttributeError: module 'test' has no attribute 'name'

尝试2-失败

这次我在这里找到了一个代码。我没有任何错误,但我无法执行任何子命令:-/

cli.py

import click
import test
@click.group()
def cli():
''' Cli command '''
pass

导入单击导入cli

测试.py

import click
import cli
@cli.group()
def test():
''' Test command. '''
pass
@test.command()
def hello():
click.echo('Hello !')

当我执行尝试执行子命令时,我会遇到以下问题:

$ test_cli test hello
Usage: test_cli [OPTIONS] COMMAND [ARGS]...
Try 'test_cli --help' for help.
Error: No such command 'test'.

你知道这个问题吗
谢谢。

最简单的方法是为CLI实现一个单独的.py文件并将函数导入其中

控制台.py

import click
from .main import store, retrieve
@click.group()
def cli():
pass
@cli.command(no_args_is_help=True)
(series of @click.arguments)
def store(application, key, expiration, userdata):
# sends the arguments directly to the "store" function in main.py
store(application,key,expiration,userdata)
(other commands)
if __name__ == '__main__':
cli()

以及在main.py 中

def store(app, key, expiration, userdata):
"""Program for a user to submit a user-generated API key to their database."""
# The actual function doing its work, in a separate file

此方法将CLI设置与实际代码分离,同时允许完全访问所有单击功能,包括组、子命令等。它还允许您从许多不同的模块调用命令,甚至可以在CLI中调用外部命令(例如,如果您想要一个将各种程序包中的多个函数组合在一起的CLI,则不讨论这种行为是否合适(。

在第一个示例中,您需要将测试组导入到模块中。

cli.py

import click
from test import test 

@click.group()
def cli():
''' Cli command '''
pass

cli.add_command(test)
if __name__ == '__main__':
cli()

测试.py

import click

@click.group()
def test():
''' Test command. '''
pass

@test.command()
def hello():
click.echo('Hello !')

相关内容

最新更新