Seguir o caminho direto dessa forma não parece funcionar no Python 3.
import ctypes
class cA(ctypes.Structure):
_fields_ = [("a", ctypes.c_ubyte)]
def __init__(self):
super().__init__()
self.c = 3
z = cA.from_buffer_copy(b'0')
print (z)
print (z.c)
print (dir(z))
Traceback (most recent call last):
File "polymorph.py", line 12, in <module>
print (z.c)
AttributeError: 'cA' object has no attribute 'c'
Portanto, ctypes.Structure
o método de classe de fábrica from_buffer_copy()
não parece usar o construtor padrão __init__
. Isso está correto e foi pretendido por ctypes.Structure
?
Ok, mesmo que não esteja tentando contornar isso, sobrescrever o método da classe from_buffer_copy
levanta outro problema. Como adicionar à classe cA:
@classmethod
def from_buffer_copy(cls,buffer, offset=0):
#obj = super().from_buffer_copy(b'2',offset)
obj = cls.from_buffer_copy(b'2',offset)
obj.__init__()
return obj
Traceback (most recent call last):
File "polymorph.py", line 17, in <module>
z = cA.from_buffer_copy(b'0')
File "polymorph.py", line 13, in from_buffer_copy
obj = cls.from_buffer_copy(b'2',offset)
File "polymorph.py", line 13, in from_buffer_copy
obj = cls.from_buffer_copy(b'2',offset)
File "polymorph.py", line 13, in from_buffer_copy
obj = cls.from_buffer_copy(b'2',offset)
[Previous line repeated 996 more times]
RecursionError: maximum recursion depth exceeded
Isso cria um RecursionError
, porque o mesmo método de classe é chamado repetidamente, mas Structure.from_buffer_copy
também não pode ser chamado porque não possui _fields_
.
Usar o super()
método acima também não ajuda. Isso levanta um AttributeError
:
Traceback (most recent call last):
File "polymorph.py", line 17, in <module>
z = cA.from_buffer_copy(b'0')
File "polymorph.py", line 12, in from_buffer_copy
obj = super().from_buffer_copy(b'2',offset)
AttributeError: 'super' object has no attribute 'from_buffer_copy'
Isso parece ser semelhante a Usar super com um método de classe. Parece algo especial do Python 3 também.
Então ctypes.Structure
parece ser um tipo realmente especial de classe. Fazer o mesmo com uma classe Python comum não é problema. Tipo:
import ctypes
class A:
def __init__(self):
self.a = "Tex"
@classmethod
def factory(cls):
return cls()
class B(A):
def __init__(self):
super().__init__()
self.b = "bTex"
z = B.factory()
print (z)
print (z.b)
print (dir(z))
Então... Existe uma maneira de misturar ctypes.Structure
com campos de classe regulares do Python ou é melhor simplesmente não fazer isso e incorporar ctypes.Structure
dentro de outras classes regulares para contornar isso?