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?
Zugriff via property und index auf ctypes-array in Klasse;
@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
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
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]
Zuletzt geändert von ddpf am Donnerstag 6. Juni 2013, 13:45, insgesamt 4-mal geändert.
@ddpf: Nee, so richtig habe ich es immer noch nicht verstanden. Kannst Du nicht mal ein Beispiel von dem zeigen was Du hast?
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]
@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:
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]
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
muss beim setter und getter rein.
Um genau zu sein gehört das so:
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]
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]