Valeur de Py_None

Il est clair pour moi que None est utilisé pour signifier le manque de valeur. Mais comme tout doit avoir une valeur sous-jacente lors de la mise en œuvre, je cherche à voir quelle valeur a été utilisée afin de signifier l’absence de valeur, concernant CPython .

D’après la documentation , je comprends que NoneObject est un singleton. Puisque mes compétences c sont rouillées, mon meilleur Py_None , amateur, serait que la valeur de None soit le pointeur sur la mémoire allouée pour l’object Py_None ; puisqu’il s’agit d’un singleton, cela garantirait l’unicité. Ou est-il assigné à la NULL c , qui a une valeur de 0x0000 basée sur la deuxième réponse à cette question ?

En outre, la documentation indique également:

Notez que PyTypeObject for None n’est pas directement exposé dans l’API Python / C.

Ce que je devine, c’est que vous ne pouvez pas le trouver en train de chercher par source. (Ce que je fis, ne sachant où chercher, pour object.c croyant naïvement que je pouvais tout comprendre)

Mais je ne suis pas certain de mon opinion là-dessus, alors j’ai demandé.

Quelle est la valeur du niveau c pour l’object Py_None dans CPython ?

Py_None est une définition de macro dans Include/object.h . C’est un alias pour _Py_NoneStruct dans object.c qui est une variable globale statique (comme dans le stockage) de type PyObject (qui est une structure). En termes Python, il est atsortingbué à NoneType (défini juste au-dessus dans object.c et utilisé une seule fois pour _Py_NoneStruct ).

Donc, ce n’est pas NULL ou toute autre valeur spéciale en C, c’est une instance singleton PyObject de _PyNone_Type . En ce qui concerne le _PyNone_Type PyTypeObject n’étant pas exposé, je suppose qu’il fait référence au mot clé static (c.-à-d. PyTypeObject interne), ce qui signifie que le PyTypeObject n’est accessible que dans object.c et n’est utilisé qu’une fois pour la définition de PyNone .

Pour append quelque chose à cela, chaque fois que la documentation indique que PyNone n’a pas de type, cela ne doit pas être pris à la lettre. Il a un type spécial de type, NoneType , auquel vous pouvez toujours accéder via le singleton None mais vous ne pouvez pas créer de nouvelles instances ou faire quoi que ce soit avec un type normal. Il semble y avoir une limitation codée en dur pour ne pas créer de nouvelles instances, et bien que je ne trouve pas exactement où il est défini dans la source CPython, vous pouvez voir son effet lorsque vous essayez de créer une nouvelle instance:

 >>> type(None)  >>> type(None)() Traceback (most recent call last): File "", line 1, in  TypeError: cannot create 'NoneType' instances 

EDIT: Il semble que l’erreur soit typeobject.c par typeobject.c lorsque le champ tp_new est NULL. De manière surprenante, _PyNone_Type semble être défini avec un tp_new non-NULL (pointe vers le static none_new dans object.c ). Il sera peut-être défini ultérieurement sur NULL, mais il ne s’agit que d’un détail d’implémentation qui ne change pas vraiment l’étendue de votre question.

Py_None est Py_None et doit être increfed et renvoyé par une fonction en cours de fonctionnement normal si aucune autre valeur ne doit être renvoyée. NULL n’est renvoyé que si une exception doit être signalée à la machine virtuelle, avec l’object exception réel créé / atsortingbué séparément .

Py_None est la valeur de l’adresse de la définition de structure _Py_NoneStruct .

Voir le code :

 /* _Py_NoneStruct is an object of undefined type which can be used in contexts where NULL (nil) is not suitable (since NULL often means 'error'). Don't forget to apply Py_INCREF() when returning this value!!! */ PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */ #define Py_None (&_Py_NoneStruct)