Ist es nur möglich, eine Variable zu deklarieren, ohne in Python einen Wert zuzuweisen?

288

Ist es möglich, eine Variable in Python so zu deklarieren?:

var

damit es auf None initialisiert wird? Es scheint, als ob Python dies zulässt, aber sobald Sie darauf zugreifen, stürzt es ab. Ist das möglich? Wenn nicht, warum?

EDIT: Ich möchte dies für Fälle wie diesen tun:

value

for index in sequence:

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

Duplikat

verbunden

Joan Venge
quelle
1
kann bitte ein kleines Programm posten, das dies verursacht.
Preet Sangha
Sie haben eine doppelte Frage gestellt und dafür gestimmt, diese Frage zugunsten der anderen zu schließen.
Jerub
Es gibt immer noch einen Unterschied, dieser befasst sich damit, dass eine Variable nicht einfach durch Deklarieren verwendet werden kann.
Joan Venge
Es gibt nicht wirklich das Deklarieren einer Variablen in der Python-Welt, wie Ihre erste Frage erklärt.
Harley Holcombe
1
Warum hat niemand jemals "nur zuweisen" gesagt, weil Variablen nicht existieren, bevor sie der Periode zugewiesen werden? Und Variablen in Python enthalten keine Typinformationen. Objekte machen das. Variablen dienen nur dazu, das Objekt zu diesem Zeitpunkt zu halten. Darüber hinaus sollte das obige Programm eine NameError-Ausnahme in der ersten Zeile auslösen. (Das ist, was ich in 2.X und 3.X beide bekomme)
Osirisgothra

Antworten:

359

Warum nicht einfach so machen:

var = None

Python ist dynamisch, sodass Sie keine Dinge deklarieren müssen. Sie existieren automatisch in dem ersten Bereich, in dem sie zugewiesen sind. Alles, was Sie brauchen, ist eine reguläre alte Zuweisungsanweisung wie oben.

Das ist schön, weil Sie nie eine nicht initialisierte Variable haben werden. Aber seien Sie vorsichtig - dies bedeutet nicht, dass Sie nicht mit falsch initialisierten Variablen enden . Wenn Sie etwas Noneinitiieren, stellen Sie sicher, dass es das ist, was Sie wirklich wollen, und weisen Sie etwas Bedeutenderes zu, wenn Sie können.

Todd Gamblin
quelle
1
Ich wollte das tun, dachte aber nur implizit, dass es das tun würde.
Joan Venge
7
Es geht darum, dass dies explizit und nicht implizit ist. Keine Vermutung, was der Anfangswert ist. Keine Frage, ob eine nicht initialisierte Variable eine Ausnahme auslöst oder auf magische Weise einen nützlichen Wert hat.
S.Lott
2
Das einzige Problem, das ich damit habe, war, dass ich einen Zähler (minValue) verfolgte und jedes Mal, wenn ein Wert niedriger als dieser war, ihn auf den neuen minValue festlegte. Wenn ich minValue ursprünglich als None deklariert habe, ist es anscheinend immer noch niedriger als alle Zahlen, mit denen ich es verglichen habe. Am Ende habe ich es nur bei sys.maxint
TJ Biddle
... sie existieren automatisch im ersten Bereich, in dem sie zugewiesen sind. Sie müssen also diese erste Aufgabe suchen und herausfinden. Pfui!
Ed Randall
56

Ich würde Ihnen wärmstens empfehlen, andere Sprachen mit "Variablen" zu lesen (ich habe sie als verwandten Link hinzugefügt) - in zwei Minuten wissen Sie, dass Python "Namen" und keine "Variablen" hat.

val = None
# ...
if val is None:
   val = any_object
jfs
quelle
Sie können auch schreiben val = val or any_object, um es zu initialisieren.
Zoltán
1
@ Zoltán: Es bricht ab, wenn ein gültiger Wert für val "falsch" ist, z. B. Null oder leer. Verwenden Sie isdiese Option , um zu testen, ob ein Wert vorliegt None.
JFS
Nach dem Lesen des Artikels unter dem angegebenen Link scheint es kaum mehr als semantische Sophistik zu sein.
Andrew P.
29

In Python 3.6+ können Sie hierfür variable Anmerkungen verwenden:

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

In PEP 484 wurden Typhinweise, auch Typanmerkungen genannt, eingeführt. Während der Schwerpunkt auf Funktionsanmerkungen lag, wurde auch der Begriff der Typkommentare zum Annotieren von Variablen eingeführt:

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

PEP 526 zielt darauf ab, Python eine Syntax zum Kommentieren der Variablentypen (einschließlich Klassenvariablen und Instanzvariablen) hinzuzufügen, anstatt sie durch Kommentare auszudrücken:

captain: str  # Note: no initial value!

Es scheint direkter mit Ihrer Frage übereinzustimmen: "Ist es nur möglich, eine Variable zu deklarieren, ohne in Python einen Wert zuzuweisen?"

Tagar
quelle
2
Ausgezeichnete Antwort
Ben
16

Ich bin mir nicht sicher, was Sie versuchen zu tun. Python ist eine sehr dynamische Sprache. Normalerweise müssen Sie Variablen erst deklarieren, wenn Sie sie tatsächlich zuweisen oder verwenden. Ich denke, was Sie tun wollen, ist gerecht

foo = None

Dadurch wird Noneder Variablen der Wert zugewiesen foo.

EDIT: Was Sie wirklich zu wollen scheinen, ist genau das:

#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"

Es ist ein wenig schwierig zu sagen, ob dies wirklich der richtige Stil für ein so kurzes Codebeispiel ist, aber es ist eine eher "pythonische" Arbeitsweise.

