Python MATLABでnargoutに相当するものはありますか?戻りパラメーターの数を柔軟に保ちたい場合、nargoutは非常に優れたアプローチだと思います。出力パラメーターの数を調べる方法はありますか?次の疑似Pythonコードのようなもの:
_def var_returns_func(a):
"""
a is a 1D numpy array
"""
if nargout==1: return a.sum()
Elif nargout==2: return a.sum(),a.std()
_
したがって、この関数をmean = var_returns_func(someNumPyarray)
として呼び出すと、単一の値が返されるはずです。しかし、それをmean,std = var_returns_func(someNumPyarray)
と呼ぶと、2つの値を返すはずです。
これを行うPythonの方法はありますか?それともハッキーな方法ですか?
関数は戻り値で何が行われるのかわからないため、必要な数を知ることができません。できることは、関数の引数としてnargout
を渡し、それを使用して何を返すかを決定することです。
_def f(a, nargout=1):
if nargout == 1:
return "one value"
Elif nargout == 2:
return "two", "values"
else:
raise ValueError, "Invalid nargout!"
_
これは、Python哲学としての「明示的は暗黙的よりも優れている」の例です。2つの引数を出したい場合は、2つの引数を出したいことを明示的に言う必要があります。見た目に基づいて暗黙的に決定する将来的には、結果で何が行われるかを確認することはPythonでは推奨されていません。a = f(x)
およびwantを実行して、で2要素のタプルを取得することは完全に可能です。
あなたのような例では、もっと良い方法がたくさんあります。 1つは、mean, std = a.mean(), a.std()
、より一般的にはx, y = someFunc(a), otherFunc(a)
を実行することです。この特定の値の組み合わせが一般的に必要であり、重複させたくない両方の操作で共有される高価な計算がある場合は、両方を明確に返す3番目の関数を作成し、x, y = funcThatReturnsTwoThings(a)
を実行します。これらはすべて、異なることを行う場合に関数を分離しておく明示的な方法です。
MATLABでnargout
について話すことができません。それがわからないため、正しく使用する方法が想像できません。ただし、ビューをPython関数(またはメソッド)が実際に行うこと)に変更することもできます。
実際には、Pythonは常に正確に1つの値を返します。または、Noneであるか、特定の型の単一の値であるか、Tuple
型の単一のオブジェクトです。
return
コマンドがない場合、関数本体が終了すると、関数はNone
を返します。これは、本文の最後に引数なしでreturn
を明示的に記述した場合、または本文の最後に_return None
_を記述した場合と同じです。
引数なしで_return None
_(None
は変数に格納できます)またはreturn
を使用する場合、None
は呼び出し元に返されます。
_return single
_の場合、single
オブジェクトが呼び出し元に返されます。
_return v1, v2, v3
_の場合、実際にはタプル_(v1, v2, v3)
_を返します。括弧を書く必要がないのは単なる構文糖衣です。
この場合のresult1, result2, result3 = f()
は、単なる別の構文糖衣です。 f()
はタプルを返し、その要素は指定された変数に自動的に抽出されます。あなたは実際に:
_result1, result2, result3 = (v1, v2, v3)
_
または
_t = f() # where t is the (v1, v2, v3)
result1, result2, result3 = t
_
実際、Pythonでは、他の言語では通常のように出力引数を定義できません。引数オブジェクトのアドレスを渡しており、渡されたオブジェクトを変更できるかどうかを考えると、変更することはできますが、たとえば、最初にNone
値を持っていた渡された引数に新しい結果を取得することはできません。の出力引数を介してPython変数を割り当てることはできません。関数-Pythonにはそのようなメカニズムはありません。
関数内から新しく作成された値(オブジェクト)を返す唯一の自然で直接的な方法は、return
コマンドを使用することです。ただし、Python関数は、返される引数の数を制限しません(まあ、タプルの場合は後で要素に分割できる単一の引数です)。
実際に返されたものを呼び出し元のコードでテストする場合は、次の値が返された場合に特別なことを行う独自の関数を作成できます:None
、single
、のタプルある程度の長さ(len(t)
を使用して、返されたタプルt
の要素数を取得できます)。関数は、single
のタイプまたは各タプル要素のタイプをテストし、それに応じて機能することもできます。
Matlabでは、出力引数の数は実際には関数への入力の1つです。これはPythonの場合には当てはまらないため、これを異なる方法で反映するように関数のインターフェースを設定しました。
たとえば、upper()を文字列のグループに適用する関数を次に示します。ユーザーは、入力の数が出力の数と等しいことを期待できます。構文もMatlabのものと非常に似ています。
>>> def var_returns_f(*args):
... return [str.upper() for str in args]
...
>>>
>>> a, b = var_returns_f('one', 'two')
>>>
>>> a
'ONE'
>>> b
'TWO'
私がしがちなのは、関数がすべてを(タプルの要素として)返すようにしてから、必要なものだけを解凍することです。
def my_func():
# do stuff...
return mean, stddev, otherstat, a, b
mu, sig, _, a, _ = myfunc()
ここではすべてを返しますが、呼び出しスコープで使用する変数に1番目の2番目と4番目の変数のみを割り当てます。 _
変数は、私が望まない/必要としない変数のプレースホルダーとして機能する使い捨てです。
私は奇妙な考えを持っています...
def nargout():
import traceback
callInfo = traceback.extract_stack()
callLine = str(callInfo[-3].line)
split_equal = callLine.split('=')
split_comma = split_equal[0].split(',')
return len(split_comma)
def fun():
this = nargout()
if this == 1:
return 3
else:
return 3, 4
a = fun()
a, b = fun()
私は今Matlabが本当に恋しいです:D
改善点:
def nargout(*args):
import traceback
callInfo = traceback.extract_stack()
callLine = str(callInfo[-3].line)
split_equal = callLine.split('=')
split_comma = split_equal[0].split(',')
num = len(split_comma)
return args[0:num] if num > 1 else args[0]
def fun(nparray):
return nargout(np.mean(nparray), np.std(nparray))
arr = np.array([3, 4, 5])
mean = fun(arr)
mean, std = fun(arr)