È possibile dichiarare solo una variabile senza assegnare alcun valore in Python?


288

È possibile dichiarare una variabile in Python, in questo modo ?:

var

in modo che inizializzato su Nessuno? Sembra che Python lo consenta, ma non appena si accede, si blocca. È possibile? Se no, perché?

EDIT: Voglio fare questo per casi come questo:

value

for index in sequence:

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

Duplicare

Relazionato


1
può pubblicare un piccolo programma che causa questo per favore.
Preet Sangha,

Hai pubblicato una domanda duplicata, votando per chiudere questa domanda a favore dell'altra.
Jerub

C'è ancora qualche differenza, questo riguarda il fatto di non poter usare una variabile semplicemente dichiarando.
Joan Venge,

Non c'è davvero nulla come dichiarare una variabile nel mondo Python, come spiega la tua prima domanda.
Harley Holcombe,

1
perché nessuno ha mai detto 'basta assegnargli' perché le variabili non esistono prima di essere assegnate al punto. E le variabili in Python non contengono le informazioni sul tipo. Gli oggetti lo fanno. Le variabili servono solo per contenere l'oggetto in quel momento. Inoltre, il programma sopra dovrebbe generare un'eccezione NameError sulla prima riga. (Questo è quello che ottengo in 2.X e 3.X entrambi)
osirisgothra

Risposte:


359

Perché non fare solo questo:

var = None

Python è dinamico, quindi non è necessario dichiarare le cose; esistono automaticamente nel primo ambito in cui sono assegnati. Quindi, tutto ciò che serve è una vecchia istruzione di assegnazione regolare come sopra.

Questo è carino, perché non finirai mai con una variabile non inizializzata. Ma fai attenzione: questo non significa che non finirai con variabili inizializzate in modo errato . Se inizi qualcosa a None, assicurati che sia quello che vuoi davvero e assegna qualcosa di più significativo se puoi.


1
Lo avrei fatto, ma ho pensato implicitamente che lo avrebbe fatto.
Joan Venge,

7
Il punto è che questo sia esplicito, non implicito. Non si può immaginare quale sia il valore iniziale. Non c'è da chiedersi se una variabile non inizializzata genera un'eccezione o magicamente ha un valore utile.
S.Lott

2
L'unico problema che ho avuto con questo era che stavo tenendo traccia di un contatore (minValue) e ogni volta che un valore era inferiore a quello, lo stavo impostando per diventare il nuovo minValue. Se inizialmente ho dichiarato minValue come Nessuno, a quanto pare è comunque inferiore a qualsiasi numero con cui lo abbia confrontato. Ho finito per inizializzarlo su sys.maxint
TJ Biddle

... esistono automaticamente nel primo ambito in cui sono assegnati. Quindi, devi dare la caccia a quel primo incarico e capirlo. ugh!
Ed Randall,

56

Consiglio vivamente di leggere Altre lingue con "variabili" (l'ho aggiunto come link correlato) - in due minuti saprai che Python ha "nomi", non "variabili".

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

Puoi anche scrivere val = val or any_objectper inizializzarlo.
Zoltán,

1
@Zoltán: si interrompe se un valore valido per val è "falso", ad esempio zero o vuoto. Utilizzare isper verificare se un valore è None.
jfs

Dopo aver letto l'articolo sul link fornito, sembra essere poco più che sofisma semantico.
Andrew P.

29

In Python 3.6+ puoi usare Annotazioni variabili per questo:

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

PEP 484 ha introdotto suggerimenti di tipo, noti anche come annotazioni di tipo. Mentre il suo obiettivo principale erano le annotazioni delle funzioni, ha anche introdotto la nozione di commenti di tipo per annotare le variabili:

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

PEP 526 mira ad aggiungere la sintassi a Python per annotare i tipi di variabili (comprese le variabili di classe e variabili di istanza), invece di esprimerli attraverso i commenti:

captain: str  # Note: no initial value!

Sembra essere più direttamente in linea con quello che stavi chiedendo "È possibile solo dichiarare una variabile senza assegnare alcun valore in Python?"


2
Ottima risposta
Ben

16

Non sono sicuro di cosa stai cercando di fare. Python è un linguaggio molto dinamico; di solito non è necessario dichiarare le variabili fino a quando non verranno effettivamente assegnate o utilizzate. Penso che quello che vuoi fare sia giusto

foo = None

che assegnerà il valore Nonealla variabile foo.

EDIT: Quello che sembra davvero voler fare è proprio questo:

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

È un po 'difficile dire se questo è davvero lo stile giusto da usare da un esempio di codice così breve, ma è un modo più "Pythonic" di lavorare.

EDIT: sotto è il commento di JFS (pubblicato qui per mostrare il codice)

Non correlato alla domanda del PO, ma il codice sopra può essere riscritto come:

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)

