86 votes

Est-ce que 1 == 2 est vrai ?

Les ints en Python sont objets qui encapsulent la valeur numérique réelle. Par curiosité / pour le fun, je me demandais : pouvons-nous modifier cette valeur, par exemple en définissant la valeur de l'objet 1 à 2 ? Ainsi, 1 == 2 devient True ?

126voto

Kelly Bundy Points 5639

Oui nous le pouvons. Mais ne faites pas ça chez vous. Sérieusement, l'objet 1 est utilisé à de nombreux endroits et je n'ai aucune idée de ce que cela pourrait casser et de ce que cela pourrait faire à votre ordinateur. Je rejette toute responsabilité. Mais j'ai trouvé cela intéressant d'apprendre sur ces choses.

La fonction id nous donne l'adresse mémoire et le module ctypes nous permet de manipuler la mémoire :

import ctypes

ctypes.memmove(id(1) + 24, id(2) + 24, 4)

print(1 == 2)

x = 40
print(x + 1)

Résultat :

Vrai
42

Essayez en ligne !. Je l'ai essayé là-bas parce que de tels sites doivent de toute façon être protégés contre nos piratages.


Plus d'explication / analyse :

Le memmove a copié la valeur de l'objet 2 dans l'objet 1. Leur taille est de 28 octets chacun, mais j'ai sauté les 24 premiers octets car il s'agit du compteur de référence de l'objet, de l'adresse du type et de la taille de la valeur, comme nous pouvons le voir/vérifier également :

import ctypes, struct, sys

x = 1
data = ctypes.string_at(id(x), 28)
ref_count, type_address, number_of_digits, lowest_digit = \
    struct.unpack('qqqi', data)

print('compteur de référence : ', ref_count, sys.getrefcount(x))
print('adresse du type : ', type_address, id(type(x)))
print('nombre de chiffres : ', number_of_digits, -(-x.bit_length() // 30))
print('chiffre le plus bas : ', lowest_digit, x % 2**30)

Résultat (ints sous forme de :</p> <pre><code>compteur de référence : 135 138 adresse du type : 140259718753696 140259718753696 nombre de chiffres : 1 1 chiffre le plus bas : 1 1 </code></pre> <p>Le compteur de référence est augmenté par l'appel de <code>getrefcount</code>, je ne sais pas pourquoi de 3. Quoi qu'il en soit, environ 134 choses autres que nous référencent l'objet <code>1</code>, et nous pourrions potentiellement tous les perturber, donc... vraiment ne faites pas ça chez vous.</p> <p>Les ) chiffres en base 230. Par exemple, x = 2 ** 3000 a 101 de ces chiffres. Résultat pour x = 123 ** 456 pour un meilleur test :

compteur de référence : 1 2
adresse du type : 140078560107936 140078560107936
nombre de chiffres : 106 106
chiffre le plus bas : 970169057 970169057

28voto

Trengot Points 794

En Python2, il y a une approche beaucoup plus simple - True et False n'étaient pas protégés, donc vous pouviez leur assigner des valeurs.

>>> True = False
>>> (1 == 2) is True
True

3voto

dan04 Points 33306

Si vous préférez ne pas vous occuper des contenus réels des objets int ou bool mis en cache, vous pouvez simuler un 1 == 2 de cette manière :

>>> import builtins
>>> import sys
>>>
>>> def displayhook(value):
...     if value is False:
...         value = True
...     elif value is 1:
...         value = 2
...     text = repr(value)
...     sys.stdout.write(text)
...     sys.stdout.write('\n')
...     builtins._ = value
...
:4: SyntaxWarning: "is" with a literal. Did you mean "=="?
>>> sys.displayhook = displayhook
>>> 1
2
>>> 1 == 2
True

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X