我们可以一起使用addOptional和addParameter吗? [英] Can we use addOptional and addParameter together?

查看:77
本文介绍了我们可以一起使用addOptional和addParameter吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

inputParser提供了addOptional和addParameter.该文档( https://www.mathworks.com/help/matlab/ref/inputparser-class.html )说

您可以通过以任意顺序调用addRequiredaddOptionaladdParameter来定义方案,但是当您调用使用输入解析器的函数时,应首先传递必需的输入,然后再传递任何可选的位置输入,最后还有任何名称/值对.

但是我无法完成这项工作,并出现以下错误.

K>> a = inputParser;
K>> addOptional(a, 'o', 'x');
K>> addParameter(a, 'p', 1);
K>> parse(a, 'w', 'p', 2)

参数'w'是一个字符串,与任何参数名称都不匹配.对参数'o'的验证失败.

如果我们将默认值定义为数字.

a = inputParser; 
addOptional(a, 'o', 42);
addParameter(a, 'p', 1);
parse(a, 'p', 2);
parse(a, 3, 'p', 2);
parse(a, 3);

有效.

我有什么想念吗?

解决方案

我不建议将inputParser与允许用作字符数组的可选参数一起使用,因为parse()无法区分用户是否传递了参数名称(始终为char类型)或可选的输入参数.因此,为什么不能将char作为可选输入参数传递,是这种行为的逻辑结果.

但是,如果为可选输入参数(可能为char)指定验证功能,则可以使其生效.来自 addOptional 文档的提示"部分下:

对于可选的字符串输入,请指定验证功能.如果没有验证功能,输入解析器会将有效的字符串输入解释为无效的参数名称,并引发错误.

这是您的示例所产生的错误.

修正示例

'o'是可选的输入参数.如果您知道如何验证'o'需要接受的值,请提供一个验证函数,该函数为那些有效输入返回true.例如,如果您知道'o'始终是char数组,请尝试以下操作(逐行).

a = inputParser; 
addOptional(a, 'o', 'default', @ischar);
addParameter(a, 'p', 1);

parse(a, 'x');  % OK

parse(a, 'Hello, World!', 'p', 2);  % OK

parse(a, 'p', 'p', 'p')  % OK, although quite cryptic

parse(a, 3);  % Throws an error, as expected, because 3 is not a char

parse(a, 'p', 4)  % Throws a somewhat unexpected error, because we meant to set parameter 'p' to value 4

最后一行似乎违反直觉,但事实并非如此!我们希望解析器能够检测到参数'p',而不是隐式假定它是我们为可选参数'o'提供的字符,而我们希望忽略该字符.不过,正如我现在要解释的那样,这是预期的行为.

为什么char可选选项给inputParser带来了麻烦

由于不需要可选参数和参数实参,即可选参数,因此可以预期演示的行为.如果您有两个可选的输入参数'o1''o2',则它们的顺序对输入解析器很重要(这就是MATLAB文档将它们称为可选的 positional 参数"的原因).您永远不能在'o1'的值之前传递'o2'的值.这意味着'o2'仅可在还指定了'o1'的情况下使用.换句话说,'o1'禁止使用任何其他可选参数.

对于参数也是如此,它应该始终位于其他可选输入参数之后(如您已经引用的).这样,如果允许任何可选输入参数为char,则它们的行为类似于可选项.结果是MATLAB的inputParser不知道char输入是可选输入参数还是参数. MATLAB的开发人员已决定要求对可选输入进行显式排序,因此MATLAB可以确保将哪些可选参数传递给parse().

如果可选输入可能是char

,则建议采取的措施

因为使用可选输入参数要求MATLAB假设某些输入参数引用了可选输入参数,而另一些参数则引用了参数,因此,如果未指定所有可选参数,这可能会导致错误,行为或最终用户无法预料的结果.

如果明确编写输入自变量方案以防止这种意外的隐式行为,则更好.我建议如果需要接受char输入的可选输入参数,则应始终将其设为参数,即使用addParameter的名称-值对参数.仅当不使用任何参数时,才使用接受char输入的可选输入参数,或者通过显式声明(例如,在帮助中)仅当也提供了所有可选输入参数的情况下,才可以使用参数输入参数.

inputParser provides addOptional and addParameter. The doc (https://www.mathworks.com/help/matlab/ref/inputparser-class.html) says

You can define your scheme by calling addRequired, addOptional, and addParameter in any order, but when you call your function that uses the input parser, you should pass in required inputs first, followed by any optional positional inputs, and, finally, any name-value pairs.

But I cannot make this work, and got the following error.

K>> a = inputParser;
K>> addOptional(a, 'o', 'x');
K>> addParameter(a, 'p', 1);
K>> parse(a, 'w', 'p', 2)

The argument 'w' is a string and does not match any parameter names. It failed validation for the argument 'o'.

If we define the default value as number.

a = inputParser; 
addOptional(a, 'o', 42);
addParameter(a, 'p', 1);
parse(a, 'p', 2);
parse(a, 3, 'p', 2);
parse(a, 3);

it works.

Did I miss anything?

解决方案

I do not recommended the use of inputParser with optional arguments that are allowed to be character arrays, because parse() cannot distinguish if the user passes a parameter name (which is always of type char) or the optional input argument. Thus, it is a logical consequence of this behaviour why you cannot pass a char as an optional input argument.

However, if you specify a validation function for the optional input arguments that may be char, you can make it work. From the addOptional documentation under section ‘Tips’:

For optional string inputs, specify a validation function. Without a validation function, the input parser interprets valid string inputs as invalid parameter names and throws an error.

This is the error your example generated.

Fixing your example

'o' is the optional input argument. If you know how to validate the values 'o' needs to accept, provide a validation function that returns true for those valid inputs. For example, if you know 'o' will always be a char array, try the following (line by line).

a = inputParser; 
addOptional(a, 'o', 'default', @ischar);
addParameter(a, 'p', 1);

parse(a, 'x');  % OK

parse(a, 'Hello, World!', 'p', 2);  % OK

parse(a, 'p', 'p', 'p')  % OK, although quite cryptic

parse(a, 3);  % Throws an error, as expected, because 3 is not a char

parse(a, 'p', 4)  % Throws a somewhat unexpected error, because we meant to set parameter 'p' to value 4

The last line seems counter-intuitive, but it's not! We'd expect the parser to detect the parameter 'p' instead of implicitly assuming it is the character we provide for optional argument 'o', which we wanted to omit. It is the expected behaviour, though, as I will explain now.

Why char optionals give inputParser a hard time

The demonstrated bahviour is expected because both the optional and parameter arguments are not required, i.e., optional. If you'd have two optional input arguments, 'o1' and 'o2', their order matters to the input parser (which is why the MATLAB documentation calls them ‘optional positional arguments’). You could never pass a value for 'o2' before a value for 'o1'. This implies 'o2' can only be used if 'o1' is also specified. In other words, 'o1' impedes the use of any other optional arguments.

The same is true for parameters, which should always come after other optional input arguments (as you already quoted). As such, they behave like optionals if any optional input arguments are allowed to be char. The result is MATLAB's inputParser not knowing if a char input is an optional input argument or a parameter. MATLAB's developers have decided to require explicit ordering of optional inputs, so MATLAB can be sure what optional arguments are passed to parse().

Suggested action if optional inputs may be char

Because using optional input arguments requires MATLAB to assume some input arguments referring to an optional input argument, others referring to parameters, this may result in errors, behaviour or results unexpected by the end-user if not all optional arguments are specified.

Input argument schemes are better if written explicitly to prevent this unexpected implicit behaviour. I suggest that if optional input arguments are required that accept char input, you always make them parameters, i.e., name-value pair arguments using addParameter. Using optional input arguments that accept char input only works if not using any parameters, or by explicitly stating (e.g. in the help) that parameter input argument can be used if and only if all optional input arguments are given as well.

这篇关于我们可以一起使用addOptional和addParameter吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