python size 中的 ctypes 与 'sys.getsizeof(Var)' 方法与 'ctypes.



我有一个关于 python 变量大小的问题,我使用 Ctypes 是因为我想要一个 1 字节的数字,但是当我尝试在 python 中检查它的大小时(通过 sys.getsize )它说它是 80 字节,但当我检查 ctypes(通过 ctypes.sizeof)时,它说它只有 1 个字节, 有人可以告诉我有什么区别,为什么有 2 种不同的尺寸?是因为 Python 正在使用对象或包装器吗?当它发送到 C 时,它会查看实际大小?

import sys
import ctypes
print("size in ctypes is : ",ctypes.sizeof(ctypes.c_byte(1)))
print("size in sys is : ",sys.getsizeof(ctypes.c_byte(1)))

结果在

size in ctypes is :  1
size in sys is :  80

如果你想知道细节,你应该看看objects.h(尤其是文件顶部的注释)。您的ctypes.c_byte(1)是一个 Python 对象:

>>> import sys
>>> import ctypes
>>> isinstance(ctypes.c_byte(1), object)
True

如@Daniel所述,sys.getsizeof获取该Python对象的大小。该 Python 对象大于 C 中的相应对象,请注意object.h注释中的以下内容:

Objects are structures allocated on the heap. . . .
The actual memory allocated for an object
contains other data that can only be accessed after casting the pointer
to a pointer to a longer structure type.  This longer type must start
with the reference count and type fields; the macro PyObject_HEAD should be
used for this.

换句话说,宏PyObject_HEAD附加到每个对象的开头。这会增加 Python 对象的大小。

另一方面,ctypes.sizeof 返回 Python 对象中 C 数据类型的实际大小(使用 C 的 sizeof 运算符)。

编辑

鉴于您在对Daniel帖子的评论中提到的目标,可以在Python 3.x中通过服务器发送一个字节。 下面是如何使用Python的socket模块发送字节的示例来证明这一点。

这是服务器,您将在一个 Python 解释器中运行它:

# Server
import socket
HOST = ''                      # All available interfaces
PORT = 50007                   # Same port as client
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
print('Connected by', addr)
while True:
    data = conn.recv(1)        # receive data with bufsize 1; a larger bufsize will break this code
    if not data: break
    conn.sendall(data)
conn.close()

这是客户端,您将在另一个 python 解释器中运行它:

# Client
import socket
HOST = '127.0.0.1'             # The remote host, but here using localhost
PORT = 50007                   # The port used by both the client and server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'1')                # a bytes object
data = s.recv(1)               # Receive data from the socket with bufsize of 1
s.close()
print('Received', repr(data))  # confirm receipt

ctypes 模块用于在 Python 中创建和操作 C 数据类型。这就是为什么 ctypes.sizeof(ctypes.c_byte(1)) 返回 1。

>>> import sys
>>> help(sys.getsizeof) Help on built-in function getsizeof in module sys:
getsizeof(...)
    getsizeof(object, default) -> int
    Return the size of object in bytes.

>>> import ctypes
>>> help(ctypes.sizeof)
Help on built-in function sizeof in module _ctypes:
sizeof(...)
    sizeof(C type) -> integer
    sizeof(C instance) -> integer
    Return the size in bytes of a C instance
>>>

sys.getsizeof返回python对象的大小,这与C数据类型的大小无关。这没什么好担心的。

最新更新