NOTA: se some_condition()genera un'eccezione, foundnon viene associato.
NOTA: se len (sequenza) == 0 itemnon è associato.

Il codice sopra non è consigliabile. Il suo scopo è di illustrare come funzionano le variabili locali, vale a dire se in questo caso la "variabile" è "definita" potrebbe essere determinata solo in fase di esecuzione. Modo preferibile:

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

O

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

if found:
   do_something(item)

C'è una differenza tra un linguaggio dinamico e un linguaggio molto dinamico?
Gavin Miller,

C'è un ottimo articolo che spiega i diversi assi della tipizzazione del linguaggio di programmazione e come sono continuum, non valori booleani; sfortunatamente non riesco mai a trovare di nuovo quell'articolo quando voglio citarlo :( Considero Python "molto dinamico" perché è all'estremità di più assi.
kquinn,

3

Di solito inizializzo la variabile su qualcosa che denota il tipo like

var = ""

o

var = 0

Se sarà un oggetto, non inizializzarlo fino a quando non lo avrai istanziato:

var = Var()

3

Bene, se vuoi controllare se una variabile è definita o no, allora perché non controllare se è nelle matrici locals () o globals ()? Il tuo codice riscritto:

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

Se è una variabile locale che stai cercando, sostituisci globals () con locals ().


2

Prima di tutto, la mia risposta alla domanda che hai inizialmente posto

D: Come posso scoprire se una variabile è definita in un punto del mio codice?

A: Leggi nel file sorgente fino a quando vedi una riga in cui è definita quella variabile.

Inoltre, hai fornito un esempio di codice secondo cui ci sono varie permutazioni che sono piuttosto pitoniche. Stai cercando un modo per scansionare una sequenza per elementi che corrispondono a una condizione, quindi ecco alcune soluzioni:

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

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

Chiaramente in questo esempio è possibile sostituire il raisecon un a return Noneseconda di ciò che si desidera ottenere.

Se volessi tutto ciò che corrispondeva alla condizione, potresti farlo:

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

    return matches

C'è un altro modo di farlo con yieldquello che non mi preoccuperò di mostrarti, perché è abbastanza complicato nel modo in cui funziona.

Inoltre, esiste un modo unico per raggiungere questo obiettivo:

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

2

Se sto capendo bene il tuo esempio, non è necessario fare riferimento a "valore" nell'istruzione if. Stai uscendo dal circuito non appena potrebbe essere impostato su qualsiasi cosa.

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

1

Sembra che tu stia provando a scrivere C in Python. Se vuoi trovare qualcosa in una sequenza, Python ha funzioni integrate per farlo, come

value = sequence.index(blarg)

1

È una buona domanda e sfortunatamente risposte cattive in quanto var = Nonesta già assegnando un valore e se lo script viene eseguito più volte viene sovrascritto Noneogni volta.

Non è lo stesso che definire senza incarico. Sto ancora cercando di capire come aggirare questo problema.


1

È possibile dichiarare una variabile in 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()

cattivo cattivo ragazzo cattivo! le variabili non associano il tipo, gli oggetti lo fanno. var_str non dovrebbe essere vincolato con un nome così generico. Se hai intenzione di farlo, rendilo significativo come 'var_age' o 'var_name' per esempio. Tali valori possono essere presi come numeri interi o stringhe o qualunque cosa tu voglia, e cambiati in oggetti, lo spirito stesso di ciò che rende Python diverso dalle altre lingue. Dicono che se ti ritrovi a doverlo fare continuamente, probabilmente vorrai usare un'altra lingua.
Osirisgothra,

0

Se Noneè un valore di dati valido, è necessario la variabile in un altro modo. Puoi usare:

var = object()

Questa sentinella è suggerita da Nick Coghlan .


0

Puoi ingannare un interprete con questo brutto oneliner. if None: var = None Non fa altro che aggiungere una variabile varal dizionario delle variabili locali, non inizializzarlo. L'interprete genererà l'eccezione UnboundLocalError se in seguito si tenta di utilizzare questa variabile in una funzione. Funzionerebbe anche per versioni molto antiche di Python. Non semplice, né bello, ma non aspettarti molto dal pitone.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.