Python different behaviour with abstractmethod

后端 未结 1 1225
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-10 20:34

I have two classes inheriting from the same parent P:

from abc import ABCMeta, abstractmethod

class P(object):

    __metaclass__ = ABCMeta

           


        
相关标签:
1条回答
  • 2020-12-10 21:14

    Abstract methods are tested for in the object.__new__ method; when you inherit from tuple, which has its own __new__ method, object.__new__ is not called and the test for abstract methods is not made.

    In other words, mixing abstract methods with any of the built-in immutable types will cause this problem.

    The only solution that works is to do your own test in __new__ and then only if you put your abstract class before tuple when mixing in the two bases in a subclass.

    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
    
    0 讨论(0)
提交回复
热议问题