12

我有一个类 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)

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

先感谢您。

4

3 回答 3

44

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

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

有几种方法可以解决这个问题。


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

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除了默认.nowfromtimestamp


使用默认值、仅关键字和/或可变参数参数来创建可以以不同方式调用的单个构造函数:

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)

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

于 2013-10-10T20:19:47.400 回答
3

您可以使用类方法,它们用作工厂方法。这是多个构造函数的最佳方法。第一个参数 'cls' 是类本身,而不是实例,因此类方法中的 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()
于 2013-10-10T20:26:38.477 回答
0

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

当类被实例化时,init调用一个方法并向它传递一个字符串参数(从实例化中获得)。该函数使用条件调用正确的“构造函数”函数来初始化您的值,假设您有不同的可能起始值集。

如果您需要提供其他参数(例如,可能仅在运行时有值),您可以使用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 中的变量 1 值

构造函数 1 中的变量 2 值

分配默认值以使此其他参数可选

将此方法用作构造函数 2

构造函数 2 中的变量 1 值

构造函数 2 中的变量 2 值

您仍然可以正常初始化值

于 2015-03-15T05:09:24.073 回答