You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取purrr部分应用函数的真实形参并转为常规函数?

解决purrr::partial生成函数的形参获取问题

purrr::partial生成的部分应用函数本质是一个闭包,它用...来接收剩余参数,所以直接调用formals()只能看到...,无法获取原函数中未被绑定的真实形参。要将其转换为保留剩余形参的常规函数,可以通过以下方法实现:

自定义转换函数

我们可以从partial函数的闭包环境中提取原函数和已绑定的参数,然后构造一个带有剩余形参的新函数:

library(purrr)
library(rlang)

partial_to_regular <- function(partial_fn) {
  # 从闭包环境中获取原函数和已绑定参数
  env <- environment(partial_fn)
  original_fn <- env$.f
  bound_args <- env$...
  
  # 提取原函数中未被绑定的形参
  original_formals <- formals(original_fn)
  remaining_formals <- original_formals[!names(original_formals) %in% names(bound_args)]
  
  # 构造新函数的执行体:调用原partial函数并传递参数
  new_body <- expr({
    do.call(!!partial_fn, as.list(environment()))
  })
  
  # 创建新的常规函数
  new_fn <- function() {}
  formals(new_fn) <- remaining_formals
  body(new_fn) <- new_body
  environment(new_fn) <- environment(partial_fn)
  
  new_fn
}

测试示例

用你的代码测试这个转换函数:

# 定义原函数
a <- function(x=2,y=2) {return(list(x,y))}
# 创建部分应用函数
b <- purrr::partial(a,x=3)
# 转换为常规函数
c <- partial_to_regular(b)

# 查看形参,符合预期
formals(c)
#> $y
#> [1] 2

# 调用测试
c()
#> [[1]]
#> [1] 3
#> 
#> [[2]]
#> [1] 2

c(y=5)
#> [[1]]
#> [1] 3
#> 
#> [[2]]
#> [1] 5

原理说明

purrr::partial生成的闭包会在内部环境中保存原函数(.f)和已绑定的参数(...),调用时通过...接收剩余参数并合并后传递给原函数。我们的转换函数:

  1. 从闭包环境中提取原函数和已绑定参数
  2. 筛选出原函数中未被绑定的形参,作为新函数的形参
  3. 构造新函数的执行逻辑,将新函数的参数传递给原partial函数

这样得到的新函数就是带有真实剩余形参的常规函数,完全满足你的需求。

内容的提问来源于stack exchange,提问作者Fredrik Nylén

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:01:06