Est-il possible de déclarer une variable uniquement sans affecter de valeur en Python?

288

Est-il possible de déclarer une variable en Python, comme ça?:

var

pour qu'il s'initialise sur None? Il semble que Python le permette, mais dès que vous y accédez, il se bloque. Est-ce possible? Sinon, pourquoi?

EDIT: Je veux le faire pour des cas comme celui-ci:

value

for index in sequence:

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

Dupliquer

en relation

Joan Venge
la source
1
peut publier un petit programme qui provoque cela s'il vous plaît.
Preet Sangha
Vous avez posté une question en double, votant pour clore cette question en faveur de l'autre.
Jerub
Il y a encore une différence, celui-ci traite du fait de ne pas pouvoir utiliser une variable simplement en déclarant.
Joan Venge
Il n'y a pas vraiment de déclaration de variable dans le monde python, comme l'explique votre première question.
Harley Holcombe
1
pourquoi personne n'a-t-il jamais dit «juste lui assigner» parce que les variables n'existent pas avant d'être assignées à la période. Et les variables en python ne contiennent pas les informations de type. Les objets font ça. Les variables servent uniquement à maintenir l'objet à ce moment précis. En outre, le programme ci-dessus doit lever une exception NameError sur la première ligne. (C'est ce que j'obtiens dans les versions 2.X et 3.X)
osirisgothra

Réponses:

359

Pourquoi ne pas simplement faire ceci:

var = None

Python est dynamique, vous n'avez donc pas besoin de déclarer des choses; ils existent automatiquement dans la première étendue où ils sont affectés. Donc, tout ce dont vous avez besoin est une ancienne déclaration d'affectation régulière comme ci-dessus.

C'est bien, car vous ne vous retrouverez jamais avec une variable non initialisée. Mais soyez prudent - cela ne signifie pas que vous ne vous retrouverez pas avec des variables incorrectement initialisées. Si vous lancez quelque chose None, assurez-vous que c'est ce que vous voulez vraiment et attribuez quelque chose de plus significatif si vous le pouvez.

Todd Gamblin
la source
1
J'allais faire ça, mais je pensais implicitement que ça ferait ça.
Joan Venge
7
Le fait est que cela soit explicite et non implicite. Pas de deviner quelle est la valeur initiale. Pas besoin de se demander si une variable non initialisée lève une exception ou a comme par magie une valeur utile.
S.Lott
2
Le seul problème que j'ai avec ceci était que je suivais un compteur (minValue) et chaque fois qu'une valeur était inférieure à celle-ci, je la définissais pour devenir la nouvelle minValue. Si j'ai déclaré minValue comme None à l'origine, il est apparemment toujours inférieur à tous les chiffres auxquels je l'ai comparé. J'ai fini par l'initialiser à sys.maxint
TJ Biddle
... ils existent automatiquement dans la première étendue où ils sont affectés. Donc, vous devez traquer cette première affectation et le découvrir. Pouah!
Ed Randall
56

Je vous recommande vivement de lire Les autres langues ont des "variables" (je les ai ajoutées comme lien connexe) - en deux minutes, vous saurez que Python a des "noms", pas des "variables".

val = None
# ...
if val is None:
   val = any_object
jfs
la source
Vous pouvez également écrire val = val or any_objectpour l'initialiser.
Zoltán
1
@ Zoltán: il se casse si une valeur valide pour val est "false" par exemple, zéro ou vide. Utilisez ispour tester si une valeur est None.
jfs
Après avoir lu l'article sur le lien fourni, il semble que ce ne soit rien de plus qu'une sophistique sémantique.
Andrew P.
29

Dans Python 3.6+, vous pouvez utiliser des annotations variables pour cela:

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

PEP 484 a introduit des indications de type, également appelées annotations de type. Alors que son objectif principal était les annotations de fonction, il a également introduit la notion de commentaires de type pour annoter les variables:

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

Le PEP 526 vise à ajouter de la syntaxe à Python pour annoter les types de variables (y compris les variables de classe et les variables d'instance), au lieu de les exprimer par des commentaires:

captain: str  # Note: no initial value!

Il semble être plus directement en ligne avec ce que vous demandiez "Est-il possible de déclarer une variable uniquement sans affecter de valeur en Python?"

Tagar
la source
2
Excellente réponse
Ben
16

Je ne sais pas trop ce que vous essayez de faire. Python est un langage très dynamique; vous n'avez généralement pas besoin de déclarer des variables avant de les affecter ou de les utiliser. Je pense que ce que tu veux faire c'est

foo = None

qui attribuera la valeur Noneà la variable foo.

EDIT: Ce que vous semblez vraiment vouloir faire, c'est juste ceci:

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

Il est un peu difficile de dire si c'est vraiment le bon style à utiliser dans un tel court exemple de code, mais il est une autre façon de travailler « Pythonic ».

EDIT: ci-dessous est le commentaire de JFS (affiché ici pour afficher le code)

Sans rapport avec la question du PO, mais le code ci-dessus peut être réécrit comme suit:

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)

