Pythonで値を割り当てずに変数を宣言することだけが可能ですか?


288

このようにPythonで変数を宣言することは可能ですか?:

var

それがNoneに初期化されるように?Pythonはこれを許可しているようですが、アクセスするとすぐにクラッシュします。これは可能ですか?そうでない場合、なぜですか?

編集:私はこのような場合のためにこれをしたいです:

value

for index in sequence:

   if value == None and conditionMet:
       value = index
       break

複製

関連した


1
これを引き起こす小さなプログラムを投稿してください。
Preet Sangha

重複する質問を投稿し、他の質問を支持してこの質問を閉じることに投票しました。
ジェルブ2009年

まだいくつかの違いがありますが、これは宣言するだけでは変数を使用できないことを扱います。
Joan Venge

最初の質問で説明されているように、Pythonの世界で変数を宣言するようなものは実際にはありません。
Harley Holcombe

1
変数はピリオドに割り当てられる前に存在しないため、「それに割り当てるだけ」と誰も言わなかったのはなぜですか。また、Pythonの変数には型情報が含まれていません。オブジェクトはそれを行います。変数は、その時点でオブジェクトを保持するためだけのものです。さらに、上記のプログラムは最初の行でNameError例外をスローする必要があります。(これが2.Xと3.Xの両方で得られるもの)
osirisgothra

回答:


359

なぜこれをしないのですか?

var = None

Pythonは動的であるため、宣言する必要はありません。それらは、割り当てられた最初のスコープに自動的に存在します。したがって、必要なのは上記の通常の古い割り当てステートメントだけです。

初期化されていない変数で終わることは決してないので、これは素晴らしいことです。しかし、注意してください。これは、誤って初期化された変数で終了しないという意味ではありません。に何かを初期化する場合はNone、それが本当に欲しいものであることを確認し、可能であればより意味のあるものを割り当てます。


1
私はそうするつもりでしたが、暗黙のうちにそれができると思っていました。
Joan Venge

7
重要なのは、これが暗黙的ではなく明示的であることです。初期値が何であるかを推測する必要はありません。初期化されていない変数が例外をスローするのか、魔法のように便利な値があるのか​​は不思議ではありません。
S.Lott、2009年

2
これに関する唯一の問題は、カウンター(minValue)を追跡していて、値がそれよりも低い場合はいつでも、新しいminValueになるように設定していたことです。最初にminValueをNoneと宣言した場合は、比較したどの数値よりもまだ低いようです。最終的にsys.maxintで初期化しただけです
TJ Biddle

...割り当てられた最初のスコープに自動的に存在します。そのため、最初の割り当てを見つけ出して、それを理解する必要があります。うわっ!
Ed Randall

56

他の言語には「変数」がある(関連リンクとして追加しました)をお読みになることを強くお勧めします。2分で、Pythonには「変数」ではなく「名前」があることがわかります。

val = None
# ...
if val is None:
   val = any_object

val = val or any_objectそれを初期化するために書くこともできます。
ゾルタン

1
@Zoltán:valの有効な値がゼロまたは空などの "false"の場合は、壊れます。is値がかどうかをテストするために使用しますNone
jfs

提供されたリンクで記事を読んだ後、それは意味論的な学問に過ぎないようです。
Andrew P.

29

Python 3.6以降では、変数アノテーションを使用できます。

https://www.python.org/dev/peps/pep-0526/#abstract

PEP 484では、型ヒント、別名型注釈が導入されました。その主な焦点は関数の注釈でしたが、変数に注釈を付けるための型コメントの概念も導入しました。

# 'captain' is a string (Note: initial value is a problem)
captain = ...  # type: str

PEP 526は、コメントを通じて変数を表現するのではなく、Pythonに構文を追加して変数のタイプ(クラス変数やインスタンス変数を含む)に注釈を付けることを目的としています。

captain: str  # Note: no initial value!

「Pythonで値を割り当てずに変数を宣言することだけが可能ですか?」


2
すばらしい答え
Ben

16

何をしようとしているのかわかりません。Pythonは非常に動的な言語です。実際に変数を割り当てるか使用するまで、通常は変数を宣言する必要はありません。あなたがしたいのはただ

foo = None

None変数に値を割り当てますfoo

編集:あなたが本当にやりたいように見えるのはこれだけです:

#note how I don't do *anything* with value here
#we can just start using it right inside the loop

for index in sequence:
   if conditionMet:
       value = index
       break

try:
    doSomething(value)
except NameError:
    print "Didn't find anything"

そのような短いコードの例から使用するのが本当に適切なスタイルかどうかを判断するのは少し難しいですが、より「Python的な」方法で作業できます。

編集:以下はJFSによるコメントです(コードを示すためにここに投稿されています)

