2009-04-28 9 views
3

は基本的に私は私がPREINITIALIZEしたくないいくつかの変数があります場合は変数をNone/Undefinedに初期化し、Pythonの他の変数と比較するには?

originalTime = None 
recentTime = None 
postTime = None 

def DoSomething () : 
    if originalTime == None or (postTime - recentTime).seconds > 5 : 
     ... 

を、私は上のエラーをコンパイル取得する:あなたが見ることができるように

UnboundLocalError: local variable 'originalTime' referenced before assignment 

、すべての変数は、別の関係を持っています(時間、時間+ 5など)またはNoneを設定する必要がありますが、Noneと宣言するだけで、あらかじめ計算された値に設定するのは簡単ではありません。

アイデア?

+2

コードを投稿する必要があります。このスニペットは問題ありません。問題を再現したり理解したりするのに十分な情報がありません。 –

+0

-1;編集後もこの質問は理解できません。 'DoSomething'関数は、(UnboundLocalErrorがなくても)どの変数にも代入を表示せず、実際の質問が不明です。 –

答えて

12

私はジャレットハーディを修正する必要がある、と私は十分に持っていないので、コメントする担当者。

グローバルスコープは問題ではありません。 Pythonは自動的に囲みスコープ内の変数名を検索します。唯一の問題は、値を変更する場合です。単に変数を再定義すると、グローバルキーワードを使用しない限り、Pythonは新しいローカル変数を作成します。だから、

originalTime = None 

def doSomething(): 
    if originalTime: 
    print "originalTime is not None and does not evaluate to False" 
    else: 
    print "originalTime is None or evaluates to False" 

def doSomethingElse(): 
    originalTime = True 

def doSomethingCompletelyDifferent() 
    global originalTime 
    originalTime = True 

doSomething() 
doSomethingElse() 
doSomething() 
doSomethingCompletelyDifferent() 
doSomething() 

べき出力:

originalTime is None or evaluates to False 
originalTime is None or evaluates to False 
originalTime is not None and does not evaluate to False 

これは悪いデザインであることを私は2番目の彼の警告。

+2

私は、グローバルな関数の内部での使用が悪い設計であることを議論が指摘していることが分かります。しかし、適切なデザインにいくつかのサンプルコードを表示することはできますか?物事を行う正しい方法だと思うものを私たちに教えてください。私はPythonの純粋主義者ではないと公言しています。私が何か良いことを見つけるまでは。 – Antony

-2

シェルでコードを試したところ、エラーは発生しませんでした。それは動作するはずです。たぶん、コード全体を投稿しますか? try/catchも使用できます。

または、おそらくlocals()。has_key( 'originalTime')?

6

あなたのコードは機能しているはずですが、私はそれが関数内にあると思いますが、originalTimeはどこかで定義されています。 また、originalTime is Noneと言ってほしいのですが、それが本当にほしいと思うのであれば、さらに良いと言えば、not originalTimeです。

+0

チップあり/ありませんありがとうございます。 –

+2

Scottが提供するapposite adviceにNoneを追加するだけで、originalTimeが0または ""またはFalseの場合は "not originalTime"が一致し、originalTimeがNoneの場合はoriginalTimeが実際に "None"の場合にのみ一致します。多くの開発者は、この相違点を使用して、実行コンテキストに値を持たない変数から指定されていない変数を定義します。 (例:def myfunc(somevar = None):somevarがNoneの場合:somevar = 5#そうでなければsomevar = 0が意図的であると仮定します) –

0

ifステートメントが関数内にありますが、= None宣言がモジュールレベルにある場合、変数は関数内のスコープ外です。

def doSomething(): 
    global originalTime 
    if originalTime: 
     print "originalTime exists and does not evaluate to False" 

多くの人々はところで、このように貧しいPythonのデザインを考える:最も簡単な修正は、明示的に変数識別子はグローバルスコープで見られることを示すためです。あなたがその評価に同意し、あなたのアーキテクチャが許せば、関数の引数として外部の依存関係を受け取るように関数をリファクタリングしたいかもしれません。

+0

ありがとうございます。それが純粋なPythonの場合、私はこれをしませんでしたが、私は非常にひどくバグがある3DパーティーアプリケーションのPython統合を使用していますが、それは私が使用しなければならないものです。 –

+0

-1;これは間違っているか、少なくとも誤解を招くほどのものです。関数本体内の任意の場所から割り当てようとしない限り、関数内の外部スコープの変数を使用することは完全に可能です。 –

-2

これは本当に「きれいな」方法ではありません。ちょうどあなたが与えてくれた変数名に基づいて、私の最初の本能は、オブジェクトを作成することです:

class SomeTimeClass(object): 
    def __init__(self, recentTime=None, originalTime=None, postTime=None): 
     self.recentTime = recentTime 
     self.originalTime = originalTime 
     self.postTime = postTime 

time = SomeTimeClass() 
if not time.recentTime:: 
    ... 

変数が相関しているように聞こえるので、これはうまくいくかもしれません。その他のオプションのカップル:

ラップ機能の手順:

def SomeFunc(recentTime=None, originalTime=None, postTime=None): 
    if not recentTime: 
     ... 

は、辞書を使用します。

some_dict = {} 

if not some_dict.get('originalTime', None): #return None if key doesn't exist 
    ... 
+0

ちょうど好奇心から、これはなぜ投票されたのですか?何か間違ったことがありましたか? –

0

==>初期値がNoneの場合

変数はただ存在しない場合には
>>>toto = None 

>>>toto = toto if toto is not None else "default Value" 

>>>toto 

'default value' 

==>

>>>del toto 

>>>toto = toto if locals().get('toto') else "default Value" 

>>> toto 

'default value' 

==>の値が設定されている場合には、同じコマンド

>>>toto = 1 

>>>toto 

1 

>>>toto = toto if locals().get('toto') else "default Value" 

1 
関連する問題