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 None
est 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.
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
.
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.
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.
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.
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
.
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
.
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
.
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
None
est une instance de NoneType
None
ne peut pas avoir de nouveaux attributsNone
ne peuvent pas être modifiés.NoneType
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
:)
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
dont le sens n'est pas clair, et-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
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
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/
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.