Python:不应该使用的魔术方法

时间:2016-11-22 12:48:22

标签: python coding-style magic-methods

我创建了一个类tuple包装器,而元组不支持项突变。 我应该离开__setitem____delitem__实施还是实施这些方法,例如下面(因此属于拒绝遗赠代码的气味)?哪种方法更pythonic?在这种情况下,自定义异常不是更好吗?

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.

3 个答案:

答案 0 :(得分:1)

虽然这是一个品味问题,但我认为你根本不应该实施它们。具有__setitem__, __delitem__的类实现可变集合协议(隐式或甚至使用collection abstract base classes显式)。你的班级不支持这个界面,而且用户既没有理由也没有权利认为它

答案 1 :(得分:1)

如果你的类应该是一个正确的元组子类型(根据Liskov substitution principle),那么它的行为应该与元组wrt / to set / del相同 - 正如Guillaume所提到的那样是默认行为您既不定义__setitem__也不定义__delitem__。我不知道这将如何落入“拒绝遗赠”类别。

如果你的类使用元组作为其实现的一部分但不应该是一个正确的元组子类型,那么做任何有意义的事情 - 但如果你不想允许项目分配/删除那么最简单的事情是不实施它们。

答案 2 :(得分:0)

如果对您的自定义类有意义,请实现其中一个或两个。

如果您实施__setitem__(),您将能够在代码中使用yourobject[yourindex] = yourvalue语法(使用您选择实施的语义)。

如果您实施__delitem__(),则可以使用del yourobject[yourindex]

为了引发异常而明确地实现一个方法是没有意义的,Python默认会这样做:

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

将提供TypeError: 'Test' object does not support item assignment