Я работаю над переводом кода из Matlab в Python. В настоящее время я работаю над этим:
switch SIGNATURES_TYPE
case 1
rand('seed',5);
load('USGS_1995_Library')
wavlen=datalib(:,1); % Wavelengths in microns
[L n_materiais]=size(datalib);
# select randomly
sel_mat = 4+randperm(n_materiais-4);
sel_mat = sel_mat(1:p);
M = datalib(:,sel_mat);
# print selected endmembers
clear datalib wavelen names aux st;
case 2
error('type not available')
case 3
M = rand(L,p);
case 4
M = randn(L,p);
case 5
L=p;
M = diag(linspace(1,(1/(COND_NUMBER)^(1/DECAY)),p).^DECAY);
case 6
L=p;
M = diag(linspace(1,(1/(COND_NUMBER)^(1/DECAY)),p).^DECAY);
A = randn(p);
[U,D,V] = svd(A);
M = U*M*V';
clear A U D V;
otherwise
error('wrong signatute type')
end
Раньше я работал над аналогичным кодом Switch/Case:
for i=1:2:(length(varargin)-1)
switch upper(varargin{i})
case 'MM_ITERS'
MMiters = varargin{i+1};
case 'SPHERIZE'
spherize = varargin{i+1};
Последнее я смог перевести на это:
for i in range(1, 2, length(*args)-1):
if (arg[i].upper() == "MM_ITERS"):
MMiters = arg(i+1)
elif (arg[i].upper() == "SPHERIZE"):
spherize = arg(i+1)
Однако для первого мне интересно, как я могу создавать похожие if-заявления. Например, для первого случая мой код может выглядеть примерно так:
if SIGNATURES_TYPE == 0:
** finish function
Я хотел бы знать, работает ли что-то подобное, или если было бы лучше разделить высказывания на отдельные функции, а затем называть их?
Спасибо за помощь и ввод!
Конструкция if
/else
будет работать. Другой способ сделать это - использовать dict
где ключи являются типами подписи, а значения - это функции, возвращающие M
Это имеет то преимущество, что вам ничего не нужно. Таким образом, это будет выглядеть примерно так:
def case1(p):
# calculate L and M
return L, M
def case6(p):
# calculate M
return p, M
try:
L, M = {1: case1(p),
3: (L, np.random.rand(L, p)),
4: (L, np.random.randn(L,p)),
5: (p, np.diag(np.linspace(1,(1/(COND_NUMBER)**(1/DECAY)),p)**DECAY),
6: case6(p)}[SIGNATURES_TYPE]
except KeyError:
raise ValueError('Wrong signatute type: {}'.format(SIGNATURES_TYPE))
Что касается вашего предыдущего примера, код MATLAB является обходным решением для отсутствия обработки аргументов по умолчанию. Python имеет обработку аргументов по умолчанию, поэтому вам вообще не нужен if
/else
или loop. Вы можете просто сделать что-то вроде:
def myfunc(arg1, arg2, arg3, MM_ITERS=MM_ITERS_default, SPHERIZE=SPHERIZE_default):
где arg1
, arg2
и arg3
- необходимые аргументы (число не имеет значения, может быть даже нулевой). MM_ITERS_default
и SPHERIZE_default
- это значения, которые вы хотите, чтобы соответствующие переменные SPHERIZE_default
, когда пользователь не определяет их. Вы можете даже собрать аргументы непосредственно в dict, используя:
def myfunc(arg1, arg2, arg3, **kwargs):
Затем вы можете получить доступ, скажем, MM_ITERS
, просто используя что-то вроде:
if MM_ITERS in kwargs:
MM_ITERS = kwargs[MM_ITERS]'
Или же
MM_ITERS = kwargs.get(MM_ITERS, MM_ITERS_default)
Но, как правило, проще просто использовать обработчик аргументов по умолчанию, который я показал ранее.
myfunc(val1, val2, val3)
, вы вызываете myfunc(val1, val2, val3)
, тогда переменная MM_ITERS
будет иметь MM_ITERS_default
а SPHERIZE
будет SPHERIZE_default
. С другой стороны, если вы вызвали myfunc(val1, val2, val3, val4)
, то у MM_ITERS
будет val4
а у SPHERIZE
будет SPHERIZE_default
. И myfunc(val1, val2, val3, val4, val5)
, имеет val4
для MM_ITERS
и val5
для SPHERIZE
. Вы также можете сделать, например, myfunc(val1, val2, val3, SPHERIZE=val5)
, в этом случае переменная MM_ITERS
будет иметь MM_ITERS_default
а SPHERIZE
будет иметь val5
.
if SIGNATURES_TYPE == 1:
elif SIGNATURES_TYPE == 2:
и т. Д. Есть ли причина, которая недостаточно хороша?