won*_*ng2 4 python abstract-class abc
我有两个继承自同一父级的类P:
from abc import ABCMeta, abstractmethod
class P(object):
__metaclass__ = ABCMeta
@abstractmethod
def foo(self):
pass
class C(P):
pass
class D(tuple, P):
pass
Run Code Online (Sandbox Code Playgroud)
唯一的区别是,D从继承tuple和P同时C继承了P而已.
现在这是行为:c = C()得到错误,如预期的那样:
TypeError: Can't instantiate abstract class C with abstract methods foo
Run Code Online (Sandbox Code Playgroud)
但d = D()工作没有错误!
我甚至可以打电话d.foo().我该如何解释这种行为?
在该方法中测试抽象方法object.__new__; 当你继承tuple自己的__new__方法时,object.__new__它没有被调用,并且没有进行抽象方法的测试.
换句话说,将抽象方法与任何内置的不可变类型混合将导致此问题.
唯一有效的解决方案是进行自己的测试__new__,然后只有在混合了子类中的两个基础之前 放置抽象tuple类.
class P(object):
__metaclass__ = ABCMeta
def __new__(cls, *args, **kwargs):
super_new = super(P, cls).__new__
if super_new.__self__ is not object:
# immutable mix-in used, test for abstract methods
if getattr(cls, '__abstractmethods__'):
raise TypeError(
"Can't instantiate abstract class %s "
"with abstract methods %s" % (
cls.__name__,
', '.join(sorted(cls.__abstractmethods__))))
return super_new(cls, *args, **kwargs)
@abstractmethod
def foo(self):
pass
class D(P, tuple):
pass
Run Code Online (Sandbox Code Playgroud)