J'ai essayé d'ajouter des diagnostics à une structure ctypes imbriquée, mais je n'ai pas réussi à le faire et j'aimerais en connaître la raison. Un exemple bare-bones pour ce qui fonctionne comme prévu:Impossible d'ajouter un attribut à une structure imbriquée dans ctypes
import ctypes
class FirstStruct(ctypes.Structure):
_fields_ = [('ch', ctypes.c_ubyte)]
f = FirstStruct()
print type(f)
print hasattr(f, 'helper')
f.helper = 'xyz'
print hasattr(f, 'helper')
Ces lignes imprimer ce que je pensais:
<class '__main__.FirstStruct'>
False
True
Mais quand je l'utiliser dans une autre structure, il échoue:
class SecondStruct(ctypes.Structure):
_fields_ = [('first', FirstStruct)]
s = SecondStruct()
print type(s.first)
print hasattr(s.first, 'helper')
s.first.helper = 'xyz'
print hasattr(s.first, 'helper')
Les résultats ci-dessus dans
<class '__main__.FirstStruct'>
False
False
Quelqu'un peut-il m'expliquer s'il vous plaît la différence? (. Je courais sur Python 2.7.8 Rappelez-vous, je ne veux pas changer la structure elle-même, mais je voulais ajouter une variable supplémentaire en dehors de la structure ctypes.)
EDIT:
est ici un exemple plus direct:
import ctypes
class FirstStruct(ctypes.Structure):
_fields_ = [('ch', ctypes.c_ubyte)]
class SecondStruct(ctypes.Structure):
_fields_ = [('first', FirstStruct)]
f = FirstStruct()
s = SecondStruct()
f.helper = 'aaa'
s.first.helper = 'bbb'
s.first.ch = 0
t = s.first
t.helper = 'ccc'
t.ch = 12
print f.helper # aaa
print t.ch # 12
print s.first.ch # 12
print t.helper # ccc
print s.first.helper # AttributeError: 'FirstStruct' object has no attribute 'helper'
Les questions sont: pourquoi ne pas s.first
et t
équivalent, et pourquoi ne pas s.first.helper
déclenchement d'un avertissement si je ca pas mis après tout?
La réponse courte est le ctype.Structures ne sont pas mutables. Les affectations d'objets mutables pointent vers le même emplacement de mémoire que la source. Avec les structures, une nouvelle valeur est créée, même si le type est conservé (FirstStruct). Cela signifie que changer la source ne modifie pas les variables assignées. Les dictionnaires pourraient faire l'affaire pour vous. Avez-vous essayé d'utiliser l'a dict comme le conteneur le plus haut niveau? –
@ RonNorris Désolé, je comprends presque ce que vous avez écrit ... Mais pas encore. Essayé le concept avec la réponse https://stackoverflow.com/a/4828831/501814 pour un objet immuable, mais ici, je reçois une erreur d'attribut lors de la tentative d'attribution d'un nouvel attribut (juste ce que je m'attendrais de s.first si il est vraiment immuable.) Est une version mutable de l'immutable s.first, pointant vers le même emplacement de mémoire ctypes mais d'un endroit différent où il a l'attribut 'helper', alors que la version altérée de s.first est immédiatement perdue parce que de l'immutabilité de s? – Andris
À peu près. 's.helper = 'sss'' fonctionnera exactement comme avec' t.helper = 'ccc'' car vous ne jouez pas avec l'objet original FirstStruct - vous ajoutez un attribut à' s '. –