Class 成员或实例属性?
Class member or instance attribute?
最近一直在使用ctypes中的Structure,但是我遇到了一个奇怪的问题。
这是我的 Python3 代码:
from ctypes import *
class AcknowledgeHeader(Structure):
_fields_ = [
('test', c_uint8),
]
ack_header = AcknowledgeHeader()
问题是:test
是AcknowledgeHeader的class成员还是ack_header的实例属性?
我试图找到答案。
如果test
是ack_header的一个实例属性,那为什么ack_header.__dict__
会打印一个空的dict?
if __name__ == '__main__':
ack_header = AcknowledgeHeader()
print(ack_header.__dict__)
C:\Users\Administrator\PycharmProjects\gige-lib\venv\Scripts\python.exe
C:/Users/Administrator/PycharmProjects/gige-lib/channel/common.py
{}
Process finished with exit code 0
如果test
是AcknowledgeHeader的class成员,那么为什么type(ack_header.test)
不等于type(AcknowledgeHeader.test)
?
if __name__ == '__main__':
ack_header = AcknowledgeHeader()
print(type(ack_header.test))
print(type(AcknowledgeHeader.test))
C:\Users\Administrator\PycharmProjects\gige-lib\venv\Scripts\python.exe C:/Users/Administrator/PycharmProjects/gige-lib/channel/common.py
<class 'int'>
<class '_ctypes.CField'>
Process finished with exit code 0
test
是 AcknowledgeHeader
class 上的 数据描述符对象 。在 ack_header
实例上访问它会导致代码 运行 在 C 约定和 Python 类型之间进行转换。
因为它是一个数据描述符,所有与属性的交互都会被捕获,包括删除和赋值。如果您要在 ack_header.__dict__
属性字典中设置 'test'
键,它会被忽略。
相反,ack_header.test
将始终调用 AcknowledgeHeader.test.__get__(ack_header, AcknowledgeHeader)
,而分配给 ack_header.test
将触发 AcknowledgeHeader.test.__set__(ack_header, <new value>)
。
本例中只实现了获取和设置,没有_ctypes.CField.__delete__()
method,只有__get__
和__set__
,所以del ack_header.test
会抛出异常。
有关描述符如何工作的更多详细信息,请参阅 descriptor HOWTO。
最近一直在使用ctypes中的Structure,但是我遇到了一个奇怪的问题。
这是我的 Python3 代码:
from ctypes import *
class AcknowledgeHeader(Structure):
_fields_ = [
('test', c_uint8),
]
ack_header = AcknowledgeHeader()
问题是:test
是AcknowledgeHeader的class成员还是ack_header的实例属性?
我试图找到答案。
如果test
是ack_header的一个实例属性,那为什么ack_header.__dict__
会打印一个空的dict?
if __name__ == '__main__':
ack_header = AcknowledgeHeader()
print(ack_header.__dict__)
C:\Users\Administrator\PycharmProjects\gige-lib\venv\Scripts\python.exe
C:/Users/Administrator/PycharmProjects/gige-lib/channel/common.py
{}
Process finished with exit code 0
如果test
是AcknowledgeHeader的class成员,那么为什么type(ack_header.test)
不等于type(AcknowledgeHeader.test)
?
if __name__ == '__main__':
ack_header = AcknowledgeHeader()
print(type(ack_header.test))
print(type(AcknowledgeHeader.test))
C:\Users\Administrator\PycharmProjects\gige-lib\venv\Scripts\python.exe C:/Users/Administrator/PycharmProjects/gige-lib/channel/common.py
<class 'int'>
<class '_ctypes.CField'>
Process finished with exit code 0
test
是 AcknowledgeHeader
class 上的 数据描述符对象 。在 ack_header
实例上访问它会导致代码 运行 在 C 约定和 Python 类型之间进行转换。
因为它是一个数据描述符,所有与属性的交互都会被捕获,包括删除和赋值。如果您要在 ack_header.__dict__
属性字典中设置 'test'
键,它会被忽略。
相反,ack_header.test
将始终调用 AcknowledgeHeader.test.__get__(ack_header, AcknowledgeHeader)
,而分配给 ack_header.test
将触发 AcknowledgeHeader.test.__set__(ack_header, <new value>)
。
本例中只实现了获取和设置,没有_ctypes.CField.__delete__()
method,只有__get__
和__set__
,所以del ack_header.test
会抛出异常。
有关描述符如何工作的更多详细信息,请参阅 descriptor HOWTO。