J'essaie de créer un objet en python qui est composé d'objets plus petits. Chacun des objets a sa propre signification - chacun des petits objets et l'objet entier dans son ensemble. Le problème est que je veux que chacun des 3 objets soit adressable en apparence indépendamment et fonctionne comme des objets autonomes et c'est assez difficile à réaliser. Ce problème serait facile à résoudre en C à l'aide de pointeurs mais je trouve difficile de simuler ce comportement en Python.
Un exemple de la situation dont je parle pourrait être vu dans un mot de contrôle d'une machine d'état: le mot de contrôle (2 octets) a une signification dans son ensemble et doit être des accès (ou transférés) en tant qu'objet, mais chacun des octets du mot de contrôle a sa propre signification et doit être défini et accessible indépendamment.
En C, je ferais quelque chose comme:
unsigned short control_word_memory;
unsigned short *control_word = &control_word_memory;
unsigned char *low_byte = &control_word_memory;
unsigned char *high_byte = low_byte + 1;
Et ainsi je serais en mesure d'accéder facilement à chacun des éléments et de ne pas être obligé de maintenir une logique complexe pour garder les 3 objets synchronisés - une affectation dans *control_word
mettrait à jour low_byte
et {{X2 }} simultanément, et toute mise à jour des objets d'octet influencera le control_word
.
Existe-t-il un moyen pour obtenir ce comportement en Python?
3 réponses
Deux alternatives:
Vous pouvez utiliser C et un wrapper CPython ... Ou vous pouvez utiliser des propriétés:
class Control(object):
def __init__(self, word=0):
self.word = word
def get_low(self):
return self.word & 0xFF
def set_low(self, x):
self.word &= 0xFF00
self.word |= x & 0xFF
def get_high(self):
return (self.word >> 8) & 0xFF
def set_high(self, x):
self.word &= 0x00FF
self.word |= (x & 0xFF) << 8
low = property(get_low, set_low)
high = property(get_high, set_high)
Vous pouvez maintenant l'utiliser comme:
In [3]: c = Control(0x1234)
In [4]: hex(c.low)
Out[4]: '0x34'
In [5]: hex(c.high)
Out[5]: '0x12'
In [6]: c.low=56
In [7]: hex(c.word)
Out[7]: '0x1238'
In [8]: c.low=0x56
In [9]: hex(c.word)
Out[9]: '0x1256'
In [10]: c.high = 0x78
In [11]: hex(c.word)
Out[11]: '0x7856'
In [12]: c.word = 0xFE0A
In [13]: c.low
Out[13]: 10
In [14]: c.high
Out[14]: 254
Compte tenu des explications complémentaires des commentaires:
Je voudrais pouvoir faire quelque chose comme
c = Control (); device_control = dict (device_control = c.word, device_read_permissions = c.low, device_write_permissions = c.high)
puis accédez à chaque composant via le dict ...
Vous n'avez pas du tout besoin du dictionnaire, vous pouvez faire en sorte que notre classe Control
se comporte comme un dictionnaire implémentant la dict
protocole (il a plusieurs méthodes, vous pouvez laisser de côté celles que vous n'utilisez pas si vous le souhaitez):
class DictControl(Control):
def __len__(self):
return 3
def __getitem__(self, k):
if k == 'device_control':
return self.word
elif k == 'device_read_permissions':
return self.low
elif k == 'device_write_permissions':
return self.high
else: raise KeyError
def __setitem__(self, k, v):
if k == 'device_control':
self.word = v
elif k == 'device_read_permissions':
self.low = v
elif k == 'device_write_permissions':
self.high = v
else: raise KeyError
Puis utilisez-le comme ceci:
In [2]: c = DictControl()
In [3]: c.word = 0x1234
In [4]: hex(c['device_control'])
Out[4]: '0x1234'
In [5]: c['device_read_permissions'] = 0xFF
In [6]: c.low
Out[6]: 255
In [7]: c.high = 0xAA
In [8]: c['device_write_permissions']
Out[8]: 170
In [9]: hex(c.word)
Out[9]: '0xaaff'
Pour accéder aux pièces ET pour extraire les objets, vous devez créer des "objets pièces".
class Part(object):
def __init__(self, ref, bitstart, bitlen):
self.ref = ref
self.bitstart = bitstart
self.bitlen = bitlen
self.mask = ((1 << bitlen) - 1) << bitstart
def set(self, value):
self.ref.word = self.ref.word & ~self.mask | ((value << self.bitstart) & self.mask)
def get(self):
return (self.ref.word & self.mask) >> self.bitstart
class Control(object):
def __init__(self, word=0):
self.word = word
self.low = Part(self, 0, 8)
self.high = Part(self, 8, 8)
Non testé, mais devrait vous donner une idée de la marche à suivre.
Si je vous comprends bien, c'est extrêmement facile à réaliser en Python.
my_obj1 = Object1()
my_obj2 = Object2()
my_parent_obj = Object3()
my_parent_obj.obj1 = my_obj1
my_parent_obj.obj2 = my_obj2
Les instances object1 et object2 sont désormais adressables indépendamment en tant que my_obj1
et en tant que partie de l'objet parent en tant que my_parent_obj.obj1
. Tout changement que vous apportez à l'un affectera l'autre.
Questions connexes
De nouvelles questions
python
Python est un langage de programmation multi-paradigme, typé dynamiquement et polyvalent. Il est conçu pour être rapide à apprendre, comprendre, utiliser et appliquer une syntaxe propre et uniforme. Veuillez noter que Python 2 est officiellement hors support à partir du 01-01-2020. Néanmoins, pour les questions Python spécifiques à la version, ajoutez la balise [python-2.7] ou [python-3.x]. Lorsque vous utilisez une variante Python (par exemple, Jython, PyPy) ou une bibliothèque (par exemple, Pandas et NumPy), veuillez l'inclure dans les balises.