2017-05-01 1 views
0

Le code suivant fait partie d'un solveur d'équations linéaires. Il est écrit pour python 3. Avant d'exécuter le programme, il vérifie le nombre magique de imp.get_magic() par rapport à une valeur attendue.Python 3.5.0 donne un nombre magique inattendu

J'ai Python 3.5.0 installé sur un système exécutant Fedora 25. Le problème est que, sur mon système, j'ai une valeur différente pour le nombre magique.

attendu est: b'\xf8\x0c\r\n'

Au lieu de cela, je reçois: b'\x16\r\r\n'

Voici le code

def _get_module(): 
    del globals()['_get_module'] 
    import imp 
    import base64 
    import marshal 

    magic = imp.get_magic() 
    if magic == b'\xf8\x0c\r\n': # Python 3.5 
     pycData = <certain value> 
    pycData = base64.decodebytes(pycData) 

Depuis que je reçois une valeur différente pour le nombre magique, je ne peux pas courir ce programme.

Ce code provient des ressources du livre Coding the Matrix. Il peut être trouvé sous la section "The Matrix" et le fichier est nommé solver.py (téléchargements de fichiers directement).

Existe-t-il un moyen d'obtenir ce roulement?

+0

Eh bien, ne pouvez-vous pas juste faire le conditionnel pour être vrai? Qu'est-ce que ce code est censé faire de toute façon? – user1685095

+1

Oh boy, donc le script contient un bytecode intégré au nombre magique d'une version Python et le charge juste. Qu'est ce qui pourrait aller mal? –

+0

@MartijnPieters A-t-il quelque chose à voir avec le système d'exploitation? – dpk

Répondre

2

Le nombre magique est mis à jour chaque fois que le bytecode change, pour s'assurer que vous n'essayez pas de charger le bytecode incompatible dans un ancien interpréteur.

Le marqueur magique spécifique qui code recherche est celui de Python 3.5a0, voir le changelog for markers:

>>> int.from_bytes(b'\xf8\x0c', 'little') 
3320 

pendant que vous essayez de charger ce avec 3.5b2 ou version ultérieure (mais avant 3.5.2) :

>>> int.from_bytes(b'\x16\r', 'little') 
3350 

Vous pouvez simplement charger cette version dans 3.5.2; il suffit de désactiver les tests de marqueur magique ou de retravailler le code pour extraire le marqueur (comme je l'ai fait ci-dessus, les deux premiers octets) et correspondre à la valeur maximale possible.

Je ne sais pas pourquoi ce code ne distribue pas seulement un fichier .pyc en premier lieu. Le bytecode Python 3.3 se charge très bien dans Python 3.6. J'ai chargé toutes les versions dans Python 3.6, couru dis.dis() sur chacun et trouvé aucune différence réelle dans le bytecode.

+0

J'utilise fedora 25, qui est venu avec python 3.5.2, je ne l'ai pas désinstallé (3.5.2) parce que les réponses à cette question, http://stackoverflow.com/questions/13661487/uninstall-old- version-python-fedora, avertit que cela peut casser le système. J'ai donc installé 3.5.0 sur la version existante, le shell IDLE et le terminal python montrent la version 3.5.0. Donc vous avez raison à propos de la version 3.5.2, c'était ce que j'avais sur mon système. – dpk

+0

Les anciennes versions de bytecode se chargent * très bien *. Ils ne vont pas casser votre système. –

+0

L'autre post avertit de remplacer le système Python 2 par Python 3, ce qui serait en effet un problème, mais cela est facilement évité en installant les deux.Ces problèmes ne s'appliquent pas ici. –