変数が存在するかどうかを確認するにはどうすればよいですか?


954

変数が存在するかどうかを確認したい。今私はこのようなことをしています:

try:
   myVar
except NameError:
   # Do something.

例外なく他の方法はありますか?


15
例外の何が問題になっていますか?
S.Lott、2009年

10
@ S.Lott:myVar本当に複雑なものである場合、生成/評価に長い時間がかかりますが、try遅くなることはありませんか?
dbliss 2015

3
@dbliss:変数です。execメタクラスでクレイジーなことをしているとしたら、本当に奇妙なケースは別として、それは高くつくことはありません。
user2357112はMonica

回答:


1628

ローカル変数の存在を確認するには:

if 'myVar' in locals():
  # myVar exists.

グローバル変数の存在を確認するには:

if 'myVar' in globals():
  # myVar exists.

オブジェクトに属性があるかどうかを確認するには:

if hasattr(obj, 'attr_name'):
  # obj.attr_name exists.

29
では、クラスに存在する属性を確認するにはどうすればよいですか?
Max Frai、2009年

7
そして、どうすれば存在しない可能性のある変数の名前を文字列に変換できますか?
SilentGhost 2009年

15
しかし、OPはコードを入力しているため、myVarの代わりに「myVar」と入力できます。コードの記述時に変数名がわからない場合は、実行時に文字列変数に格納され、投稿したチェックも機能します。
Ayman Hourieh、2009年

8
組み込み変数もあり、関数がネストされている場合は、外部スコープの変数もあります。それらのすべてをチェックしたい場合は、結局のところ、トリガーするのが最善でしょうNameError
Petr Viktorin 2014年

14
私もif hasattr(obj, 'attr_name'):クラスで機能するものが好きでした:ieif hasattr(self, 'attr_name'):
Ron Kalian

118

(暗黙的または明示的に)まだ定義または設定されていない変数の使用は、プログラムのロジックが適切に検討されていないことを示し、結果が生じる可能性が高いため、ほとんどの場合、どの言語で悪いことです予測不可能な動作で。

Pythonでそれを行う必要がある場合、次のトリックはあなたのものと同様であり、使用前に変数に何らかの値があることを確認します。

try:
    myVar
except NameError:
    myVar = None

# Now you're free to use myVar without Python complaining.

しかし、それが良い考えだとはまだ確信していません。私の意見では、この状況が発生しないようにコードをリファクタリングする必要があります。


8
多分それは依存関係の変数であり、バージョン/プラットフォームに応じて、存在する場合と存在しない場合があり、それがどのバージョンであるかを知る他の方法はありません。
WhyNotHugo

35
状態変数は、それらが割り当てられる前には存在しません。以前の位置から現在の位置まで線を引いて、previous = currentを設定しても、最初の呼び出しで「変数がわからない」という意味ではありません。また、drawルーチンの外部でprevious = nullを初期化するコード行を追加しても、「変数を知っている」という意味にはなりません。
Dave

4
私のポイントは、「if last:draw(last、current); last = current」というブロックは理解しやすく、プログラミングが貧弱ではないということです。テストする前に「最後」の存在を確認する「try / except」を追加すると、そのコードの可読性が損なわれます。
Dave

23
「定義されていない変数を使用することは、実際にはどの言語でも悪いことです。」一部の人は、SpyderなどのIDEを使用してMatlabのように機能する単純な数学または統計スクリプトにPythonを使用しています。これらの環境では、ユーザーがグローバルコンソールで変数を定義して、Matlabで数学を行うときのようにスクリプトで宣言されていないかどうかをチェックできるようにすることが理にかなっています。
Ricardo Cruz

15
むしろそれの謙遜を想定したよりもおそらく@Ricardo、、、あなたは、少なくともしたいことを検討し、それが誰かからちょうど良いアドバイスだという可能性より多くの知識が:-)または私は世界の制約のない使用に対して助言した場合、あなたはそれが平等にご愛顧検討すると変数、スパゲッティコード、godオブジェクト、テストされていないコードのリリース、またはCOBOLでのオペレーティングシステムの記述 私の答えは、なぜそれが悪い考えだと思ったのか(そしてOPがなぜそれが必要だと思ったのかを示す質問には何もなかったのです)を述べましたが、それでも彼らが本当にやりたかったオフチャンスの道を提供しました。
paxdiablo

