Python 透過 Click 仿 PowerShell 自動填充參數
在 Linux 上很少看到像 PowerShell 那樣依照位置自動填充參數的功能,但透過 Click,我們可以實現大約九成的相似效果。
動態填充的意思是可以給參數設置一個順序,這個順序會自動抓取未加前綴的變數,依序自動填入。舉個例子:
function DemoFunction {
Param(
[Parameter(Position = 0, Mandatory)]
[string]$Id,
[Parameter(Position = 1, Mandatory)]
[string]$Name
)
return $null
}
你可以通過以下的方式顛倒指定順序:
DemoFunction "CHG" -Id 777
這是一個非常方便的功能。接下來,我們看看如何在 Python 中實現類似的功能。
Python 自動參數填充
我們使用 Click,這是 Python 的一個第三方模組。
官方網站有詳細的文檔:Click Documentation (8.1.x)
以下示例分成兩個檔案:command1.py
和 setup.py
。
先來看 setup.py
,這是 Python 內建的功能,用來啟動代碼。
from setuptools import setup, find_packages
setup(
name='myapp',
version='0.1.0',
# packages=find_packages(),
py_modules=['command1'],
install_requires=[
'click',
],
entry_points={
'console_scripts': [
'myappcmd1=command1:pycli1',
],
}
)
接下來是 command1.py
。
import click
# 自動填入剩餘參數的函數閉包
def auto_fill_argument(required=False):
def callback(ctx, param, value):
if 'args' not in ctx.params:
ctx.params['args'] = ()
args = list(ctx.params['args'])
if value is None:
if args:
value = args.pop(0)
ctx.params['args'] = tuple(args)
elif required:
raise click.MissingParameter(param_hint=[f"--{param.name}", f"-{param.opts[1]}"])
ctx.params['args'] = tuple(args)
return value
return callback
# 自定義命令類以實現多餘參數檢查
class AddWithExtraArgsCheck(click.Command):
def invoke(self, ctx):
if 'args' in ctx.params and ctx.params['args']:
params_info = ", ".join(f"{param}: {value if value is not None else ''}" for param, value in ctx.params.items() if param != 'args')
extra_args = " ".join(ctx.params['args'])
raise click.UsageError(
f"Got unexpected extra arguments ({extra_args})"
f", already assigned ({params_info})",
ctx=ctx
)
return super().invoke(ctx)
# 宣告選項群
@click.group()
def pycli1():
pass
# 選項命令1:: upload
@pycli1.command(cls=AddWithExtraArgsCheck)
@click.option('--identity', '-id', type=str, callback=auto_fill_argument(required=True), help="指定雲端文件夾的 ID")
@click.option('--name', '-n', type=str, callback=auto_fill_argument(required=True), help="指定文件路徑")
@click.option('--type', '-t', type=click.Choice(['any', 'folder', 'file'], case_sensitive=False), default='any', help="指定路徑類型: any (預設), folder, file")
@click.argument('args', nargs=-1)
def upload(identity, name, type, args):
"""上傳文件到指定的雲端文件夾"""
click.echo(f"雲端文件夾ID:{identity}, 正在上傳文件:{name}, 路徑類型:{type}", err=False)
# 選項命令2:: getmyinfo
@pycli1.command()
def getmyinfo():
"""獲取我的信息"""
click.echo(f"執行 getmyinfo 動作,目前沒有任何參數", err=False)
if __name__ == '__main__':
pycli1()
使用範例:
myappcmd1 upload "C:\path\to\your\file.txt" -id 12345
如此一來,就可以實現自動參數填充的功能。
通過指定 callback=auto_fill_argument(required=True)
可以將參數標記為自動填入項目,並且可以進一步標記為必須項目。該參數可以為空,但至少要保留括號。
此外,通過在選項命令處指定 cls=AddWithExtraArgsCheck
,可以檢查是否有多餘的參數。這樣做的原因是,啟用 args
後會關閉原生的參數檢查功能,但如果不啟用 args
,又無法接收任意參數,所以只能這樣妥協使用。
沒有留言:
張貼留言