web-dev-qa-db-fra.com

Qu'est-ce qu'une valeur None?

J'ai étudié Python et j'ai lu un chapitre décrivant la valeur de None, mais malheureusement, ce livre n'est pas très clair à certains moments. Je pensais que je trouverais la réponse à ma question si je la partage ici.

Je veux savoir ce que la valeur Noneest et à quoi l'utilisez-vous?

Et aussi, je ne comprends pas cette partie du livre:

L'affectation d'une valeur de None à une variable est un moyen de la réinitialiser à son état d'origine vide.

Qu'est-ce que ça veut dire?

Les réponses étaient excellentes, même si je n'ai pas compris la plupart des réponses à cause de ma faible connaissance du monde de l'informatique (je n'ai pas appris sur les classes, les objets, etc.). Que signifie cette phrase?

L'affectation d'une valeur de None à une variable est un moyen de la réinitialiser à son état d'origine vide.

Final:

Enfin, ma réponse consiste à chercher différentes réponses. Je dois remercier toutes les personnes qui ont mis leur temps pour m'aider (en particulier Martijn Pieters et DSM) et je souhaite pouvoir choisir toutes les réponses comme étant les meilleures, mais la sélection est limitée à une. Toutes les réponses étaient excellentes.

113
The_Diver

La réponse de Martijn explique ce qu'est None en Python et indique correctement que le livre est trompeur. Puisque Python, les programmeurs ne diraient jamais

L'affectation d'une valeur de None à une variable est un moyen de la réinitialiser à son état d'origine vide.

il est difficile d'expliquer ce que Briggs veut dire d'une manière qui a du sens et qui explique pourquoi personne ici n'en semble heureux. Une analogie qui peut aider:

En Python, les noms de variable sont comme des autocollants placés sur des objets. Chaque autocollant porte un nom unique et ne peut figurer que sur un objet à la fois, mais vous pouvez apposer plusieurs autocollants sur le même objet, si vous le souhaitez. Quand tu écris

F = "fork"

vous placez l'autocollant "F" sur un objet chaîne "fork". Si vous écrivez alors

F = None

vous déplacez l’autocollant sur l’objet None.

Ce que Briggs vous demande d’imaginer, c’est que vous n’avez pas écrire l’autocollant "F", il y avait déjà un autocollant F sur le None, et tout ce que vous avez fait était déplacer le, de None à "fork". Ainsi, lorsque vous tapez F = None, vous "réinitialisez [son état] vide,", si nous décidons de traiter None comme signifiant empty state.

Je peux voir où il veut en venir, mais c'est une mauvaise façon de voir les choses. Si vous démarrez Python et tapez print(F), vous voyez

>>> print(F)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'F' is not defined

et que NameError signifie que Python ne reconnaît pas le nom F, car il n'y a pas d'autocollant de ce type. Si Briggs avait raison et que F = None réinitialise F à son état d'origine, il devrait alors être là, et nous devrions voir

>>> print(F)
None

comme nous le faisons après avoir tapé F = None et mis l'autocollant sur None.


Donc c'est tout ce qui se passe. En réalité, Python est livré avec des autocollants déjà attachés à des objets (noms intégrés), mais vous devez vous en écrire d'autres avec des lignes telles que F = "fork" et A = 2 et c17 = 3.14 et vous pourrez ensuite les coller ultérieurement sur d'autres objets (comme F = 10 ou F = None; c'est la même chose.)

Briggs prétend que tous les autocollants possibles que vous pourriez vouloir écrire étaient déjà collés à l'objet None.

85
DSM

None est simplement une valeur couramment utilisée pour signifier "vide" ou "pas de valeur ici". C'est un objet signal ; cela n'a de sens que parce que la documentation Python indique que c'est le cas.

Il n'y a qu'une seule copie de cet objet dans une session d'interprétation Python donnée.

Si vous écrivez une fonction et que celle-ci n'utilise pas d'instruction return explicite, None est renvoyé à la place, par exemple. De cette façon, la programmation avec des fonctions est beaucoup simplifiée. une fonction toujours renvoie quelque chose , même s'il ne s'agit que de cet objet None.

