How do I determine if my python shell is executing in 32bit or 64bit?

前端 未结 18 1141
北恋
北恋 2020-11-22 04:25

I need a way to tell what mode the shell is in from within the shell.

While I\'m primarily an OS X user, I\'d be interested in knowing about other platforms as well.<

相关标签:
18条回答
  • 2020-11-22 04:31

    Grouping everything...

    Considering that:

    • The question is asked for OSX (I have an old (and cracked) VM with an ancient Python version)
    • My main env is Win
    • I only have the 32bit version installed on Win (and I built a "crippled" one on Lnx)

    I'm going to exemplify on all 3 platforms, using Python 3 and Python 2.

    1. Check [Python 3.Docs]: sys.maxsize value - compare it to 0x100000000 (2 ** 32): greater for 64bit, smaller for 32bit:
      • 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)
          
      • Win 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. Use [Python 3.Docs]: struct.calcsize(format) to determine the object size produced by the (pointer) format. In other words, determines the pointer size (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
          
      • Win 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. Use [Python 3.Docs]: ctypes - A foreign function library for Python. It also boils down to determining the size of a pointer (sizeof(void*)). As a note, ctypes uses #2. (not necessarily for this task) via "${PYTHON_SRC_DIR}/Lib/ctypes/__init__.py" (around line #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
          
      • Win 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]: platform.architecture(executable=sys.executable, bits='', linkage='') !!! NOT reliable on OSX !!! due to multi arch executable (or .dylib) format (in some cases, uses #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')
          
      • Win 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 workaround (gainarie) - invoke an external command ([man7]: FILE(1)) via [Python 3.Docs]: os.system(command). The limitations of #4. apply (sometimes it might not even work):
      • 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
          
      • Win 10 x64:
        • file utility is not present, there are other 3rd Party tools that can be used, but I'm not going to insist on them


    Win specific:

    1. Check env vars (e.g. %PROCESSOR_ARCHITECTURE% (or others)) via [Python 3.Docs]: os.environ:
      • Win 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.version (also displayed in the 1st line when starting the interpreter)
      • Check #1.
    0 讨论(0)
  • 2020-11-22 04:33

    When starting the Python interpreter in the terminal/command line you may also see a line like:

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

    Where [MSC v.1500 64 bit (AMD64)] means 64-bit Python. Works for my particular setup.

    0 讨论(0)
  • 2020-11-22 04:35
    import sys
    print(sys.version)
    

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

    0 讨论(0)
  • 2020-11-22 04:37

    Based On abe32's answer,

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

    n_bits will have 32 or 64 bits.

    0 讨论(0)
  • 2020-11-22 04:37

    platform.architecture() is problematic (and expensive).

    Conveniently test for sys.maxsize > 2**32 since Py2.6 .

    This is a reliable test for the actual (default) pointer size and compatible at least since Py2.3: struct.calcsize('P') == 8. Also: ctypes.sizeof(ctypes.c_void_p) == 8.

    Notes: There can be builds with gcc option -mx32 or so, which are 64bit architecture applications, but use 32bit pointers as default (saving memory and speed). 'sys.maxsize = ssize_t' may not strictly represent the C pointer size (its usually 2**31 - 1 anyway). And there were/are systems which have different pointer sizes for code and data and it needs to be clarified what exactly is the purpose of discerning "32bit or 64bit mode?"

    0 讨论(0)
  • 2020-11-22 04:38

    Try using ctypes to get the size of a void pointer:

    import ctypes
    print ctypes.sizeof(ctypes.c_voidp)
    

    It'll be 4 for 32 bit or 8 for 64 bit.

    0 讨论(0)
提交回复
热议问题