问题
I'm trying to create classmethod constructors for a child class, but I cannot initialize the instance properly.
I have read many blogs and answers on this site and even tried exactly what some other people have posted, still to no avail. Hopefully I'm missing something really simple. Basic example of what I'm trying:
class A(object):
def __init__(self, foo):
self.foo = foo
class B(A):
@classmethod
def make_new(cls):
super(B, cls).__init__('bar')
foobar = B.make_new()
I keep getting unbound method error:
TypeError: unbound method __init__() must be called with B instance as first argument (got str instance instead)
回答1:
The __init__
method is a regular instance method, not a class method. It needs the instance it is going to initialize to already have been created when it is called. Your current code is failing in exactly the same way that A.__init__("foo")
would fail (it's not the fault of super
).
I suspect you wanted to be calling __new__
rather than __init__
. The __new__
method is the actual "constructor" method that is responsible for creating the instance (usually by delegating the actual creation step to object.__new__
). You don't need to use super
either, since you've not overridden the __new__
method that you inherited (from object
, since A
doesn't override it either).
But you don't actually need to do that either. You can just call the cls
argument your classmethod
been passed. Calling a class is the normal way to construct instances:
class B(A):
@classmethod
def make_new(cls):
return cls("bar") # note that you also need to `return` the instance you create!
If the purpose of the class method is to avoid running B.__init__
, you might want something like:
class B(A):
@classmethod
def make_new(cls):
self = cls.__new__(cls)
super(B, self).__init__('bar')
return self
来源:https://stackoverflow.com/questions/45429815/child-class-constructor-using-super-getting-unbound-method-init