Vous pouvez le tester explicitement:

if foo is None:
    # foo is set to None

if bar is not None:
    # bar is set to something *other* than None

Une autre utilisation est de donner aux paramètres optionnels des fonctions un "vide" par défaut:

def spam(foo=None):
    if foo is not None:
        # foo was specified, do something clever!

La fonction spam() a un argument optionnel; si vous appelez spam() sans le spécifier, la valeur par défaut None lui est donnée, ce qui permet de détecter facilement si la fonction a été appelée avec un argument ou non.

D'autres langues ont des concepts similaires. SQL a NULL; JavaScript a undefined ET null , etc.

Notez qu'en Python, les variables existent en vertu de leur utilisation. Il n'est pas nécessaire de déclarer d'abord une variable, il n'y a donc pas de variable vraiment vide dans Python. Définir une variable sur None n’est donc pas la même chose que la définir sur une valeur vide par défaut; None est aussi une valeur, même si elle est souvent utilisée pour signaler le vide. Le livre que vous lisez est trompeur sur ce point.

56
Martijn Pieters

C’est ce que la documentation Python a à dire à propos de None:

La seule valeur de types.NoneType. Aucun est fréquemment utilisé pour représenter l'absence de valeur, comme lorsque les arguments par défaut ne sont pas transmis à une fonction.

Modifié dans la version 2.4: les assignations à Aucune sont illégales et génèrent une SyntaxError.

Remarque Les noms Aucun et debug ne peuvent pas être réaffectés (leur affectation, même en tant que nom d'attribut, soulèvent SyntaxError), ils peuvent donc être considérés comme "vrais". des constantes.

  1. Confirmons le type de None en premier

    print type(None)
    print None.__class__
    

    Sortie

    <type 'NoneType'>
    <type 'NoneType'>
    

Fondamentalement, NoneType est un type de données au même titre que int, float, etc. Vous pouvez extraire la liste des types par défaut disponibles dans Python in 8.15. Types - Noms des types intégrés.

  1. Et, None est une instance de NoneType class. Nous pourrions donc vouloir créer des instances de None nous-mêmes. Essayons ça

    print types.IntType()
    print types.NoneType()
    

    Sortie

    0
    TypeError: cannot create 'NoneType' instances
    

Si clairement, impossible de créer des instances NoneType. Nous n'avons pas à nous soucier de l'unicité de la valeur None.

  1. Voyons comment nous avons implémenté None en interne.

    print dir(None)
    

    Sortie

    ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', 
     '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__',
     '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
    

À l'exception de __setattr__, tous les autres sont des attributs en lecture seule. Il n’ya donc aucun moyen de modifier les attributs de None.

  1. Essayons d'ajouter de nouveaux attributs à None

    setattr(types.NoneType, 'somefield', 'somevalue')
    setattr(None, 'somefield', 'somevalue')
    None.somefield = 'somevalue'
    

    Sortie

    TypeError: can't set attributes of built-in/extension type 'NoneType'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    AttributeError: 'NoneType' object has no attribute 'somefield'
    

Les instructions vues ci-dessus produisent ces messages d'erreur, respectivement. Cela signifie que nous ne pouvons pas créer d'attributs de manière dynamique sur une instance None.

  1. Laissez-nous vérifier ce qui se passe lorsque nous assignons quelque chose None. Selon la documentation, il devrait lancer un SyntaxError. Cela signifie que si nous affectons quelque chose à None, le programme ne sera pas exécuté du tout.

    None = 1
    

    Sortie

    SyntaxError: cannot assign to None
    

Nous avons établi que

  1. None est une instance de NoneType
  2. None ne peut pas avoir de nouveaux attributs
  3. Les attributs existants de None ne peuvent pas être modifiés.
  4. Nous ne pouvons pas créer d'autres instances de NoneType
  5. Nous ne pouvons même pas changer la référence en None en lui attribuant des valeurs.

Ainsi, comme mentionné dans la documentation, None peut vraiment être considéré comme un true constant.

Heureux de savoir None :)

