Python bietet mir die Möglichkeit, Klassen so zu definieren, daß Objekte nur die Attribute aufnehmen, die ich vorher festgelegt habe. Dafür steht mir __slots__ zur Verfügung. Wenn ich einem Objekt, das diesen Mechanismus nutzt nun Werte zuweise, wird dies akzeptiert, solange ich mich an die Definition halte. Versuche ich jedoch ein neues Attribut anzulegen, wird der Interpreter mit einer Fehlermeldung abbrechen.
Ein entsprechendes Beispiel sieht so aus:
>>> example = example()
>>> example.x = 0
>>> example.y = ’0′
>>> example.z = ‘Null’
>>> example.a = 0
Traceback (most recent call last):
File "<pyshell #18>", line 1, in ?
example.a = 0
AttributeError: ‘example’ object has no attribute ‘a’
>>>
Es darf natürlich nicht verschwiegen werden, daß es auch Nachteile gibt, die speziell auch abgeleitete Klassen betreffen. Das soll aber an dieser Stelle nicht weiter interessieren, da wir uns ja mit PHP beschäftigen wollen und diese Technik für Objekte, die wie structs arbeiten, allemal interessant ist.
Um diese Mechanismus zu implementieren, habe ich eine Klasse namens slotObject geschrieben:
function set ($input) {
$slot = array_keys (get_class_vars (get_class ($this)));
if (is_array ($input)) {
foreach ($input as $key => $value) {
if (in_array ($key, $slot)) {
$this->$key = $value;
}
else {
die ("AttributeError: ‘" . get_class ($this) . "’ object has no attribute ‘" . $key . "’");
}
}
}
}
}
Die Idee für diese Lösung ist, etwas zu implementieren, das wie __slot_arbeitet, aber auch in extends verwendet werden kann.
var $x;
var $y;
var $z;
}
class exampleChild extends example {
var $a;
var $b;
var $c;
}
$arrOne = array (‘x’ => 0, ‘y’ => null, ‘z’ => ‘null’);
$arrTwo = array (‘a’ => 0, ‘b’ => null, ‘c’ => ‘null’);
$example = new example ();
$example->set ($arrOne);
// das wird nicht funktionieren und zum
// Abbruch führen
$example->set ($arrTwo);
print_r ($example);
$exampleChild = new exampleChild ();
$exampleChild->set ($arrOne);
$exampleChild->set ($arrTwo);
print_r ($exampleChild);
Ich muß zugegeben, daß dieser Mechanismus (im Gegensatz zum Original in Python) nur wirksam ist, solange man die Methode set verwendet und der übergebene Paramter eine Assoziatives array ist. Ansonsten kann man den Objekten natürlich Attribute zuweisen, ohne behindert zu werden.
Aber wofür ist das eigentlich gut? Ein mögliches Anwendungsbeispiel habe ich im Artikel extract () und include () beschrieben.
Have fun!