BEARBEITEN: unten ist ein Kommentar von JFS (hier gepostet, um den Code zu zeigen)

Unabhängig von der Frage des OP, aber der obige Code kann wie folgt umgeschrieben werden:

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)

HINWEIS: Wenn some_condition()eine Ausnahme ausgelöst wird, foundist diese nicht gebunden.
HINWEIS: Wenn len (Sequenz) == 0 ist, itemist es ungebunden.

Der obige Code ist nicht ratsam. Sie soll veranschaulichen, wie lokale Variablen funktionieren, nämlich ob "Variable" "definiert" ist und in diesem Fall nur zur Laufzeit bestimmt werden kann. Bevorzugter Weg:

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

Oder

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

if found:
   do_something(item)
Kquinn
quelle
Gibt es einen Unterschied zwischen einer dynamischen Sprache und einer sehr dynamischen Sprache?
Gavin Miller
Es gibt einen großartigen Artikel, der die verschiedenen Achsen der Typisierung von Programmiersprachen erklärt und erklärt, wie sie Kontinuen und keine booleschen Werte sind. Leider kann ich diesen Artikel nie wieder finden, wenn ich ihn zitieren möchte :( Ich halte Python für "sehr dynamisch", weil es am anderen Ende mehrerer Achsen liegt.
kquinn
3

Normalerweise initialisiere ich die Variable mit etwas, das den Typ wie bezeichnet

var = ""

oder

var = 0

Wenn es sich um ein Objekt handelt, initialisieren Sie es erst, wenn Sie es instanziieren:

var = Var()
Andrew Hare
quelle
3

Wenn Sie überprüfen möchten, ob eine Variable definiert ist oder nicht, überprüfen Sie dann, ob sie in den Arrays local () oder globals () enthalten ist. Ihr Code wurde neu geschrieben:

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

Wenn es sich um eine lokale Variable handelt, nach der Sie suchen, ersetzen Sie globals () durch local ().

Johan
quelle
2

Zunächst meine Antwort auf die Frage, die Sie ursprünglich gestellt haben

F: Wie kann ich feststellen, ob an einem Punkt in meinem Code eine Variable definiert ist?

A: Lesen Sie in der Quelldatei nach, bis Sie eine Zeile sehen, in der diese Variable definiert ist.

Aber weiter haben Sie ein Codebeispiel gegeben, dass es verschiedene Permutationen gibt, die ziemlich pythonisch sind. Sie suchen nach einer Möglichkeit, eine Sequenz nach Elementen zu durchsuchen, die einer Bedingung entsprechen. Hier sind einige Lösungen:

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

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

In diesem Beispiel können Sie das natürlich raisedurch ein ersetzen, return Noneje nachdem, was Sie erreichen möchten.

Wenn Sie alles wollten, was der Bedingung entspricht, können Sie dies tun:

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

    return matches

Es gibt einen anderen Weg, dies zu tun yield, den ich Ihnen nicht zeigen werde, weil es in der Art und Weise, wie es funktioniert, ziemlich kompliziert ist.

Darüber hinaus gibt es einen einzeiligen Weg, um dies zu erreichen:

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

Wenn ich Ihr Beispiel richtig verstehe, müssen Sie in der if-Anweisung sowieso nicht auf 'value' verweisen. Sie brechen aus der Schleife aus, sobald sie auf irgendetwas eingestellt werden kann.

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

Sie sehen aus, als würden Sie versuchen, C in Python zu schreiben. Wenn Sie etwas in einer Sequenz finden möchten, verfügt Python über integrierte Funktionen, um dies zu tun, wie z

value = sequence.index(blarg)

quelle
1

Es ist eine gute Frage und leider eine schlechte Antwort, da var = Nonebereits ein Wert zugewiesen wird. Wenn Ihr Skript mehrmals ausgeführt wird, wird es Nonejedes Mal überschrieben .

Es ist nicht dasselbe wie ohne Zuweisung zu definieren. Ich versuche immer noch herauszufinden, wie ich dieses Problem umgehen kann.

Zinturis
quelle
1

Ist es möglich, eine Variable in Python zu deklarieren (var = None):

def decl_var(var=None):
if var is None:
    var = []
var.append(1)
return var
Abderrahim
quelle
0
var_str = str()
var_int = int()
Zaur
quelle
frecher ungezogener ungezogener Mann! Variablen assoziieren keinen Typ, Objekte nicht. var_str sollte in einem solchen generischen Namen nicht eingeschränkt werden. Wenn Sie dies tun, machen Sie es sinnvoll, wie zum Beispiel 'var_age' oder 'var_name'. Solche Werte können als Ganzzahlen oder Zeichenfolgen oder was auch immer Sie wollen genommen und in Objekte geändert werden, genau der Geist dessen, was Python von anderen Sprachen unterscheidet. Sie sagen, wenn Sie dies die ganze Zeit tun müssen, möchten Sie wahrscheinlich eine andere Sprache verwenden.
Osirisgothra
0

Wenn Nonees sich um einen gültigen Datenwert handelt, müssen Sie die Variable auf andere Weise verwenden. Du könntest benutzen:

var = object()

Dieser Sentinel wird von Nick Coghlan vorgeschlagen .

Chris_Rands
quelle
0

Sie können einen Interpreter mit diesem hässlichen Oneliner austricksen. if None: var = None Er fügt vardem lokalen Variablenwörterbuch eine Variable hinzu und initialisiert sie nicht. Der Interpreter löst die UnboundLocalError-Ausnahme aus, wenn Sie versuchen, diese Variable anschließend in einer Funktion zu verwenden. Dies würde auch für sehr alte Python-Versionen funktionieren. Nicht einfach oder schön, aber erwarten Sie nicht viel von Python.

ZAB
quelle