我想為我的應用程式構建一個具有嵌套功能的 cli 界面。例子:
├── ...
├── setup.py
└── package-name
├──__init__.py
├──command1.py
└──command2.py
package-name command1 --arg .. ..
package-name command2 --arg ..
和
python -m package-name command1 --arg ..
這里要注意的是,command1andcommand2是接受不同命令列引數的獨立模塊。因此,將它們連接在一起__main__.py也可能是另一個挑戰。
我遇到了類似的問題,這些問題entry_points用于setup.py創建類似的 cli 功能,但這并不是我想要的。我發現了這個類似的問題。
如何在 Python 中創建可以使用 PIP 安裝的 CLI?
uj5u.com熱心網友回復:
如果你想在一個入口命令中訪問多個子cli,你可以在 處實作一個子命令管理器__main__.py,它可以從 sys.argv 決議子命令,然后分發到目標模塊。
1??首先,我推薦google fire,它可以在大多數情況下滿足您的需求,無需額外的代碼。
這里是一個例子,你可以使用 替換你的子命令函式的加法/乘法函式from command1 import xx,并使用入口點來暴露主函式。
import fire
def add(x, y):
return x y
def multiply(x, y):
return x * y
def main():
fire.Fire({
'add': add,
'multiply': multiply,
})
if __name__ == '__main__':
main()
我們可以通過以下相同的方式進行除錯:
$ python example.py add 10 20
30
$ python example.py multiply 10 20
200
2??其次,如果您出于某種目的需要自己實作,例如使用argparse為每個命令定義選項。一個典型的做法是Django命令,官方demo:Writing custom django-admin commands
核心步驟是:
- 定義一個 BaseCommand
- 在子 commands.py 中實作 BaseCommand,并將其命名為
Command. __main__.py實作 find 命令和呼叫
# base_command.py
class BaseCommand(object):
def create_parser(self, prog_name, subcommand, **kwargs):
"""
Create and return the ``ArgumentParser`` which will be used to
parse the arguments to this command.
"""
# TODO: create your ArgumentParser
return CommandParser(**kwargs)
def add_arguments(self, parser):
"""
Entry point for subclassed commands to add custom arguments.
"""
pass
def run_from_argv(self, argv):
"""
Entry point for commands to be run from the command line.
"""
parser = self.create_parser(argv[0], argv[1])
options = parser.parse_args(argv[2:])
cmd_options = vars(options)
args = cmd_options.pop('args', ())
self.handle(*args, **cmd_options)
def handle(self, *args, **options):
"""
The actual logic of the command. Subclasses must implement
this method.
"""
raise NotImplementedError('subclasses of BaseCommand must provide a handle() method')
# command1.py
class Command(BaseCommand):
def handle(self, *args, **options):
print("Hello, it is command1!")
# command2.py
class Command(BaseCommand):
def handle(self, *args, **options):
print("Hello, it is command2!")
# __main__.py
def main():
# sub command name is the second argument
command_name = sys.argv[1]
# build sub command module name, and import
# package-name is the module name you mentioned
cmd_package_name = f'package-name.{command_name}'
instance = importlib.import_module(cmd_package_name)
# create instance of sub command, the Command must exist
command = instance.Command()
command.run_from_argv(sys.argv)
if __name__ == "__main__":
main()
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/475047.html
標籤:Python python-3.x
上一篇:從日志檔案中查找延遲最低的用戶
