Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

oop - Multiple constructors in python, using inheritance

I have a class AbstractDataHandle, whith his init method, and a class Classifier. I would like to have two constructors in Classifier, Java like. One inherited from it`s superclass, and one brand new.

It would be something like (but i intend to "keep" the two constructors):

class AbstractDataHandle():
    def __init__(self, elements, attributes, labels):
        self._load(elements, attributes, labels)


class Classifier(AbstractDataHandle):
    def __init__(self, classifier="LinearSVC", proba=False):
        self._fit(classifier, proba)

Can i have two constructors in one class? If yes, can i have a constructor inherited from a superclass, and add a new one?

Thank you in advance.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can't have two constructors in one class.

Constructors have to be named __init__. And, unlike Java, Python doesn't allow overloading functions or methods by the type of their arguments. So, if you had two constructors, they would both be the same function.

There are a few ways around this.


Use @classmethods as alternate constructors:

class Breakfast(object):
    @classmethod
    def from_eggs(cls, eggs):
        obj = cls()
        obj.spam, obj.eggs = 5, eggs
        return obj

    @classmethod
    def from_spam_and_eggs(cls, spam, eggs):
        obj = cls()
        obj.spam, obj.eggs = spam, eggs
        return obj

A simple example from the standard library is datetime.datetime, which can be constructed with now, fromtimestamp, or a few other alternate constructors, besides the default.


Use default-valued, keyword-only, and/or variable-argument parameters to make a single constructor that can be called different ways:

class Breakfast(object):
    def __init__(self, eggs=0, spam=5):
        self.spam, self.eggs = spam, eggs

int is an example of this: You can create it from a string and a base, or from a single argument that knows how to convert itself to an integer.


Create subclasses that each have different constructors:

class Breakfast(object):
    pass

class HealthyBreakfast(object):
    def __init__(self, spam):
        self.spam, self.eggs = spam, 0

class NormalBreakfast(object):
    def __init__(self, spam, eggs):
        self.spam, self.eggs = spam, eggs

In any of these cases, you can factor out commonalities into a single "base" initializer. For example:

class Breakfast(object):
    def __init__(self, eggs, spam):
        self.spam, self.eggs = spam, eggs

class HealthyBreakfast(object):
    def __init__(self, spam):
        super(HealthyBreakfast, self).__init__(0, spam)

Of course in no case is it possible to have breakfast without spam.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...