问题
The problem is quite simple. If a class B
inherit a class A
and wants to override a ´classmethod´ that is used as a constructor (I guess you call that a "factory method"). The problem is that B.classmethod
will want to reuse A.classmethod
, but then it will have to create an instance of the class A, while it subclasses the class A - since, as a classmethod, it has no self. And then, it doesn't seem the right way to design that.
I did the example trivial, I do more complicate stuff by reading numpy arrays, etc. But I guess there is no loss of information here.
class A:
def __init__(self, a):
self.el1 = a
@classmethod
def from_csv(cls, csv_file):
a = read_csv(csv_file)
return cls(a)
@classmethod
def from_hdf5 ...
class B(A):
def __init__(self, a, b)
A.(self, a)
self.el2 = b
@classmethod
def from_csv(cls, csv_file):
A_ = A.from_csv(csv_file) #instance of A created in B(A)
b = [a_*2 for a_ in A.el]
return cls(A.el, b)
Is there a pythonic way to deal with that?
回答1:
One easy solution would be to have class B
's __init__
method have a default value for its b
parameter. This would let the cls(a)
call made by A.from_csv
work when it is inherited. If the default is used, the __init__
method could calculate a value to store from a
(as you do in B.from_csv
now).
class B(A):
def __init__(self, a, b=None):
super().__init__(a) # use super(B, self).__init__(a) if you're in Python 2
self.el2 = b if b is not None else [i*2 for i in a]
# don't override from_csv, B.from_csv will already return a B instance!
回答2:
After doing some different trials. My conclusion is that you should override a classmethod
without reusing the code inside. So the best way I found, for my particular problem, is to make the classmethod
as simply as possible and put the code I want to reuse in another method, static
in my case, since the classmethod is a constructor.
来源:https://stackoverflow.com/questions/20925137/classmethod-as-constructor-and-inheritance