类成员或实例属性?

问题描述 投票:3回答:1

我最近一直在使用ctypes中的Structure,但我有一个奇怪的问题。

这是我的Python3代码:

from ctypes import *
class AcknowledgeHeader(Structure):
    _fields_ = [
        ('test', c_uint8),
    ]
ack_header = AcknowledgeHeader()

问题是:test是AcknowledgeHeader的类成员还是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的一个成员,那么为什么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
python python-3.x python-2.7 ctypes
1个回答
4
投票

testAcknowledgeHeader类的数据描述符对象。在ack_header实例上访问它会导致代码在C约定和Python类型之间转换。

因为它是数据描述符,所以捕获与属性的所有交互,包括删除和赋值。如果你要在'test'属性字典中设置一个ack_header.__dict__密钥,它就会被忽略。

相反,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

© www.soinside.com 2019 - 2024. All rights reserved.