我有一个关于 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数据类型的大小无关。这没什么好担心的。