Seite 1 von 1

Zugriff via property und index auf ctypes-array in Klasse;

Verfasst: Donnerstag 6. Juni 2013, 11:52
von ddpf
Ich habe ein ctypes array das aus Kanälen besteht. Jedem Kanal ist ein Element aus dem array zugewiesen (Vereinfachtes Beispiel). Ich habe eine setter-Methode (set_register_channel(self, ch, value)) und eine getter-Methode (get_register_channel(self, ch)). Ich möchte jetzt eine property haben die wie folgt aussieht beim Zugriff:

object.channel_array[x] = y
output = object.channel_array[x]

wobei x ein beliebiger aber begrentzer Integerwert ist um einen Kanal anzusprechen und y ein beliebiger Integerwert. z.B. channel_array[2] = 20 # Schreibe in Kanal 2 (x = 2) den Wert 20 (y = 20).

Wie geht das?

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 12:03
von BlackJack
@ddpf: Ich habe noch nicht so richtig verstanden was Du hast und was Du haben möchtest. Kann es sein, dass Du Deine Getter- und Settermethoden einfach nur in `__getitem__()` und `__setitem__()` umbenennen willst?

Code: Alles auswählen

    print obj.get_register_channel(channel_number)
    obj.set_register_channel(channel_number, value)
    # 
    # -> Umbenennen der Methoden nach `__getitem__()` und `__setitem__()`
    # 
    print obj[channel_number]
    obj[channel_number] = value

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 13:05
von ddpf
Ungefähr das möchte ich haben. Ich habe bei der betreffenden Klasse eine Datenstruktur (Klasse) vererbt. In dieser Datenstruktur gibt es Register die mittels mehrerer Arrays dargestellt sind. Ich möchte innerhalb der vererbten Datenstruktur ein Element ansprechen. Dieses Element ist ein ctypes-array. Also in deinem Code würde es nur eine Sache geben. Ich habe aber mehrere Elemeente und ein Teil dieser Elemente sind arrays.
Ist es jetzt verständlich?

EDIT: Habe gerade kleinen Fehler gesehen. Ist im Originalposting ausgebessert.
(
object.channel_array[x] = y
output = object.channel_array[x]
)

EDIT2: Ich probiers mal direkt mit Source. Meine Frage: Wie kann ich jetzt ein property machen, sodass ich

Code: Alles auswählen

class data_struct(Structure):
   pass

data_struct._fields_ = [
...
('register', POINTER(c_ulong)*8),
...

Code: Alles auswählen

class C(data_struct):
   def __init__(self)
      data_struct.__init__(self)
      for primary_ptr in (
                self.register
        ):
            register.contents = register._type_()
      ...

   def set_register_channel(self, ch, value):
        self.register[ch][0] = self.register[ch]._type_(value)

   def get_register_channel(self, ch):
      return self.register[ch][0]

   register = property(?,?)#wie geht das?

Code: Alles auswählen

obj = C()
obj.register[2] = 20
print obj.register[2]

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 13:33
von BlackJack
@ddpf: Nee, so richtig habe ich es immer noch nicht verstanden. Kannst Du nicht mal ein Beispiel von dem zeigen was Du hast?

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 13:43
von ddpf
Ich habe oben edited

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 14:12
von Sirius3
so?

Code: Alles auswählen

class C(data_struct):
   def __init__(self)
      data_struct.__init__(self)
      for primary_ptr in (
                self.register
        ):
            register.contents = register._type_()
      ...

   def __setitem__(self, ch, value):
        self.register[ch][0] = self.register[ch]._type_(value)

   def __getitem__(self, ch):
      return self.register[ch][0]

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 14:19
von ddpf
Und wie spreche ich jetzt das register genau an?

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 14:35
von BlackJack
@dppf: Also `register` kannst Du es schon mal nicht nennen, denn damit würdest Du ja das `register`-Attribut was es schon gibt verdecken. Entweder müsstest Du es anders nennen — registers zum Beispiel — oder Du darfst nicht von `data_struct` erben, sondern müsstest das in def `C`-Klasse per Komposition lösen.

Das würde man dann auch nicht mit einem Property lösen (können), sondern man bräuchte eine Wrapperklasse um das `register`-Array mit den magischen Itemzugriffsmethoden. Also quasi so etwas hier:

Code: Alles auswählen

class _RegisterWrapper(object):
    def __init__(self, register):
        self.register = register

    def __getitem__(self, channel_number):
        return self.register[channel_number][0]

    def __setitem__(self, channel_number, value):
        self.register[channel_number][0] = (
            self.register[channel_number]._type_(value)
        )


class C(data_struct):
    def __init__(self):
        data_struct.__init__(self)
        for primary_ptr in self.register:
            primary_ptr.contents = primary_ptr._type_()

        self.registers = _RegisterWrapper(self.register)


obj = C()
obj.registers[2] = 20
print obj.registers[2]

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 15:29
von ddpf
EDIT: Ich sehe gerade wie ich es machen muss... werde Lösung gleich posten

Wegen dem keyword register: Habe ich jetzt einfach mal schnell reingeschrieben weil die Namen im Programm anders heißen und die ganze Struktur viel komplizierter ist. Ich hätte da aber noch ein Problem. Ich habe nicht nur eine Registerbank, sondern 2. Da steht genau das Gleiche drinnen. Ist eine Reduntanz. Ich würde in der setter und getter Methode auch gleichzeitig abragen ob das gleiche drinnen ist.
Sprich

Code: Alles auswählen

assert self.register_primary[ch][0] == self.register_secondary[ch][0]; "primary register differs to secondary register of channel {0}".format(ch)

muss beim setter und getter rein.

Um genau zu sein gehört das so:

Code: Alles auswählen

    def set_register_channel(self, ch, value):
        self.register_primary[ch][0] = self.register_primary[ch]._type_(value)
        self.register_secondary[ch][0] = self.register_primary[ch]._type_(value)        
        assert self.register_primary[ch][0] == self.register_secondary[ch][0]; "Primary register differs to secondary register of channel {0}".format(ch)

Code: Alles auswählen

    def get_register_channel(self, ch):
        assert self.register_primary[ch][0] == self.register_secondary[ch][0]; "Primary register differs to secondary register of channel {0}".format(ch)
        return self.register_primary[ch][0]

Re: Zugriff via property und index auf ctypes-array in Klass

Verfasst: Donnerstag 6. Juni 2013, 16:00
von ddpf
Gut, ich habe das jetzt mit dem gespiegelten Register wie folgt gelöst:

Code: Alles auswählen

class _RegisterWrapper(object):
    def __init__(self, register_primary, register_secondary):
        self.register_primary = register_primary
        self.register_secondary = register_secondary

    def __getitem__(self, channel_number):
        assert self.register_primary[channel_number][0] == self.register_secondary[channel_number][0]; "Primary register differs to secondary register of channel {0}".format(channel_number)
        return self.register_primary[channel_number][0]

    def __setitem__(self, channel_number, value):
        self.register_primary[channel_number][0] = self.register_primary[channel_number]._type_(value)
        self.register_secondary[channel_number][0] = self.register_secondary[channel_number]._type_(value)
        assert self.register_primary[channel_number][0] == self.register_secondary[channel_number][0]; "Primary register differs to secondary register of channel {0}".format(channel_number)

Code: Alles auswählen

def __init__(self)
...
   self.registers = _RegisterWrapper(self.register_primary, self.register_secondary)
...

Code: Alles auswählen

        self.obj.registers[0] = 4294967295
        print self.obj.register_primary[0][0]
        print self.obj.register_secondary[0][0]
        print self.obj.registers[0]