我正在尝试将一些代码从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中实现相同功能的解释吗?
谢谢!
答案 0 :(得分:2)
简短版本
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
。
在python中,内置了对可选参数的处理。您可以通过设置true
在函数定义中为参数指定默认值,其中name=value
是参数名,name
是默认值。同样,由于历史原因,MATLAB通常使用value
和'on'
而不是'off'
和true
。这在Python中几乎从未实现过,人们只使用false
和True
。因此,您可以像这样在Python中指定相同的内容:
False
这使def hysime(y, n, Rn, verbose=True):
,y
和n
成为必需参数,但使Rn
是可选的。
这不能处理将verbose
设置为字符串verbose
的情况。就像我说的那样,由于历史原因,这在MATLAB中很常见,但是在可以避免的情况下,您真的不应该再在MATLAB中进行此操作,并且绝对不应该在Python中进行。但是,如果您确实需要处理这种情况,则可以执行以下操作:
'off'
对于输出,MATLAB代码的作用是让函数返回一个值或两个值。所以有人可以这样做:
def hysime(y, n, Rn, verbose=True):
if isinstance(verbose, str):
verbose = verbose.lower() != 'off'
或
kf = hysime(y, n, Rn);
但是,这样做的方式也比必要的复杂。如果仅返回两个值,并且仅使用一个返回值,MATLAB将丢弃其余的值。因此,该函数可以只返回[kf, Ek] = hysime(y, n, Rn);
而不是弄乱varargout
,而MATLAB将执行相同的操作。如果有人尝试使用两个以上的输出来调用该函数,则会自动发生错误,因此这也是不必要的。
仅当您希望程序根据输出数量更改其行为时,才需要用[kf, Ek]
处理。在这种结构中,您这样做的主要原因是如果varargout
的计算成本很高,在这种情况下,您将执行以下操作:
eK
对于varargout(1) = {kf};
if nargout == 2
# calculate eK here
varargout(2) = {Ek};
end
,只有在MATLAB中,如果您想使函数在正常结束之前提前停止,才需要这样做。一旦正常到达末尾,它将自动return
。因此,如果您指定的最后一个代码块是函数的结尾,则return
是多余的。
因此,您在MATLAB中显示的所有代码都可以简化为:
return
对于Python,正如我在other answer to you中提到的那样,Python要求处理所有返回的值。除非您明确告知,否则它将永远不会丢弃返回的值。在您的情况下,最简单的解决方案是在函数末尾添加function [kf, Ek]=hysime(y, n, Rn, verbose);
error(nargchk(3, 4, nargin))
if nargin < 4
verbose = true;
else
verbose = ~strcmpi(verbose ,'off');
end
。如果有人同时需要return kf, Ek
和kf
,他们可以这样做:
Ek
如果他们只想要kf, Ek = hysime(y, n, Rn)
,他们就可以做到(其中kf
是您不关心的变量的python约定)
_
或者:
kf, _ = hysime(y, n, Rn)
因此python代码为:
kf = hysime(y, n, Rn)[0]
如果您确实希望能够有一个或两个返回值,则需要有另一个参数来更改行为。如:
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
。但是,在Python中,您真的不希望这样做,除非计算kf
会花费一些主要的额外费用,在这种情况下似乎没有。