Создание питонических объектов, которые разделяют память - PullRequest
1 голос
/ 18 ноября 2011

Я пытаюсь создать объект в Python, который состоит из более мелких объектов.Каждый из объектов имеет свое значение - каждый из меньших объектов и весь объект в целом.Проблема в том, что я хочу, чтобы каждый из 3 объектов был, по-видимому, независимо адресуемым и работал как отдельный объект, а это довольно сложно достичь.Эту проблему было бы легко решить в C с помощью указателей, но мне трудно смоделировать это поведение в Python.

Пример ситуации, о которой я говорю, можно увидеть в контрольном слове конечного автомата: Управляющее слово (2 байта) имеет значение в целом и должно быть доступно (или перенесено) как объект, но каждый из байтов в управляющем слове имеет свое собственное значение и должно быть установлено и доступно независимо.

В C я бы сделал что-то вроде:

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;

И, таким образом, я мог бы легко получить доступ к каждому из элементов и не был бы вынужден поддерживать сложную логику, чтобы сохранить все 3 объектасинхронно - назначение в *control_word будет обновлять одновременно и low_byte, и high_byte, и любое обновление байтовых объектов будет влиять на control_word.

Есть ли , простой способ достижения этого поведения в Python?

Ответы [ 3 ]

4 голосов
/ 18 ноября 2011

Два варианта:

Вы можете использовать C и оболочку CPython ... Или вы можете использовать свойства:

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)

теперь вы можете использовать его как:

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

дано дальнейшее объяснение из комментариев:

Я бы хотел иметь возможность сделать что-то вроде c = Control(); device_control = dict(device_control = c.word, device_read_permissions = c.low, device_write_permissions = c.high), а затем получить доступ к каждому компоненту через диктовку ...

словарь вам вообще не нужен, вы можете заставить наш класс Control вести себя как словарь, реализующий протокол dict (в нем довольно много методов, вы можете его опустить те, которые вы не используете, если хотите):

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

и затем используйте его так:

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'
1 голос
/ 18 ноября 2011

Чтобы получить доступ к деталям И извлечь объекты, вы должны создать некоторые "объекты частей".

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)

Не проверено, но должно дать вам представление о том, как действовать.

0 голосов
/ 18 ноября 2011

Если я правильно вас понимаю, это очень легко сделать в Python.

my_obj1 = Object1()
my_obj2 = Object2()
my_parent_obj = Object3()
my_parent_obj.obj1 = my_obj1
my_parent_obj.obj2 = my_obj2

Теперь экземпляры object1 и object2 могут быть адресованы независимо как my_obj1 и как часть родительского объекта как my_parent_obj.obj1. Любое изменение, внесенное вами в одно, повлияет на другое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...