Wolfram mathematica 从规则和/转换的好处是什么。在大型应用程序中选择OptionPattern[]和OptionValue?

Wolfram mathematica 从规则和/转换的好处是什么。在大型应用程序中选择OptionPattern[]和OptionValue?,wolfram-mathematica,mathematica-8,Wolfram Mathematica,Mathematica 8,旧习惯很难改掉,我意识到我一直在使用opts\uuuu规则模式匹配和类似thispoption/的结构。{opts}/。选项[myfunction]在我目前正在开发的非常大的软件包中。Sal Manango的“Mathematica Cookbook”提醒我,第6版后的实现方法是opts:options模式[]和option值[thispoption]。无论如何,这个软件包需要版本8,但多年来我从未改变过编写这种代码的方式 是否值得从我6版之前的做法中重构所有这些?是否有绩效或其他好处 问候 韦

旧习惯很难改掉,我意识到我一直在使用
opts\uuuu规则
模式匹配和类似
thispoption/的结构。{opts}/。选项[myfunction]
在我目前正在开发的非常大的软件包中。Sal Manango的“Mathematica Cookbook”提醒我,第6版后的实现方法是
opts:options模式[]
option值[thispoption]
。无论如何,这个软件包需要版本8,但多年来我从未改变过编写这种代码的方式

是否值得从我6版之前的做法中重构所有这些?是否有绩效或其他好处

问候

韦比娅

编辑:摘要

