如何实现PowerShell参数展开与Python *args、**kwargs类似的效果
PowerShell复刻Python参数展开与链式传递问题
Python与PowerShell均支持将数组和命名参数展开作为函数输入,这是一项实用功能,但PowerShell的内部表现存在一定不一致性。以下是尝试用PowerShell复刻Python参数展开行为的过程及问题:
Python示例代码
def echoName(Name, *args, **kwargs): print("Name is:", Name) def wrapper(*args, **kwargs): print("args:", args) print("kwargs:", kwargs) echoName(*args, **kwargs) d = { "Name": "John", "Age": 25 } wrapper(**d) # 输出: # args: () # kwargs: {'Name': 'John', 'Age': 25} # Name is: John
尝试的PowerShell代码
在PowerShell高级函数中,ValueFromRemainingArguments是接收剩余参数的常用方式,于是编写了如下代码:
function echoName { param( [CmdletBinding()] [string]$Name, [parameter(Mandatory = $False, ValueFromRemainingArguments = $True)] [Object[]] $Arguments ) Write-Host "Name is: $Name" } function wrapper { [CmdletBinding()] param( [parameter(Mandatory = $False, ValueFromRemainingArguments = $True)] [Object[]] $Arguments ) Write-Host "Arguments is: $Arguments" echoName @Arguments } $d = @{ Name = 'John' Age = 25 } wrapper @d # 输出: # Arguments is: -Name: John -Age: 25 # Name is: -Name:
遇到的疑问
- 参数被转换为数组形式;
- 命名参数被自动添加了
-前缀和:后缀; - 混合传递数组和哈希表时出现异常行为:
$a = @(1,2,3) wrapper @a @d # 输出: # Arguments is: 1 2 3 -Name: John -Age: 25 # Name is: 1
实现类似Python的链式参数传递方案
要实现Python式的位置参数、剩余位置参数、命名参数分离传递,需要利用PowerShell的参数绑定特性和$PSBoundParameters自动变量,而非用ValueFromRemainingArguments把所有参数混为一个数组:
修正后的核心代码
function echoName { [CmdletBinding()] param( [string]$Name, [parameter(ValueFromRemainingArguments = $true)] [object[]]$Args ) Write-Host "Name is: $Name" } function wrapper { [CmdletBinding()] param( [parameter(ValueFromRemainingArguments = $true)] [object[]]$Args ) # 提取命名参数,排除自动生成的Args键 $namedArgs = $PSBoundParameters.Clone() $namedArgs.Remove('Args') | Out-Null Write-Host "args: $Args" Write-Host "kwargs: $($namedArgs | Out-String)" # 分别传递位置参数和命名参数 echoName @Args @namedArgs } # 测试单一哈希表传递 $d = @{ Name = 'John'; Age = 25 } wrapper @d # 输出: # args: # kwargs: Name Value # ---- ----- # Name John # Age 25 # Name is: John # 测试混合数组和哈希表传递 $a = @(1,2,3) wrapper @a @d # 输出: # args: 1 2 3 # kwargs: Name Value # ---- ----- # Name John # Age 25 # Name is: 1
关键说明
- PowerShell中
@d(哈希表展开)会被解析为命名参数,数组@a展开则是位置参数; $PSBoundParameters自动变量会收集所有绑定到函数的命名参数,直接对应Python中的**kwargs;- 结合
ValueFromRemainingArguments收集剩余位置参数(对应Python的*args),再配合$PSBoundParameters传递命名参数,即可实现Python式的链式参数传递,同时解决参数格式混乱的问题。
内容的提问来源于stack exchange,提问作者Yorai Levi
相关产品推荐
相关产品推荐

