使用sys.getsizeof(Var)方法的python大小的ctypes与`ctypes.sizeof(Var)`

New*_*bie 5 python size byte ctypes sys

我有一个关于python中可变大小的问题,我使用Ctypes是因为我想要一个1字节的数字,但是当我尝试通过python检查它的大小时(via sys.getsize)它说是80字节,但是当我用ctypes(via 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)))
Run Code Online (Sandbox Code Playgroud)

结果是

size in ctypes is :  1
size in sys is :  80
Run Code Online (Sandbox Code Playgroud)

πόδ*_*κύς 4

如果您想了解详细信息,您应该看一下objects.h(尤其是文件顶部的注释)。你的ctypes.c_byte(1)是一个Python对象:

>>> import sys
>>> import ctypes
>>> isinstance(ctypes.c_byte(1), object)
True
Run Code Online (Sandbox Code Playgroud)

正如 @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.
Run Code Online (Sandbox Code Playgroud)

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

ctypes.sizeof另一方面,返回CPython 对象内数据类型的实际大小(使用 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()
Run Code Online (Sandbox Code Playgroud)

这是客户端,您将在另一个 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
Run Code Online (Sandbox Code Playgroud)