19
thefourtheye

Le livre auquel vous faites référence essaye clairement de grandement simplifier le sens de None. Python les variables n'ont pas un état initial vide - Les variables Python sont liées (uniquement)) lorsqu'elles ' re défini . Vous ne pouvez pas créer une variable Python sans lui donner une valeur.

>>> print(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> def test(x):
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: test() takes exactly 1 argument (0 given)
>>> def test():
...   print(x)
... 
>>> test()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in test
NameError: global name 'x' is not defined

mais parfois, vous voulez qu'une fonction ait une signification différente selon que la variable est définie ou non. Vous pouvez créer un argument avec une valeur par défaut de None:

>>> def test(x=None):
...   if x is None:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

Le fait que cette valeur soit la valeur spéciale None n’est pas très important dans ce cas. J'aurais pu utiliser n'importe quelle valeur par défaut:

>>> def test(x=-1):
...   if x == -1:
...     print('no x here')
...   else:
...     print(x)
... 
>>> test()
no x here
>>> test('x!')
x!

… Mais avoir None autour nous procure deux avantages:

  1. Nous n'avons pas à choisir une valeur spéciale comme -1 dont le sens n'est pas clair, et
  2. Notre fonction peut en réalité avoir besoin de traiter -1 comme une entrée normale.
>>> test(-1)
no x here

oops!

Donc, le livre est un peu trompeur principalement dans son utilisation du mot reset - attribuer None à un nom est un signal pour un programmeur qui cette valeur n'est pas utilisée ou que la fonction doit se comporter de manière par défaut, mais pour réinitialiser une valeur à son état initial non défini que vous devez utiliser le mot clé del:

>>> x = 3
>>> x
3
>>> del x
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
9
kojiro

D'autres réponses ont déjà expliqué le sens de Aucun magnifiquement. Cependant, je voudrais quand même éclaircir cette question en prenant un exemple.

Exemple:

def extendList(val, list=[]):
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

Maintenant, essayez de deviner la sortie de la liste ci-dessus. Eh bien, la réponse est étonnamment comme ci-dessous:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

mais pourquoi?

Nombreux sont ceux qui s'attendent à ce que list1 soit égal à [10] et list3 égal à ['a'] , en pensant que la liste L'argument sera réglé à sa valeur par défaut de [] chaque fois que extendList est appelée.

Cependant, ce qui se passe réellement est que la nouvelle liste par défaut est créée une seule fois lorsque la fonction est définie, et cette même liste est ensuite utilisée chaque fois que extendList est appelée sans qu'un argument de liste ne soit spécifié. Cela est dû au fait que les expressions dans les arguments par défaut sont calculées lorsque la fonction est définie et non lorsqu'elle est appelée.

list1 et list3 fonctionnent donc sur la même liste par défaut, alors que list2 fonctionne sur une liste séparée qu'il a créée (en transmettant sa propre liste vide en tant que valeur du paramètre list).


'Aucun' le sauveur: (Modifier l'exemple ci-dessus pour produire le comportement souhaité)

def extendList(val, list=None):
    if list is None:
       list = []
    list.append(val)
    return list

list1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')

print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

Avec cette mise en œuvre révisée, le résultat serait:

list1 = [10]
list2 = [123]
list3 = ['a']

Note - Exemple de crédit sur toptal.com

4
Jadav Bheda

None est un objet singleton (signifiant qu'il n'y en a qu'un), utilisé à de nombreux endroits dans le langage et la bibliothèque pour représenter l'absence d'une autre valeur.


Par exemple:
si d est un dictionnaire, d.get(k) renverra d[k] s'il existe, mais None si d n'a pas de clé k.

Lisez cette information sur un excellent blog: http://python-history.blogspot.in/

3
GrvTyagi

J'adore les exemples de code (ainsi que les fruits), alors laissez-moi vous montrer

Apple = "Apple"
print(Apple)
>>> Apple
apple = None
print(Apple)
>>> None

Aucun ne signifie rien, il n'a aucune valeur.

Aucun n'évalue à Faux.

1
Azeirah