REMARQUE: si some_condition()déclenche une exception, il foundn'est pas lié.
REMARQUE: si len (séquence) == 0 itemest alors non lié.

Le code ci-dessus n'est pas recommandé. Son but est d'illustrer le fonctionnement des variables locales, à savoir si la "variable" est "définie" ne pourrait être déterminée qu'au moment de l'exécution dans ce cas. Manière préférable:

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

Ou

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

if found:
   do_something(item)
kquinn
la source
Y a-t-il une différence entre une langue dynamique et une langue très dynamique?
Gavin Miller
Il y a un excellent article expliquant les différents axes du typage du langage de programmation, et comment ils sont des continuums, pas des valeurs booléennes; malheureusement je ne retrouve jamais cet article quand je veux le citer :( Je considère Python "très dynamique" car il est à l'extrémité de plusieurs axes.
kquinn
3

J'initialise généralement la variable à quelque chose qui dénote le type comme

var = ""

ou

var = 0

S'il s'agit d'un objet, ne l'initialisez pas tant que vous ne l'instanciez pas:

var = Var()
Andrew Hare
la source
3

Eh bien, si vous voulez vérifier si une variable est définie ou non, alors pourquoi ne pas vérifier si elle est dans les tableaux locals () ou globals ()? Votre code réécrit:

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

Si c'est une variable locale que vous recherchez, remplacez globals () par locals ().

Johan
la source
2

Tout d'abord, ma réponse à la question que vous avez initialement posée

Q: Comment savoir si une variable est définie à un point de mon code?

R: Lisez dans le fichier source jusqu'à ce que vous voyiez une ligne où cette variable est définie.

Mais en outre, vous avez donné un exemple de code selon lequel il existe différentes permutations qui sont assez pythoniques. Vous recherchez un moyen de scanner une séquence pour trouver des éléments qui correspondent à une condition, voici donc quelques solutions:

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

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

De toute évidence, dans cet exemple, vous pouvez remplacer le raisepar un en return Nonefonction de ce que vous souhaitez réaliser.

Si vous vouliez tout ce qui correspondait à la condition, vous pouvez le faire:

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

    return matches

Il y a une autre façon de le faire avec yieldlaquelle je ne vais pas vous montrer, car c'est assez compliqué dans la façon dont cela fonctionne.

De plus, il existe un moyen unique pour y parvenir:

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

Si je comprends bien votre exemple, vous n'avez de toute façon pas besoin de faire référence à la «valeur» dans l'instruction if. Vous sortez de la boucle dès qu'il peut être réglé sur quoi que ce soit.

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

On dirait que vous essayez d'écrire C en Python. Si vous voulez trouver quelque chose dans une séquence, Python a des fonctions intégrées pour le faire, comme

value = sequence.index(blarg)

la source
1

C'est une bonne question et malheureusement de mauvaises réponses, tout comme l' var = Noneattribution d'une valeur, et si votre script s'exécute plusieurs fois, il est écrasé à Nonechaque fois.

Ce n'est pas la même chose que de définir sans attribution. J'essaie toujours de comprendre comment contourner ce problème.

zinturis
la source
1

Est-il possible de déclarer une variable en Python (var = None):

def decl_var(var=None):
if var is None:
    var = []
var.append(1)
return var
Abderrahim
la source
0
var_str = str()
var_int = int()
Zaur
la source
vilain vilain vilain homme! les variables n'associent pas le type, les objets le font. var_str ne doit pas être contraint dans un nom aussi générique. Si vous allez faire cela, rendez-le significatif comme 'var_age' ou 'var_name' par exemple. Ces valeurs peuvent être prises comme des entiers ou des chaînes ou tout ce que vous voulez, et changées en objets, l'esprit même de ce qui rend le python différent des autres langages. Ils disent que si vous devez faire cela tout le temps, vous voudrez probablement utiliser une autre langue.
osirisgothra
0

Si Noneest une valeur de données valide, vous devez modifier la variable d'une autre manière. Vous pouvez utiliser:

var = object()

Cette sentinelle est suggérée par Nick Coghlan .

Chris_Rands
la source
0

Vous pouvez tromper un interprète avec ce laid oneliner if None: var = None Il ne fait rien d'autre que d'ajouter une variable varau dictionnaire de variables local, pas de l'initialiser. L'interpréteur lèvera l'exception UnboundLocalError si vous essayez d'utiliser cette variable dans une fonction par la suite. Cela fonctionnerait également pour les versions très anciennes de python. Pas simple, ni beau, mais n'attendez pas grand-chose de python.

ZAB
la source