Jak ustalić, czy moja powłoka Pythona działa w trybie 32-bitowym lub 64-bitowym w systemie OS X?

420

Potrzebuję sposobu, aby powiedzieć, w jakim trybie znajduje się powłoka z powłoki.

Próbowałem spojrzeć na moduł platformy , ale wydaje się, że mówi tylko o „o architekturze bitowej i formacie powiązania używanym do pliku wykonywalnego”: plik binarny jest jednak skompilowany jako 64-bitowy (działam na systemie OS X 10.6), więc wydaje się, że zawsze zgłasza 64-bitowe, mimo że używam opisanych tutaj metod , aby wymusić tryb 32-bitowy).

jkp
źródło
1
Po prostu z zainteresowania: dlaczego musisz to wiedzieć?
Lennart Regebro,
2
Mam problemy z budowaniem i ładowaniem niektórych modułów w systemie OS X 10.6. W szczególności pysco, które narzeka, że ​​pracuję w trybie 64-bitowym. Jest to również wirtualne, więc są pewne dodatkowe komplikacje, przez które muszę przejść ...
jkp 10.09.2009
2
Chciałbym wiedzieć, ponieważ kiedy używam czegoś takiego jak PyInstaller, aby utworzyć autonomiczny plik binarny do dystrybucji (aby dać użytkownikom, którzy mogą nie mieć (odpowiedniej wersji) Pythona, plik binarny, który produkuję, będzie 32/64 bitowy w zależności w Pythonie uruchamiam PyInstaller. Idealnie myślę, że chciałbym automatycznie nazwać wynikowy plik binarny / archiwalny z „32” lub „64” w nazwie pliku, zamiast konieczności ręcznej zmiany nazwy plików w zależności od tego, gdzie I wykonać polecenie „make” od
Jonathan Hartley

Odpowiedzi:

412

Jednym ze sposobów jest spojrzenie, sys.maxsizejak udokumentowano tutaj :

$ python-32 -c 'import sys;print("%x" % sys.maxsize, sys.maxsize > 2**32)'
('7fffffff', False)
$ python-64 -c 'import sys;print("%x" % sys.maxsize, sys.maxsize > 2**32)'
('7fffffffffffffff', True)

sys.maxsizezostał wprowadzony w Pythonie 2.6. Jeśli potrzebujesz testu dla starszych systemów, ten nieco bardziej skomplikowany test powinien działać na wszystkich wersjach Python 2 i 3:

$ python-32 -c 'import struct;print( 8 * struct.calcsize("P"))'
32
$ python-64 -c 'import struct;print( 8 * struct.calcsize("P"))'
64

BTW, możesz mieć ochotę do platform.architecture()tego. Niestety, jego wyniki nie zawsze są wiarygodne, szczególnie w przypadku OS X uniwersalnych plików binarnych .

$ arch -x86_64 /usr/bin/python2.6 -c 'import sys,platform; print platform.architecture()[0], sys.maxsize > 2**32'
64bit True
$ arch -i386 /usr/bin/python2.6 -c 'import sys,platform; print platform.architecture()[0], sys.maxsize > 2**32'
64bit False
Ned Deily
źródło
14
Użycie sys.maxint nie będzie działać w celu wykrycia 64-bitowego Pythona podczas pracy w systemie Windows (patrz tutaj ). Zamiast tego użyj struct.calcsize („P”) dla rozwiązania wieloplatformowego.
Luke Moore
Dzięki za sprawdzenie. Zasadniczo poprawiłem odpowiedź, aby pokazać teraz udokumentowany sys.maxsizetest dla Pythona 2.6+ i structtest używany przez platformmoduł, który działa również dla starszych wersji Pythona 2.
Ned Deily
To nie działa w IronPython, sys.maxsize to 2 ** 31 dla 32-bitowego i 64-bitowego IronPython
Meh
4
Yinon, to prawda, ale nie o to pytano. A na procesorach, na których można uruchomić, powiedzmy, 32-bitowe lub 64-bitowe pliki binarne, łuk maszyny zwykle nie jest tak istotny dla programu w języku Python; ważne jest to, jak łuk działa sam interpreter Pythona.
Ned Deily,
6
W Windows cmd musisz umieścić podwójne cudzysłowy na zewnątrz i pojedyncze cudzysłowy w środku, inaczej spowoduje to błąd składniowy. Jest tak prawdopodobnie dlatego, że system Windows uważa, że ​​spacje między pojedynczymi cudzysłowami nadal są ogranicznikami argumentów. Pomocne może być dostosowanie tej odpowiedzi, aby uwzględnić ten fakt.
Steven Bluen,
254

Podczas uruchamiania interpretera Pythona w terminalu / wierszu poleceń możesz także zobaczyć linię:

Python 2.7.2 (default, Jun 12 2011, 14:24:46) [MSC v.1500 64 bit (AMD64)] on win32

Gdzie [MSC v.1500 64 bit (AMD64)]oznacza 64-bitowy Python. Działa dla mojej konkretnej konfiguracji.

Dustin
źródło
6
więc to co? Python 64-bitowy czy 32-bitowy?
phpJs
9
@phpJs 64-bitowy z powodu[MSC v.1500 64 bit (AMD64)]
Eduarda Florinescu,
19
Niestety działa tylko dla wersji Python dla Windows. Moja instalacja OSX powracaPython 2.7.8 (v2.7.8:ee879c0ffa11, Jun 29, 2014, 21:07:35) [GCC 4.2.1 (Apple In. build 5666) (dot 3)] on darwin
aodj
6
Na Python 2.7.8 (default, Jul 25 2014, 14:04:36) [GCC 4.8.3] on cygwin
cygwinie
1
Informacje te można znaleźć w kodzie, dzwoniąc sys.version. Dostaję na przykład ('3.4.4 |Continuum Analytics, Inc.| (default, Feb 16 2016, 09:54:04) [MSC ' 'v.1600 64 bit (AMD64)]')lub2.7.5 (default, May 15 2013, 22:43:36) [MSC v.1500 32 bit (Intel)]
otterb
190

Zasadniczo wariant odpowiedzi Matthew Marshalla (z struct z biblioteki std.library):

import struct
print struct.calcsize("P") * 8
ChristopheD
źródło
1
Imho, lepsza niż wersja ctypes - działa nawet ze starszym Pythonem.
yk4ever
7
Bardzo przydatny, może być używany w jednym wierszu. $ python -c 'import struct; print struct.calcsize („P”) * 8 '
Sun Liwen
1
print (struct.calcsize („P”) * 8) jest lepszy.
HelloWorld,
2
więc skopiuj i wklej oneliner dla Python3:python -c "import struct; print(struct.calcsize('P')*8)"
Neinstein
78

Spróbuj użyć ctypów, aby uzyskać rozmiar pustego wskaźnika:

import ctypes
print ctypes.sizeof(ctypes.c_voidp)

Będzie to 4 dla wersji 32-bitowej lub 8 dla wersji 64-bitowej.

Matthew Marshall
źródło
1
To również działa, chociaż może mieć niewielką wadę niepotrzebnego importu i ładowania modułu, jeśli nie potrzebujesz inaczej ctypów: moduł sys, otoh, jest wkompilowany w interpreter.
Ned Deily,
pomóżcie mi zrozumieć: na mojej instalacji 64b python -c 'import ctypes; print ctypes.sizeof(ctypes.c_voidp)'zwraca 8 . A może tak powinno być python -c 'import ctypes; print ctypes.sizeof(ctypes.c_voidp) * 8'?
lukmdo
Funkcja zwraca rozmiar w bajtach (4 lub 8). Jeśli potrzebujesz rozmiaru w bitach (32 lub 64), musisz pomnożyć przez 8. b_is_python_64bit = (ctypes.sizeof (ctypes.c_voidp) == 8)
phobie
1
Wystarczy zadzwonićpython -c "import ctypes; print(32 if ctypes.sizeof(ctypes.c_voidp)==4 else 64, 'bit CPU')"
vitiral
54

Otwórz konsolę python:

import platform
platform.architecture()[0]

powinien wyświetlać „64-bitowy” lub „32-bitowy” w zależności od platformy.

Alternatywnie ( w przypadku plików binarnych OS X ):

import sys
sys.maxsize > 2**32 
# it should display True in case of 64bit and False in case of 32bit
abe312
źródło
moduł patform nie zawsze jest niezawodny, patrz dokumentacja docs.python.org/2/library/platform.html dotyczy to także niektórych aplikacji Windows
GM,
18

Aby uzyskać rozwiązanie nieprogramowe, poszukaj w monitorze aktywności. Podaje architekturę 64-bitowych procesów jako „Intel (64-bit)”.

Peter Hosey
źródło
1
Bardzo fajna alternatywna odpowiedź dla tych z nas korzystających z Mac OS 10.xx Dziękujemy!
mkelley33
16

W moim systemie Centos Linux wykonałem następujące czynności:

1) Uruchomiłem interpreter Pythona (używam 2.6.6)
2) Uruchomiłem następujący kod:

