2016-11-22 1 views
0

Ich habe eine Klasse erstellt, die ein tuple Wrapper ist und Tupel Item Mutationen nicht unterstützt. Sollte ich __setitem__ und __delitem__ Umsetzung verlassen oder diese Methoden wie z. unten (also in Art von Refused Bequest Code Geruch fallen)? Welcher Ansatz ist pythischer? Sind in diesem Fall keine benutzerdefinierten Ausnahmen besser?Python: magische Methoden, die nicht verwendet werden sollten

def __setitem__(self, key, value): 
    """ 
    :raise: Always. 
    :raises: TypeError 
    """ 
    self.data_set[key] = value # Raise from tuple. 

def __delitem__(self, key): 
    """ 
    :raise: Always. 
    :raises: TypeError 
    """ 
    raise TypeError("Item deletion is unsupported") # Custom exceptions thrown. 

Antwort

1

Wenn deine Klasse ein richtiger Tupel-Subtyp sein soll (nach Liskov substitution principle), dann sollte es sich verhalten Genau wie ein Tupel wrt/to set/del - was, wie Guillaume erwähnt, das Standardverhalten ist, wenn Sie weder __setitem__ noch __delitem__ definieren. Ich sehe nicht, wie das in die Kategorie "Refused Bequest" fallen würde.

Wenn Ihre Klasse ein Tupel als Teil ihrer Implementierung verwendet, aber NICHT als Tupel-Subtyp gelten soll, dann tun Sie, was auch immer sinnvoll ist - aber wenn Sie die Zuweisung/Löschung von Elementen nicht erlauben wollen, dann ist das die einfachste Sache ist es, sie nicht umzusetzen.

+0

Mit Refused Bequest meine ich, dass diese Klasse behauptet, "__setitem__" und "__delitem__" zu implementieren, aber das Verhalten zeigt, dass diese Operationen nicht unterstützt werden. – JCode

+1

AOK. Nun, eigentlich (wie ich bereits erwähnte), wenn das Ziel darin besteht, die Zuweisung und Löschung von Objekten nicht zu unterstützen, macht es keinen Sinn, diese Methoden zu implementieren. –

0

Implementieren Sie die eine oder andere oder beide, wenn sie für Ihre benutzerdefinierte Klasse sinnvoll sind. Wenn Sie __setitem__() implementieren, können Sie yourobject[yourindex] = yourvalue Syntax in Ihrem Code (mit der Semantik, die Sie implementieren) verwenden.

Wenn Sie __delitem__() implementieren können Sie del yourobject[yourindex] verwenden

Es macht keinen Sinn zu explictly ein Verfahren zu implementieren nur eine Ausnahme zu erhöhen, Python wird sie standardmäßig tun:

class Test(object): 
    pass 
test = Test() 
test['foo'] = 'bar' # will call Test.__setitem__() which is not explicitly defined 

geben TypeError: 'Test' object does not support item assignment

1

Obwohl das eine Frage des Geschmacks ist, denke ich, dass Sie sie überhaupt nicht implementieren sollten. Eine Klasse mit __setitem__, __delitem__ implementiert die veränderbare Auflistung Protokoll (entweder implizit oder sogar explizit mithilfe von collection abstract base classes). Deine Klasse unterstützt diese Schnittstelle einfach nicht, das wars, und der Benutzer hat weder Grund noch Recht zu glauben, dass es funktioniert

Verwandte Themen