52

簡単な方法は、最初にそれを初期化することです myVar = None

次に後で:

if myVar is not None:
    # Do something

2
この答えには改善すべきことがたくさんあります。むしろ-簡単な方法は、それを最初に宣言することです。 myVar = none # do stuff... if not myVar: # give myVar a value myVar = 'something'
Shawn Mehan、2015年

exceptステートメントでNoneに設定しているので、これがとても好きです
HashRocketSyntax

なぜ次のようなものではない:if myVar: # Do something これは二重否定を読む必要性を回避する
-jjisnow

@jjisnow myVar空のリスト、ゼロ、空の文字列などであっても、この条件を真にしたいので
Gabriel

7
@jjisnow if myVar: # Do somethingNameError、myVarが宣言されていない場合、python3でスローします
アジャイルBean

25

変数の存在をテストする最良の方法は、try / exceptを使用することです。しかし、ほぼ確実に、グローバル変数を設定/テストするよりも、あなたがしていることを何でも行うより良い方法があります。

たとえば、ある関数を初めて呼び出すときにモジュールレベルの変数を初期化する場合は、次のようなコードを使用することをお勧めします。

my_variable = None

def InitMyVariable():
  global my_variable
  if my_variable is None:
    my_variable = ...

2
これはグローバル名前空間を汚染するため、使用しないようにします。これを回避する1つの方法は、関数をクラス変数にし、my_variableをクラス変数として、callを既存の関数の本体として定義することですが、これはコーディングが面倒であり、他の多くの質問が開かれます。関数の属性を使用したいのですが、以下を参照してください。
samwyse 2014年

17

オブジェクト/モジュールの場合、次のこともできます

'var' in dir(obj)

例えば、

>>> class Something(object):
...     pass
...
>>> c = Something()
>>> c.a = 1
>>> 'a' in dir(c)
True
>>> 'b' in dir(c)
False

11

テストは、user97370の回答と同様に、関数で使用されることを想定しています。グローバルな名前空間を汚染するので、私はその答えは好きではありません。これを修正する1つの方法は、代わりにクラスを使用することです。

class InitMyVariable(object):
  my_variable = None

def __call__(self):
  if self.my_variable is None:
   self.my_variable = ...

これはコードが複雑になり、シングルトンプログラミングパターンで確認する必要があるかなどの質問が開かれるので、私はこれが好きではありません。幸いなことに、Pythonではしばらくの間、関数に属性を持たせることができました。これにより、次の簡単な解決策が得られます。

def InitMyVariable():
  if InitMyVariable.my_variable is None:
    InitMyVariable.my_variable = ...
InitMyVariable.my_variable = None

9

catchexceptPython で呼び出されます。それ以外は、そのような単純なケースでは問題ありません。ありますAttributeErrorオブジェクトが属性を持っているかどうかを確認するために使用することができます。


5

この種の状況を処理するためによく機能する方法は、変数が存在するかどうかを明示的にチェックせずに、存在しない可能性のある変数の最初の使用をtry / except NameErrorにラップすることです。

# Search for entry.
for x in y:
  if x == 3:
    found = x

# Work with found entry.
try:
  print('Found: {0}'.format(found))
except NameError:
  print('Not found')
else:
  # Handle rest of Found case here
  ...

3

カスタム関数を作成しました。

def exists(var):
     var_exists = var in locals() or var in globals()
     return var_exists

次に、次のような関数を呼び出して、variable_name確認する変数に置き換えます。

exists("variable_name")

戻るTrueFalse


2
いいえ、これは機能しません。locals()... ERR ...関数に対してローカルですexists😅
bgusach

1
1)locals()関数はローカルです。2)なぜvar_existsの追加割り当てが必要なのですか?
デイブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.