OPの質問とは関係ありませんが、上記のコードは次のように書き直すことができます。

for item in sequence:
    if some_condition(item): 
       found = True
       break
else: # no break or len(sequence) == 0
    found = False

if found:
   do_something(item)

注:some_condition()例外が発生した場合foundはバインドされません。
注:len(sequence)== 0の場合item、バインドされていません。

上記のコードはお勧めできません。その目的は、ローカル変数がどのように機能するかを説明することです。つまり、この場合、「変数」が「定義」されているかどうかは、実行時にのみ決定できます。好ましい方法:

for item in sequence:
    if some_condition(item):
       do_something(item)
       break

または

found = False
for item in sequence:
    if some_condition(item):
       found = True
       break

if found:
   do_something(item)

動的言語と非常に動的な言語の間に違いはありますか?
Gavin Miller

プログラミング言語のタイピングのさまざまな軸と、それらがブール値ではなく連続体であることを説明する優れた記事があります。私はそれが複数の軸の遠端にありますので、:(私はPythonは「非常にダイナミック」を検討し、それを引用したい場合、残念ながら私は再びその記事を見つけることはできません。
kquinn

3

私は通常、変数を次のようなタイプを表すものに初期化します

var = ""

または

var = 0

オブジェクトにする場合は、インスタンス化するまで初期化しないでください。

var = Var()

3

変数が定義されているかどうかを確認したい場合は、locals()またはglobals()配列にあるかどうかを確認してください。あなたのコードは書き直されました:

for index in sequence:
   if 'value' not in globals() and conditionMet:
       value = index
       break

探しているローカル変数の場合は、globals()をlocals()に置き換えます。


2

まず、あなたが最初に尋ねた質問に対する私の回答

Q:変数がコード内のある時点で定義されているかどうかを確認するにはどうすればよいですか?

A:その変数が定義されている行が表示されるまで、ソースファイルを読み取ります。

しかし、さらに、Pythonのようにさまざまな順列があるコード例を示しました。あなたは条件に一致する要素のシーケンスをスキャンする方法を求めているので、ここにいくつかの解決策があります:

def findFirstMatch(sequence):
    for value in sequence:
        if matchCondition(value):
            return value

    raise LookupError("Could not find match in sequence")

明らかにこの例raiseでは、をreturn Noneは、達成したいものに応じてます。

条件に一致するすべてが必要な場合は、次のようにすることができます。

def findAllMatches(sequence):
    matches = []
    for value in sequence:
        if matchCondition(value):
            matches.append(value)

    return matches

これを実行する別の方法がありますがyield、その方法は非常に複雑であるため、ここでは説明しません。

さらに、これを達成するための1行の方法があります。

all_matches = [value for value in sequence if matchCondition(value)]

2

私があなたの例を正しく理解しているなら、とにかくifステートメントで 'value'を参照する必要はありません。何かに設定されるとすぐにループから抜け出します。

value = None
for index in sequence:
   doSomethingHere
   if conditionMet:
       value = index
       break 

1

あなたはPythonでCを書こうとしているように見えます。シーケンスで何かを検索したい場合、Pythonにはそれを行う組み込み関数があります。

value = sequence.index(blarg)

1

var = Noneすでに値を割り当てているので、これは良い質問であり、残念ながら悪い答えです。スクリプトが複数回実行さNoneれると、毎回上書きされます。

割り当てなしで定義することと同じではありません。私はまだこの問題を回避する方法を理解しようとしています。


1

Pythonで変数を宣言することは可能ですか(var = None):

def decl_var(var=None):
if var is None:
    var = []
var.append(1)
return var

0
var_str = str()
var_int = int()

いたずらいたずらいたずらな男!変数は型を関連付けませんが、オブジェクトは関連付けます。var_strは、このような一般的な名前で制約されるべきではありません。これを行う場合は、たとえば、 'var_age'または 'var_name'のように意味のあるものにします。そのような値は、整数や文字列など、好きなものとして取得でき、オブジェクトに変更できます。これは、Pythonを他の言語と異なるものにする精神です。彼らはあなたがいつもこれをする必要があると感じたら、おそらく他の言語を使いたいと思うでしょう。
osirisgothra 2015

0

Noneが有効なデータ値である場合は、別の方法で変数を指定する必要があります。あなたは使うことができます:

var = object()

この歩哨はニックコグランによって提案されます。


0

この醜いワンライナーでインタプリタをだますif None: var = None ことができますvar。ローカル変数ディクショナリに変数を追加するだけで、初期化はしません。後で関数でこの変数を使用しようとすると、インタープリターはUnboundLocalError例外をスローします。これは非常に古いpythonバージョンでも機能します。単純でも美しくもありませんが、Pythonにはあまり期待していません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.