在回答这个问题时提出了很多好的观点,所以谢谢大家(当然还有一点)。总之,是的,我应该重构以使用
OptionsPattern
OptionValue
。(注意:
OptionsPattern
不是我以前使用的
OptionsPattern
),原因有很多:

  • 这是一个触摸更快(@Sasha)
  • 它可以更好地处理参数必须在
    HoldForm
    (@Leonid)中的函数
  • options模式
    会自动检查您是否正在向该函数传递有效的选项(
    FilterRules
    如果您要传递到另一个函数(@Leonid))则仍然需要
  • 它处理
    RuleDelayed
    :>
    )的能力要好得多(@rcollyer)
  • 它处理嵌套的规则列表,而不使用
    flant
    (@Andrew)
  • 使用
    OptionValue/@list
    分配多个局部变量比多次调用
    someoptions/{opts}/.Options[thisfunction]
    要容易一些(在@rcollyer和我之间的评论中出现)

  • 编辑:7月25日我最初认为使用
    /。
    语法的一次可能仍然有意义,那就是如果您有意从另一个函数中提取默认选项,而不是实际调用的选项。结果证明,这是通过使用
    OptionsPattern[]的形式来处理的
    中有一个标题列表,例如:
    选项模式[{myLineGraph,DateListPlot,myDateTicks,GraphNotesGrid}]
    (请参阅中的“更多信息”部分)。我最近才解决了这个问题。

    依赖模式匹配器似乎比使用
    patternetest
    产生更快的执行速度,因为后者需要调用求值器。无论如何,我的计时表明可以实现一些加速,但我认为它们并没有那么关键,不会促使重新分解

    In[7]:= f[x__, opts : OptionsPattern[NIntegrate]] := {x, 
      OptionValue[WorkingPrecision]}
    
    In[8]:= f2[x__, opts___?OptionQ] := {x, 
      WorkingPrecision /. {opts} /. Options[NIntegrate]}
    
    In[9]:= AbsoluteTiming[Do[f[1, 2, PrecisionGoal -> 17], {10^6}];]
    
    Out[9]= {5.0885088, Null}
    
    In[10]:= AbsoluteTiming[Do[f2[1, 2, PrecisionGoal -> 17], {10^6}];]
    
    Out[10]= {8.0908090, Null}
    
    In[11]:= f[1, 2, PrecisionGoal -> 17]
    
    Out[11]= {1, 2, MachinePrecision}
    
    In[12]:= f2[1, 2, PrecisionGoal -> 17]
    
    Out[12]= {1, 2, MachinePrecision}
    
    一个鲜为人知(但经常有用)的事实是,允许选项出现在嵌套列表中:

    In[1]:= MatchQ[{{a -> b}, c -> d}, OptionsPattern[]]
    
    Out[1]= True
    
    选项处理功能,如了解以下内容:

    In[2]:= FilterRules[{{PlotRange -> 3}, PlotStyle -> Blue, 
      MaxIterations -> 5}, Options[Plot]]
    
    Out[2]= {PlotRange -> 3, PlotStyle -> RGBColor[0, 0, 1]}
    
    考虑到:

    In[3]:= OptionValue[{{a -> b}, c -> d}, a]
    
    Out[3]= b
    
    但当然没有考虑到这一点:

    In[4]:= a /. {{a -> b}, c -> d}
    
    During evaluation of In[4]:= ReplaceAll::rmix: Elements of {{a->b},c->d} are a mixture of lists and nonlists. >>
    
    Out[4]= a /. {{a -> b}, c -> d}
    
    因此,如果使用,可能还应该使用OptionValue来确保可以使用用户传入的选项集

    另一方面,如果使用ReplaceAll(/),出于同样的原因,您应该坚持使用
    opts\uuuuu规则

    请注意,
    选择规则
    在某些情况下也有点过于宽容:

    无效选项:

    In[5]:= MatchQ[Unevaluated[Rule[a]], OptionsPattern[]]
    
    Out[5]= False
    
    但是
    \u规则
    允许它通过:

    In[6]:= MatchQ[Unevaluated[Rule[a]], ___Rule]
    
    Out[6]= True
    

    更新:正如rcollyer所指出的,
    \uuuu规则
    的另一个更严重的问题是它遗漏了指定的选项。您可以解决它(请参阅rcollyer的答案),但这是使用OptionValue的另一个很好的理由。

    您的代码本身有一个微妙但可修复的缺陷。模式
    opts\uuuuu规则
    将与表单
    a:>b
    的选项不匹配,因此如果您需要使用它,您必须更新代码。立即解决的方法是将
    opts\uu规则
    替换为
    opts:(uuuuu Rule | uuuuuuruledelayed)
    OptionsPattern[]
    需要更多的输入。但是,对于我们这些懒惰的人来说,
    OptionValue[…]
    ReplaceAll
    的缩写形式需要更多的输入。不过,我认为它有助于更清晰地阅读代码


    我发现
    选项pattern[]
    OptionValue
    更容易阅读,也更容易理解正在做的事情。较旧的
    形式选择了uuuuuuuuuuuu…
    ReplaceAll
    在第一次通读时就更难理解。除此之外,我会继续更新你的代码。

    虽然有几个答案强调了dif在使用选项的新旧方法的不同方面,我想做一些额外的观察。较新的构造
    OptionValue
    -
    OptionsPattern
    OptionQ
    提供更多的安全性,因为
    OptionValue
    检查全局选项列表,以确保函数知道传递的选项但是,较旧的
    选项q
    似乎更容易理解,因为它仅基于标准模式匹配,与任何全局属性都没有直接关系。您是否希望这些构造提供这种额外的安全性取决于您,但我猜大多数人会发现它很有用,尤其是对于更大的pr项目

    这些类型检查非常有用的一个原因是,函数通常会以链式方式将选项作为参数传递、过滤等,因此如果没有这些检查,一些模式匹配错误将很难捕获,因为它们将在远离原点的地方造成危害

    <> P>在核心语言方面,<代码> opthValue<代码> OptionsPattern > <代码>构造是模式匹配器的一个附加部分,可能是其所有特征中最“神奇”的一个。它不需要语义上的,只要一个人愿意考虑选项作为规格。
    f[a_, b_, opts___?OptionQ] := Print[someOption/.Flatten[{opts}]/.Options[f]]
    
    f[a_, b_, opts:OptionsPattern[]] := Print[OptionValue[someOption]]
    
    ClearAll[f, ff, fff, a, b, c, d];
    Options[f] = Options[ff] = {a -> 0, c -> 0};
    SetAttributes[{f, ff}, HoldAll];
    f[x_, y_, opts___?OptionQ] :=
       {{"Parameters:", {HoldForm[x], HoldForm[y]}}, {" options: ", {opts}}};
    ff[x_, y_, opts : OptionsPattern[]] :=
       {{"Parameters:", {HoldForm[x], HoldForm[y]}}, {" options: ", {opts}}};
    
    In[199]:= f[Print["*"],Print["**"],a->b,c->d]
    Out[199]= {{Parameters:,{Print[*],Print[**]}},{ options: ,{a->b,c->d}}}
    
    In[200]:= f[Print["*"],Print["**"],Print["***"],a->b,c->d]
    During evaluation of In[200]:= ***
    Out[200]= f[Print[*],Print[**],Print[***],a->b,c->d]
    
    In[201]:= ff[Print["*"],Print["**"],a->b,c->d]
    Out[201]= {{Parameters:,{Print[*],Print[**]}},{ options: ,{a->b,c->d}}}
    
    In[202]:= ff[Print["*"],Print["**"],Print["***"],a->b,c->d]
    Out[202]= ff[Print[*],Print[**],Print[***],a->b,c->d]