Search code examples
pythoninheritanceabstract-base-class

python error when initializing a class derived from and abstract one


I have this simple code and I get a strange error:

from abc import ABCMeta, abstractmethod

class CVIterator(ABCMeta):

    def __init__(self):

        self.n = None # the value of n is obtained in the fit method
        return


class KFold_new_version(CVIterator): # new version of KFold

    def __init__(self, k):
        assert k > 0, ValueError('cannot have k below 1')
        self.k = k
        return 


cv = KFold_new_version(10)

In [4]: ---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-ec56652b1fdc> in <module>()
----> 1 __pyfile = open('''/tmp/py13196IBS''');exec(compile(__pyfile.read(), '''/home/donbeo/Desktop/prova.py''', 'exec'));__pyfile.close()

/home/donbeo/Desktop/prova.py in <module>()
     19 
     20 
---> 21 cv = KFold_new_version(10)

TypeError: __new__() missing 2 required positional arguments: 'bases' and 'namespace'

What am I doing wrong? A theoretical explanation would be appreciated.


Solution

  • You used the ABCMeta meta class incorrectly. It is a meta class, not a base class. Use it as such.

    For Python 2, that means assigning it to the __metaclass__ attribute on the class:

    class CVIterator(object):
        __metaclass__ = ABCMeta
    
        def __init__(self):
            self.n = None # the value of n is obtained in the fit method
    

    In Python 3, you'd use the metaclass=... syntax when defining the class:

    class CVIterator(metaclass=ABCMeta):
        def __init__(self):
            self.n = None # the value of n is obtained in the fit method
    

    As of Python 3.4, you can use the abc.ABC helper class as a base class:

    from abc import ABC
    
    class CVIterator(ABC):
        def __init__(self):
            self.n = None # the value of n is obtained in the fit method