2017-05-12 15 views
0

私は価格オプションにお互いを呼び出す一連の関数を作成しました。関数の1つは、(Nelder Meadを使用して)いくつかのパラメータを最適化するためにかなり長い間実行されます。この関数内では、他の関数で使用したい値が計算されていますが、return文で渡す必要はありません。私はグローバル変数を使用すると完璧だと思った。returnを使用せずに関数から値を渡す方法は?

今、奇妙な部分:私がimport *でパッケージとして書いた関数を読み込むと、関数が作成するグローバル変数にアクセスできません。関数定義でスクリプトを実行し、Pythonコンソールで関数を定義するためにそれを実行し、関数を呼び出すと、グローバル変数varはうまく動作します。問題とは何か、また、関数をパッケージとしてロードするか「手動で」ロードするかという違いがあるのはなぜですか?

パッケージとしてロードするときのエラー:NameError: name 'h_out' is not defined

global h_out 
h_out=None 
import hngoption 

prices = timeseries[data.Date[i]:].head(30) 
output = hngoption.params(prices) 

params() calls function LogLike() as part of its computations which contains: 

def LogLike(B, r): 
     # (...) 
     for i in range(N - 3, -1, -1): 
      h[i] = B[0] + B[2] * h[i + 1] + B[1] * pow(Z[i + 1] - B[3] * sqrt(h[i + 1]), 2) 
      Z[i] = (ret[i] - r - B[4] * h[i])/(h[i] ** 0.5) 
      L[i] = -log(h[i]+ 0.000000000000001) - (ret[i] ** 2)/h[i] 

     LogL = VecSum(L) 

     global h_out  #IMPORTANT PART 
     h_out = h[0] 

     if ((B[0] < 0) | (B[1] < 0) | (B[2] < 0) | (B[3] < 0) | (B[4] < 0)): # (B[2]+B[1]*pow(B[3],2)>=1)) 

      return 1e50 
     else: 
      return -LogL # Minimize -Log-Like(Beta) 

全LogLike機能:

def LogLike(B, r): 

    N = len(timeseries) #timeseries is a global var 
    # Calculate S&P500 returns 
    ret = [0.0] * (N - 1) 
    for i in range(0, N - 1): 
     ret[i] = (log(timeseries.ix[i]/timeseries.ix[i + 1])) 

    Variance = VecVar(ret) 
    h = [0 * i for i in range(N - 1)] 
    Z = [0 * i for i in range(N - 1)] 
    L = [0 * i for i in range(N - 1)] 

    # Construct GARCH(1,1) process by working back in time 
    h[N - 2] = Variance 
    Z[N - 2] = (ret[N - 2] - r - B[4] * h[N - 2])/h[N - 2] ** 0.5 
    L[N - 2] = -log(h[N - 2]) - (ret[N - 2] ** 2)/h[N - 2] 

    for i in range(N - 3, -1, -1): 
     h[i] = B[0] + B[2] * h[i + 1] + B[1] * pow(Z[i + 1] - B[3] * sqrt(h[i + 1]), 2) 
     Z[i] = (ret[i] - r - B[4] * h[i])/(h[i] ** 0.5) 
     L[i] = -log(h[i]+ 0.000000000000001) - (ret[i] ** 2)/h[i] 

    LogL = VecSum(L) 

    global h_out  #IMPORTANT PART 
    h_out = h[0] 


    if ((B[0] < 0) | (B[1] < 0) | (B[2] < 0) | (B[3] < 0) | (B[4] < 0)): # (B[2]+B[1]*pow(B[3],2)>=1)) 

     return 1e50 
    else: 
     return -LogL # Minimize -Log-Like(Beta) 
+6

スクリーンショット内のコードを与えないでください。代わりに、質問自体にコードを投稿してください。コードは[mcve]を構成するのが好ましいです。 –

+4

また、関数からデータを返す明白な方法であるため、なぜreturnを使用したくないのか説明する必要があります。 –

+0

主にNelderMeadがこの関数を呼び出し、戻り値から別の引数を渡すと、互いに呼び出す関数のチェーンが非常に複雑になるからです。 – SW7

答えて

0

あなたは結果を運ぶの引数の次のタイプを使用することができます。

def test(a): 
    a[0]=a[0]+2 

>>> a = [2] 
>>> test(a) 
>>> a 
[4] 
0

from somemodule import *現在のモジュール内の変数-という名前を好きにその時点で存在してsomemoduleでグローバル変数をバインドします。まだ作成されていない変数はインポートされません。現在のモジュールは、他のモジュールの変数が再割り当てされても影響を受けないオブジェクトへの参照を持つようになりました。

問題を解決するには、グローバルスコープでいくつかのデフォルト値をh_outに割り当てて、関数が完了する前に他のモジュールが参照するとエラーにならないようにします。また、ワイルドカードのインポートを行う代わりに、モジュールを介して変数にアクセスして共有値を取得します。

somemodule.py

h_out = None 

def LogLikeDeep(B, r): 
    global h_out  #IMPORTANT PART 
    h_out = h[0] 

使い方

>>> import somemodule 
>>> somemodule.h_out 
>>> print(repr(somemodule.h_out)) 
None 
>>> somemodule.LogLikeDeep('foo', 'bar') 
>>> print(repr(somemodule.h_out)) 
'foo' 
+0

グローバルh_out h_outは= DEF LogLikeなし は(B、R): グローバルh_out h_outの= hの[0] (...) – SW7

+0

はありがとう、私はこれを実装していないが、私はhngoption.h_outを呼び出すときには、むしろ空を返します値よりも。コード: グローバルh_out h_out =なし DEF LogLike(B、R): グローバルh_out h_outの=さh [0] (...) – SW7

+0

...および関数がすでに呼び出されていますか?あなたの質問を実際の例で更新すると、何が起こっているのかが分かります。 – tdelaney

関連する問題