python中的多个构造函数,使用继承

时间:2013-10-10 20:11:54

标签: python oop inheritance python-2.7 constructor

我有一个AbstractDataHandle类,它的 init 方法和类分类器。我想在Classifier中有两个构造函数,Java就像。一个继承自它的超类,一个全新的。

它会像(但我打算“保留”两个构造函数):

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)

我可以在一个班级中拥有两个构造函数吗? 如果是,我可以从超类继承构造函数,并添加一个新构造函数吗?

提前谢谢。

3 个答案:

答案 0 :(得分:43)

一个类中不能有两个构造函数。

构造函数必须命名为__init__。而且,与Java不同,Python不允许按参数类型重载函数或方法。所以,如果你有两个构造函数,它们都是相同的函数。

有几种解决方法。


使用@classmethod作为替代构造函数:

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

标准库中的一个简单示例是datetime.datetime,除now之外,可以使用fromtimestampdefault或其他一些替代构造函数构建。{ / p>


使用default-valued,keyword-only和/或variable-argument参数来创建可以以不同方式调用的单个构造函数:

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

int就是一个例子:您可以从字符串和基础创建它,或者从知道如何将自身转换为整数的单个参数创建它。


创建每个都有不同构造函数的子类:

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

在任何这些情况下,您都可以将共性分解为单个“基础”初始值设定项。例如:

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)

当然,在任何情况下都不可能在没有垃圾邮件的情况下享用早餐。

答案 1 :(得分:3)

您可以使用类方法,它们用作工厂方法。对于多个构造函数来说,这是最好的方法。第一个参数'cls'是类本身,而不是它的实例,所以class方法中的cls('Truck')调用类Car的构造函数。

class Car(object):
    def __init__(self, type='car'):
        self.car_type = type

    @classmethod
    def Truck(cls):
        return cls('Truck')

    @classmethod
    def Sport(cls):
        return cls('Sport')

    @classmethod
    def Van(cls):
        return cls('Van')

然后你用这种方式调用工厂方法:

mycar = Car.Sport()

答案 2 :(得分:0)

接受的答案中有一些方法,但我认为这个方法相当灵活。它很复杂,但非常灵活。

当类被填充时, init 调用一个方法并传递一个字符串参数(从实例化中获取)。该函数使用条件来调用右边的"构造函数"函数初始化您的值,假设您有不同的可能起始值集。

如果您需要提供其他参数(例如,可能仅在运行时具有值),您可以使用 init ()中的默认值来允许可选参数,并在中初始化这些参数。像往常一样初始化

class MyClass:
def __init__(self,argsSet1, otherAttribute="Assigning this default value 
             to make this other argument optional",):
    self.selectArgSet(argsSet1)
    self.otherAttribute = otherAttribute
    print otherAttribute
def selectArgSet(self,ArgSet1):
    if ArgSet1 == "constructorArgSet1":
        self.constructorArgSet1()
    elif ArgSet1 == "constructorArgSet2":
        self.constructorArgSet2()
def constructorArgSet1(self):
    print "Use this method as Constructor 1"
    self.variable1 = "Variable1 value in Constructor 1"
    self.variable2 = "Variable2 value in Constructor 1"
    print self.variable1
    print self.variable2
def constructorArgSet2(self):
    print "Use this method as Constructor 2"


      self.variable1 = "Variable1 value in Constructor 2"
        self.variable2 = "Variable2 value in Constructor 2"
        print self.variable1
        print self.variable2

myConstructor_1_Instance = MyClass("constructorArgSet1")
myConstructor_2_Instance = MyClass("constructorArgSet2", "You can still 
                                           initialize values normally")

其输出为:

  

将此方法用作构造函数1

     

构造函数1中的Variable1值

     

构造函数1中的Variable2值

     

指定默认值以使此其他参数可选

     

将此方法用作构造函数2

     

构造函数2中的Variable1值

     

构造函数2中的Variable2值

     

您仍然可以正常初始化值