import platform
print(platform.architecture())

i dało mi to

(64bit, 'ELF')
rekabbnad
źródło
Czy to rozwiązanie nie zostało opisane przez OP jako niedziałające?
Antony Hatchkins
Być może, ale właśnie tego potrzebowałem; przykro mi dać +1 „złą odpowiedź”, ale bardzo tego potrzebowałem.
UnsettlingTrend
To rozwiązanie jest idealne dla Solaris 11.
Steven Wolfe
11

platform.architecture() notatki mówią:

Uwaga: W systemie Mac OS X (i być może na innych platformach) pliki wykonywalne mogą być plikami uniwersalnymi zawierającymi wiele architektur.

Aby uzyskać „64-bitowość” bieżącego interpretera, bardziej niezawodne jest zapytanie o atrybut sys.maxsize:

import sys
is_64bits = sys.maxsize > 2**32
Shannon Mann
źródło
11

Grupowanie wszystkiego ...

Biorąc pod uwagę, że:

  • Pytanie dotyczy OSX (mam starą (i popękaną) maszynę wirtualną ze starą wersją Pythona )
  • Moją główną env jest Win
  • Mam tylko wersję 32- bitową zainstalowaną na Win (i zbudowałem „okaleczoną” wersję na Lnx )

Zamierzam zilustrować przykłady na wszystkich 3 platformach, używając Python 3 i Python 2 .

  1. Sprawdź [Python 3.Docs]: sys. wartość maxsize - porównaj ją do 0x100000000( 2 ** 32): większa dla wersji 64-bitowej , mniejsza dla wersji 32-bitowej :
    • OSX 9 x64 :
      • Python 2.7.10 x64 :
        >>> import sys
        >>> "Python {0:s} on {1:s}".format(sys.version, sys.platform)
        'Python 2.7.10 (default, Oct 14 2015, 05:51:29) \n[GCC 4.8.2] on darwin'
        >>> hex(sys.maxsize), sys.maxsize > 0x100000000
        ('0x7fffffffffffffff', True)
    • Ubuntu 16 x64 :
      • Python 3.5.2 x64 :
        >>> import sys
        >>> "Python {0:s} on {1:s}".format(sys.version, sys.platform)
        'Python 3.5.2 (default, Nov 23 2017, 16:37:01) \n[GCC 5.4.0 20160609] on linux'
        >>> hex(sys.maxsize), sys.maxsize > 0x100000000
        ('0x7fffffffffffffff', True)
      • Python 3.6.4 x86 :
        >>> import sys
        >>> "Python {0:s} on {1:s}".format(sys.version, sys.platform)
        'Python 3.6.4 (default, Apr 25 2018, 23:55:56) \n[GCC 5.4.0 20160609] on linux'
        >>> hex(sys.maxsize), sys.maxsize > 0x100000000
        ('0x7fffffff', False)
    • Wygraj 10 x64 :
      • Python 3.5.4 x64 :
        >>> import sys
        >>> "Python {0:s} on {1:s}".format(sys.version, sys.platform)
        'Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32'
        >>> hex(sys.maxsize), sys.maxsize > 0x100000000
        ('0x7fffffffffffffff', True)
      • Python 3.6.2 x86 :
        >>> import sys
        >>> "Python {0:s} on {1:s}".format(sys.version, sys.platform)
        'Python 3.6.2 (v3.6.2:5fd33b5, Jul  8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32'
        >>> hex(sys.maxsize), sys.maxsize > 0x100000000
        ('0x7fffffff', False)


  1. Użyj [Python 3.Docs]: struct. calcsize ( format ), aby określić rozmiar obiektu utworzony przez format (wskaźnik). Innymi słowy, określa rozmiar wskaźnika ( sizeof(void*)):
    • OSX 9 x64 :
      • Python 2.7.10 x64 :
        >>> import struct
        >>> struct.calcsize("P") * 8
        64
    • Ubuntu 16 x64 :
      • Python 3.5.2 x64 :
        >>> import struct
        >>> struct.calcsize("P") * 8
        64
      • Python 3.6.4 x86 :
        >>> import struct
        >>> struct.calcsize("P") * 8
        32
    • Wygraj 10 x64 :
      • Python 3.5.4 x64 :
        >>> import struct
        >>> struct.calcsize("P") * 8
        64
      • Python 3.6.2 x86 :
        >>> import struct
        >>> struct.calcsize("P") * 8
        32


  1. Użyj [Python 3.Docs]: ctypes - zagraniczna biblioteka funkcji dla Pythona . Sprowadza się również do określenia wielkości wskaźnika ( sizeof(void*)). Uwaga: ctypes używa # 2. (niekoniecznie do tego zadania) za pośrednictwem „$ {PYTHON_SRC_DIR} / Lib / ctypes / __ init__.py” (wokół linii nr 15 ):
    • OSX 9 x64 :
      • Python 2.7.10 x64 :
        >>> import ctypes
        >>> ctypes.sizeof(ctypes.c_void_p) * 8
        64
    • Ubuntu 16 x64 :
      • Python 3.5.2 x64 :
        >>> import ctypes
        >>> ctypes.sizeof(ctypes.c_void_p) * 8
        64
      • Python 3.6.4 x86 :
        >>> import ctypes
        >>> ctypes.sizeof(ctypes.c_void_p) * 8
        32
    • Wygraj 10 x64 :
      • Python 3.5.4 x64 :
        >>> import ctypes
        >>> ctypes.sizeof(ctypes.c_void_p) * 8
        64
      • Python 3.6.2 x86 :
        >>> import ctypes
        >>> ctypes.sizeof(ctypes.c_void_p) * 8
        32


  1. [Python 3.Docs]: platforma. architektura ( executable = sys.executable, bits = '', linkage = '' ) !!! NIE jest wiarygodny w OSX !!! ze względu na format wykonywalny Multi Arch (lub .dylib ) (w niektórych przypadkach używa # 2. ):
    • OSX 9 x64 :
      • Python 2.7.10 x64 :
        >>> import platform
        >>> platform.architecture()
        ('64bit', '')
    • Ubuntu 16 x64 :
      • Python 3.5.2 x64 :
        >>> import platform
        >>> platform.architecture()
        ('64bit', 'ELF')
      • Python 3.6.4 x86 :
        >>> import platform
        >>> platform.architecture()
        ('32bit', 'ELF')
    • Wygraj 10 x64 :
      • Python 3.5.4 x64 :
        >>> import platform
        >>> platform.architecture()
        ('64bit', 'WindowsPE')
      • Python 3.6.2 x86 :
        >>> import platform
        >>> platform.architecture()
        ('32bit', 'WindowsPE')


  1. Lame obejście ( gainarie ) - wywołaj zewnętrzne polecenie ( [man7]: FILE (1) ) przez [Python 3.Docs]: os. system ( polecenie ) . Ograniczenia # 4. zastosuj (czasami może nawet nie działać):
    • OSX 9 x64 :
      • Python 2.7.10 x64 :
        >>> import os
        >>> os.system("file {0:s}".format(os.path.realpath(sys.executable)))
        /opt/OPSWbuildtools/2.0.6/bin/python2.7.global: Mach-O 64-bit executable x86_64
    • Ubuntu 16 x64 :
      • Python 3.5.2 x64 :
        >>> import os
        >>> os.system("file {0:s}".format(os.path.realpath(sys.executable)))
        /usr/bin/python3.5: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=59a8ef36ca241df24686952480966d7bc0d7c6ea, stripped
      • Python 3.6.4 x86 :
        >>> import os
        >>> os.system("file {0:s}".format(os.path.realpath(sys.executable)))
        /home/cfati/Work/Dev/Python-3.6.4/python: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=5c3d4eeadbd13cd91445d08f90722767b0747de2, not stripped
    • Wygraj 10 x64 :
      • Plik narzędzie nie jest obecny, istnieją inne 3 rd strona narzędzia, które mogą być stosowane, ale nie będę nalegać na nich


Wygraj określone:

  1. Sprawdź zmienne środowiskowe (np. % PROCESSOR_ARCHITECTURE% (lub inne)) za pomocą [Python 3.Docs]: os. rodowisko :
    • Wygraj 10 x64 :
      • Python 3.5.4 x64 :
        >>> import os
        >>> os.environ["PROCESSOR_ARCHITECTURE"]
        'AMD64'
      • Python 3.6.2 x86 :
        >>> import os
        >>> os.environ["PROCESSOR_ARCHITECTURE"]
        'x86'


  1. [Python 3.Docs]: sys. wersja ( wyświetlana również w 1 pierwszym wierszu podczas uruchamiania tłumacza)
    • Sprawdź nr 1.
CristiFati
źródło
7

struct.calcsize("P")zwraca rozmiar bajtów wymaganych do przechowywania pojedynczego wskaźnika. W systemie 32-bitowym zwróci 4 bajty. W systemie 64-bitowym zwróci 8 bajtów.

Tak więc następujące informacje będą zwracane, 32jeśli używasz 32-bitowego Pythona i 64jeśli używasz 64-bitowego Pythona:

Python 2

import struct;print struct.calcsize("P") * 8

Python 3

import struct;print(struct.calcsize("P") * 8)
kimbaudi
źródło
5

Wykonaj a python -VVw wierszu poleceń. Powinien zwrócić wersję.

użytkownik12549815
źródło
Nie pokazuje to, jak to zrobić w Pythonie.
ParkerD
Wydaje się, że nie zapewnia to informacji potrzebnych do udzielenia odpowiedzi na pytanie
Dmitrij Zaitsev
4
C:\Users\xyz>python

Python 2.7.6 (default, Nov XY ..., 19:24:24) **[MSC v.1500 64 bit (AMD64)] on win
32**
Type "help", "copyright", "credits" or "license" for more information.
>>>

po uderzeniu w python w cmd

Nikhil
źródło
4
import sys
print(sys.version)

3.5.1 (v3.5.1: 37a07cee5969, 6 grudnia 2015, 01:54:25) [MSC v.1900 64 bit (AMD64) ]

betontalpfa
źródło
Nie dotyczy OSX .
CristiFati,
3

Na podstawie odpowiedzi abe32

import sys
n_bits = 32 << bool(sys.maxsize >> 32)

n_bity będą miały 32 lub 64 bity.

Rishabh Bhatnagar
źródło
2

Dla wersji 32-bitowej zwraca 32, a dla wersji 64-bitowej zwraca 64

import struct
print(struct.calcsize("P") * 8)
bajt legion
źródło
1

Architektura platformy nie jest niezawodnym sposobem. Zamiast nas:

$ arch -i386 /usr/local/bin/python2.7
Python 2.7.9 (v2.7.9:648dcafa7e5f, Dec 10 2014, 10:10:46)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform, sys
>>> platform.architecture(), sys.maxsize
(('64bit', ''), 2147483647)
>>> ^D
$ arch -x86_64 /usr/local/bin/python2.7
Python 2.7.9 (v2.7.9:648dcafa7e5f, Dec 10 2014, 10:10:46)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import platform, sys
>>> platform.architecture(), sys.maxsize
(('64bit', ''), 9223372036854775807)
Prakhar Agarwal
źródło
0

platform.architecture() jest problematyczne (i drogie).

Dogodnie przetestuj sys.maxsize > 2**32od wersji Py2.6.

Jest to wiarygodny test dla rzeczywistej (domyślnie) wielkości wskaźnika i zgodne przynajmniej od Py2.3: struct.calcsize('P') == 8. Również:ctypes.sizeof(ctypes.c_void_p) == 8 .

Uwagi: Mogą być kompilacje z opcją gcc -mx32lub podobną, które są aplikacjami architektury 64-bitowej, ale domyślnie używają wskaźników 32-bitowych (oszczędzanie pamięci i prędkości). 'sys.maxsize = ssize_t' nie może ściśle reprezentować rozmiaru wskaźnika C (zwykle 2**31 - 1tak jest). I były / są systemy, które mają różne rozmiary wskaźników dla kodu i danych i należy wyjaśnić, jaki dokładnie jest cel rozpoznania „trybu 32-bitowego lub 64-bitowego”?

kxr
źródło