首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Mathematica中的可选命名参数

Mathematica中的可选命名参数
EN

Stack Overflow用户
提问于 2009-10-24 04:54:22
回答 3查看 3.3K关注 0票数 13

用可选的命名参数定义函数的最佳/规范方法是什么?为了更具体,让我们创建一个带有命名参数abc的函数foo,它们的缺省值分别为1、2和3。为了便于比较,这里有一个带有位置参数的foo版本:

代码语言:javascript
运行
复制
foo[a_:1, b_:2, c_:3] := bar[a,b,c]

以下是foo的命名参数版本的示例输入和输出

代码语言:javascript
运行
复制
foo[]                  --> bar[1,2,3]
foo[b->7]              --> bar[1,7,3]
foo[a->6, b->7, c->8]  --> bar[6,7,8]

当然,在命名参数之前使用位置参数也很容易。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-10-24 05:53:15

我在Mathematica文档中找到了这样做的标准方法:http://reference.wolfram.com/mathematica/tutorial/SettingUpFunctionsWithOptionalArguments.html

代码语言:javascript
运行
复制
Options[foo] = {a->1, b->2, c->3};  (* defaults *)
foo[OptionsPattern[]] := bar[OptionValue@a, OptionValue@b, OptionValue@c]

每次输入"OptionValue“都有点麻烦。出于某些原因,你不能只做一个像ov = OptionValue这样的全局缩写,但你可以这样做:

代码语言:javascript
运行
复制
foo[OptionsPattern[]] := Module[{ov},
  ov[x___] := OptionValue[x];
  bar[ov@a, ov@b, ov@c]]

或者这样:

代码语言:javascript
运行
复制
With[{ov = OptionValue},
  foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
]

或者这样:

代码语言:javascript
运行
复制
$PreRead = ReplaceAll[#, "ov" -> "OptionValue"] &;

foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
票数 12
EN

Stack Overflow用户

发布于 2010-02-19 14:40:22

是的,OptionValue可能有点棘手,因为它依赖于一种魔法,因此

OptionValue[name]相当于OptionValue[f,name],其中f是出现OptionValue[name]的转换规则左侧的头部。

添加一个显式的Automatic通常可以做到这一点,所以在您的例子中,我认为解决方案是:

代码语言:javascript
运行
复制
Options[foo] = {a -> 1, b -> 2, c -> 3};
foo[OptionsPattern[]] := 
  bar @@ (OptionValue[Automatic, #] &) /@ First /@ Options[foo] 

顺便说一句,选项过去是通过匹配opts:___?OptionQ,然后以{a,b,c}/.Flatten[{opts}]的形式手动查找选项值来完成的。模式检查OptionQ仍然存在(尽管没有文档记录),但OptionValue方法的优点是,您可以收到不存在的选项(例如foo[d->3])的警告。这也适用于您的第二个响应,但不适用于您已接受的响应。

票数 6
EN

Stack Overflow用户

发布于 2009-10-24 04:58:40

我将把这个可能的解决方案放入其中:

代码语言:javascript
运行
复制
foo[opts___Rule] := Module[{f},
  f@a = 1; (* defaults... *)
  f@b = 2;
  f@c = 3;
  each[a_->v_, {opts}, f@a = v];

  Return[bar[f@a, f@b, f@c]]
]

我喜欢它的简洁,但我不认为这是标准的方式。这样做有什么问题吗?

PS,它使用以下方便的实用函数:

代码语言:javascript
运行
复制
SetAttributes[each, HoldAll];                (* each[pattern, list, body]     *)
each[pat_, lst_, bod_] :=                    (*  converts pattern to body for *)
  Scan[Replace[#, pat:>bod]&, Evaluate@lst]  (*   each element of list.       *)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1615836

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档