What's the best/canonical way to define a function with optional named arguments?  To make it concrete, let's create a function foo wi开发者_Go百科th named arguments a, b, and c, which default to 1, 2, and 3, respectively.  For comparison, here's a version of foo with positional arguments:
foo[a_:1, b_:2, c_:3] := bar[a,b,c]
Here is sample input and output for the named-arguments version of foo:
foo[]                  --> bar[1,2,3]
foo[b->7]              --> bar[1,7,3]
foo[a->6, b->7, c->8]  --> bar[6,7,8]
It should of course also be easy to have positional arguments before the named arguments.
I found the standard way to do it in the Mathematica documentation: http://reference.wolfram.com/mathematica/tutorial/SettingUpFunctionsWithOptionalArguments.html
Options[foo] = {a->1, b->2, c->3};  (* defaults *)
foo[OptionsPattern[]] := bar[OptionValue@a, OptionValue@b, OptionValue@c]
Typing "OptionValue" every time is a little cumbersome. For some reason you can't just make a global abbreviation like ov = OptionValue but you can do this:
foo[OptionsPattern[]] := Module[{ov},
  ov[x___] := OptionValue[x];
  bar[ov@a, ov@b, ov@c]]
Or this:
With[{ov = OptionValue},
  foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
]
Or this:
$PreRead = ReplaceAll[#, "ov" -> "OptionValue"] &;
foo[OptionsPattern[]] := bar[ov@a, ov@b, ov@c]
Yes, OptionValue can be a bit tricky because is relies on a piece of magic so that 
OptionValue[name]is equivalent toOptionValue[f,name], wherefis the head of the left-hand side of the transformation rule in whichOptionValue[name]appears.
Throwing in an explicit Automatic usually does the trick, so in your case I would say that the solution is:
Options[foo] = {a -> 1, b -> 2, c -> 3};
foo[OptionsPattern[]] := 
  bar @@ (OptionValue[Automatic, #] &) /@ First /@ Options[foo] 
By the way, options used to be done by matching to opts:___?OptionQ, and then finding option values manually as {a,b,c}/.Flatten[{opts}]. The pattern check OptionQ is still around (although not documented), but the OptionValue approach has the advantage that you get warnings for non-existing options (e.g. foo[d->3]). This would also be the case for your second response, but not for the one you have accepted. 
I'll throw this possible solution into the mix:
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]]
]
I like it for its terseness but I don't think it's the standard way. Any gotchas with doing it that way?
PS, it uses the following handy utility function:
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.       *)
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论