简体   繁体   中英

Class member or instance attribute?

I've been using Structure in ctypes recently, but i got a strange question.

This is my Python3 code:

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

The question is: Is test a class member of AcknowledgeHeader or an instance attribute of ack_header?

I tried to find the answer.

If test is an instance attribute of ack_header, then why does ack_header.__dict__ print a empty 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

If test is a class member of AcknowledgeHeader, then why is type(ack_header.test) not equal to 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 is a data descriptor object on the AcknowledgeHeader class. Accessing it on the ack_header instance causes code to run that translates between C conventions and Python types.

Because it is a data descriptor, all interaction with the attribute is captured, including deletion and assignment. If you were to set a 'test' key in the ack_header.__dict__ attribute dictionary it'd simply be ignored.

Instead, ack_header.test will always invoke AcknowledgeHeader.test.__get__(ack_header, AcknowledgeHeader) , while assignment to ack_header.test will trigger AcknowledgeHeader.test.__set__(ack_header, <new value>) .

In this case, only getting and setting is implemented, there is no _ctypes.CField.__delete__() method , only __get__ and __set__ , so del ack_header.test will throw an exception.

See the descriptor HOWTO for more details on how descriptors work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM