0

在Python 3中有没有一种方法表明一个类不支持其父类支持的某些操作?*我知道类可以将__hash__设置为None以指示类型不可用,但这似乎不起作用一般来说。如何在子类上“取消定义”Python魔术方法?

例如,假设我有一个集合类,其中有一个__len__方法,我想让一个子类代表一个没有定义大小的无限集合。如果我在子类中将__len__设置为None,当我尝试获取集合的长度时,会收到一个丑陋/令人困惑的错误消息。

>>> class C: 
...  def __len__(self): 
...   return 3 
... 
>>> class D(C): 
...  __len__ = None 
... 
>>> len(D()) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'NoneType' object is not callable 

我想,好像D没有定义__len__都得到一个错误:

>>> class E: 
...  pass 
... 
>>> len(E()) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: object of type 'E' has no len() 

This question是相关的,但是我的问题特别是涉及到魔术方法/操作符重载。由于Python魔术方法直接在对象的类型上查找,所以一些可能的方法(如重写__getattribute__或使用描述符)在此处不起作用。

*注意:我知道这将违反Liskov substitution principle,但如果我想要类型安全性,我不会首先使用Python。 ;)

+0

为什么不'从孩子提高NotImplementedError'?另外请注意,动态类型与创建破碎的类结构不同;你能否给出一些背景知道为什么你认为你需要这个? – jonrsharpe

回答

2

我不希望“取消定义”它,因为这可能会使它更容易混淆。我很明确的和定制一个TypeError消息给它,指出为什么这个系列不支持__len__

class D(C): 
    def __len__(self): 
     raise TypeError("Unbounded collection defines no __len__")