我正在尝试将一些代码从Matlab翻译成Python。我的函数(在 Matlab 中)的开头是这样的:
function [varargout]=hysime(varargin);
error(nargchk(3, 4, nargin))
if nargout > 2, error('too many output parameters'); end
verbose = 1; % default value
y = varargin{1}; % 1st parameter is the data set
在程序的后面有这样的内容:
n = varargin{2}; % the 2nd parameter is the noise
Rn = varargin{3}; % the 3rd parameter is the noise correlation matrix
if nargin == 4, verbose = ~strcmp(lower(varargin{4}),'off');end
最后是这个:
varargout(1) = {kf};
if nargout == 2, varargout(2) = {Ek};end
return
我对这段代码的含义感到非常困惑。一方面,我知道输入的参数都需要返回。但是,在程序结束时,似乎只会返回 2 个变量(而我们输入 3?如何翻译此代码以返回必要的参数?我想我在这里最大的问题是 matlab 代码让代理输入参数,但它们似乎并不都是必需的?而且似乎不能有两个以上的输出?我只是无法破译这里的每一行代码的含义。有人可以解释一下 matlab 代码发生了什么以及我可以做些什么来在 python 中制作相同的功能吗?
谢谢!
简短版本
MATLAB 代码应该是这样写的:
function [kf, Ek]=hysime(y, n, Rn, verbose);
error(nargchk(3, 4, nargin))
if nargin < 4
verbose = true;
else
verbose = ~strcmpi(verbose ,'off');
end
如果你知道 MATLAB,这应该更清楚。 (大部分)相应的 Python 代码可以这样编写:
def hysime(y, n, Rn, verbose=True):
# rest of the function here
return kf, Ek
长版本
此函数需要 3 或 4 个输入参数,如果未提供第四个参数,则设置默认值。 但是,它的完成方式比需要的要复杂得多(尽管我经常看到这种模式)。 理想情况下,在 MATLAB 中,您可以像这样指定相同的内容:
function [varargout]=hysime(y, n, Rn, verbose)
error(nargchk(3, 4, nargin))
if nargin < 4
verbose = true;
else
verbose = ~strcmpi(verbose ,'off');
end
所以它所做的是将第一个参数放在变量y
中,第二个参数放在变量n
中,第三个参数放在Rn
中,如果指定了第四个参数,则将其放在verbose
中(基于它与字符串'off'
的比较),否则verbose
设置为true
。
在python中,可选参数的处理是内置的。 您可以通过设置name=value
直接在函数定义中指定参数的默认值,其中name
是参数名称,value
是默认值。 此外,由于历史原因,MATLAB 经常使用'on'
和'off'
而不是true
和false
。 这在 Python 中几乎从未完成过,人们只是使用True
和False
. 所以你可以在Python中指定同样的东西,如下所示:
def hysime(y, n, Rn, verbose=True):
这使得y
、n
和Rn
参数成为必需的参数,但verbose
是可选的。
这不会处理将verbose
设置为字符串'off'
的情况。 正如我所说,由于历史原因,这在 MATLAB 中很常见,但是当你可以避免它时,你真的不应该再在 MATLAB 中这样做了,你绝对不应该在 Python 中这样做。 但是,如果您真的需要处理这种情况,您可以执行以下操作:
def hysime(y, n, Rn, verbose=True):
if isinstance(verbose, str):
verbose = verbose.lower() != 'off'
对于输出,MATLAB 代码所做的是让函数返回一个值或两个值。 所以有人可以这样做:
kf = hysime(y, n, Rn);
或
[kf, Ek] = hysime(y, n, Rn);
但是,这也以比必要更复杂的方式完成。 如果只返回两个值,并且只使用一个返回值,则 MATLAB 将丢弃其余值。 因此,与其弄乱varargout
,该函数可以只返回[kf, Ek]
,MATLAB 将做同样的事情。 如果有人尝试调用具有 2 个以上输出的函数,则会自动发生错误,因此这也是不必要的。
仅当您希望程序根据输出数量更改其行为时,才需要以这种方式处理varargout
。 在这种结构中,这样做的主要原因是如果eK
计算成本很高,在这种情况下,您将执行以下操作:
varargout(1) = {kf};
if nargout == 2
# calculate eK here
varargout(2) = {Ek};
end
至于return
,只有在 MATLAB 中,如果你想让函数在正常到达终点之前提前停止,才需要。 一旦正常到达终点,它将自动return
。 因此,如果您指定的最后一个代码块是函数的结尾,则该return
是多余的。
因此,您在 MATLAB 中显示的所有代码都可以简化为:
function [kf, Ek]=hysime(y, n, Rn, verbose);
error(nargchk(3, 4, nargin))
if nargin < 4
verbose = true;
else
verbose = ~strcmpi(verbose ,'off');
end
至于 Python,正如我在另一个回答中提到的,Python 需要处理所有返回的值。 它永远不会丢弃返回的值,除非你明确告诉它这样做。 在您的情况下,最简单的解决方案就是在函数末尾使用return kf, Ek
。 如果有人想要kf
和Ek
,他们可以做:
kf, Ek = hysime(y, n, Rn)
如果他们只想要kf
,他们可以做(其中_
是你不关心的变量的python约定):
kf, _ = hysime(y, n, Rn)
或:
kf = hysime(y, n, Rn)[0]
所以python代码将是:
def hysime(y, n, Rn, verbose=True):
# rest of the function here
return kf, Ek
如果确实希望能够有一个或两个返回值,则需要另一个参数来更改行为。 如:
def hysime(y, n, Rn, verbose=True, ret_eK=False):
# rest of the function here
return (kf, Ek) if ret_eK else kf
因此,在这种情况下,如果指定了ret_eK
参数并将其设置为True
,则返回kf, Ek
,否则仅返回kf
。 但是在Python中,你真的不想这样做,除非计算Ek
有一些重大的额外成本,在这种情况下似乎不是。