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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python:不应该使用的魔术方法相关的知识,希望对你有一定的参考价值。

我创建了一个类是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.
答案

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

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

另一答案

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

另一答案

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

如果您实现__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

以上是关于Python:不应该使用的魔术方法的主要内容,如果未能解决你的问题,请参考以下文章

PHP链式操作通过call和callstatic魔术方法的实现,以及phpstorm通过注释去追踪function

python魔术方法

Python中的魔术方法

python之使用魔术方法__getitem__和__len__

多继承及魔术方法介绍

Python 魔术方法笔记