Normally, to subclass a class I do something like
class Subby(Parenty):
def __init__(self):
Parenty.__init__(self)
But now I'm trying to subclass a metaclass, specifically ABCMeta, so I'm doing
import ABCMeta
class Subby(ABCMeta):
def __init__(self):
ABCMeta.__init__(self) #this never seems to run
def __new__(mcls, name, bases, namespace):
cls = ABCMeta.__new__(mcls, name, bases, namespace)
return cls
But, when I then try to subclass Subby
as a metaclass like
class newClass(metaclass=Subby):
pass
I get the error TypeError: __init__() takes 1 positional argument but 4 were given
.
Why is this, and how do I subclass ABCMeta correctly?
From the datamodel:
If
__new__()
returns an instance ofcls
, then the new instance’s__init__()
method will be invoked like__init__(self[, ...])
, where self is the new instance and the remaining arguments are the same as were passed to__new__()
.
So, as @user2357112 said, the signatures must match.
Despite this, there's really no reason to define __init__
and __new__
if you simply want to create an ABC. Just create it and use .register
to register the conforming classes. Optionally, create a number of abstract methods and a __subclasshook__
that checks for conformance. A good example already exists in the abc
module documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With