Czy istnieje sposób, aby wiedzieć, przez które Python wersji.plik pyc został skompilowany?

Czy Jest jakiś sposób, aby wiedzieć, przez którą wersję Pythona został skompilowany plik .pyc?

Author: Stefan van den Akker, 2011-10-18

5 answers

Możesz uzyskać magiczną liczbę Pythona w następujący sposób:

$ python -V
Python 2.6.2
# python
>>> import imp
>>> imp.get_magic().encode('hex')
'd1f20d0a'

Aby uzyskać magiczny numer dla pliku pyc, możesz wykonać następujące czynności:

>>> f = open('test25.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'b3f20d0a'
>>> f = open('test26.pyc')
>>> magic = f.read(4)
>>> magic.encode('hex')
'd1f20d0a'

Porównując magiczne liczby poznasz wersję Pythona, która wygenerowała plik pyc.

 48
Author: Igor Popov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-18 13:11:52

Pierwsze dwa bajty pliku .pyc są liczbą magiczną, która informuje o wersji bajtowych kodów. Słowo jest przechowywane w formacie little-endian, a znane wartości to:

# Python/import.c - merged by aix from Python 2.7.2 and Python 3.2.2
# EDIT: added little endian hex values for comparison first two bytes of Igor Popov's method -jimbob

       Python 1.5:   20121  0x994e
       Python 1.5.1: 20121  0x994e
       Python 1.5.2: 20121  0x994e
       Python 1.6:   50428  0x4cc4
       Python 2.0:   50823  0x87c6
       Python 2.0.1: 50823  0x87c6
       Python 2.1:   60202  0x2aeb
       Python 2.1.1: 60202  0x2aeb
       Python 2.1.2: 60202  0x2aeb
       Python 2.2:   60717  0x2ded
       Python 2.3a0: 62011  0x3bf2
       Python 2.3a0: 62021  0x45f2
       Python 2.3a0: 62011  0x3bf2 (!)
       Python 2.4a0: 62041  0x59f2
       Python 2.4a3: 62051  0x63f2
       Python 2.4b1: 62061  0x6df2
       Python 2.5a0: 62071  0x77f2
       Python 2.5a0: 62081  0x81f2 (ast-branch)
       Python 2.5a0: 62091  0x8bf2 (with)
       Python 2.5a0: 62092  0x8cf2 (changed WITH_CLEANUP opcode)
       Python 2.5b3: 62101  0x95f2 (fix wrong code: for x, in ...)
       Python 2.5b3: 62111  0x9ff2 (fix wrong code: x += yield)
       Python 2.5c1: 62121  0xa9f2 (fix wrong lnotab with for loops and
                            storing constants that should have been removed)
       Python 2.5c2: 62131  0xb3f2 (fix wrong code: for x, in ... in listcomp/genexp)
       Python 2.6a0: 62151  0xc7f2 (peephole optimizations and STORE_MAP opcode)
       Python 2.6a1: 62161  0xd1f2 (WITH_CLEANUP optimization)
       Python 2.7a0: 62171  0xdbf2 (optimize list comprehensions/change LIST_APPEND)
       Python 2.7a0: 62181  0xe5f2 (optimize conditional branches:
                introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
       Python 2.7a0  62191  0xeff2 (introduce SETUP_WITH)
       Python 2.7a0  62201  0xf9f2 (introduce BUILD_SET)
       Python 2.7a0  62211  0x03f3 (introduce MAP_ADD and SET_ADD)

       Python 3000:   3000  0xb80b
                      3010  0xc20b (removed UNARY_CONVERT)
                      3020  0xcc0b (added BUILD_SET)
                      3030  0xd60b (added keyword-only parameters)
                      3040  0xe00b (added signature annotations)
                      3050  0xea0b (print becomes a function)
                      3060  0xf40b (PEP 3115 metaclass syntax)
                      3061  0xf50b (string literals become unicode)
                      3071  0xff0b (PEP 3109 raise changes)
                      3081  0x090c (PEP 3137 make __file__ and __name__ unicode)
                      3091  0x130c (kill str8 interning)
                      3101  0x1d0c (merge from 2.6a0, see 62151)
                      3103  0x1f0c (__file__ points to source file)
       Python 3.0a4:  3111  0x270c (WITH_CLEANUP optimization).
       Python 3.0a5:  3131  0x3b0c (lexical exception stacking, including POP_EXCEPT)
       Python 3.1a0:  3141  0x450c (optimize list, set and dict comprehensions:
               change LIST_APPEND and SET_ADD, add MAP_ADD)
       Python 3.1a0:  3151  0x4f0c (optimize conditional branches:
           introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
       Python 3.2a0:  3160  0x580c (add SETUP_WITH)
                     tag: cpython-32
       Python 3.2a1:  3170  0x620c (add DUP_TOP_TWO, remove DUP_TOPX and ROT_FOUR)
                     tag: cpython-32
       Python 3.2a2   3180  0x6c0c (add DELETE_DEREF)
 48
Author: NPE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-18 16:37:16

Lub, jeśli posiadasz system GNU / Linux, możesz użyć polecenia "file"w Terminalu:

$ file code.pyc
> code.pyc: python 3.5.2 byte-compiled
 7
Author: Infected,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-26 23:07:03

Spójrz na mój skrypt w Pythonie, który wykrywa i zwraca wersję Pythona, za pomocą której plik (*.pyc lub*.pyo) został skompilowany.

Wykrywa wersje Pythona od Pythona 1.5 do ostatniej kompilacji Pythona 3.

 2
Author: Delimitry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-03 10:42:32

Oficjalne repozytorium Pythona github nie wydaje się już utrzymywać listy w imporcie.c.

Szukając bardziej aktualnej listy, niż mogłem znaleźć gdzie indziej, napotkałem coś, co wydaje się być aktualną listą od Google od maja 2017.

Https://github.com/google/pytype/blob/master/pytype/pyc/magic.py

 1
Author: Ubuntourist,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-25 22:04:03